From 28e5cc75a49bdc621a75986f3d045b79397d55c9 Mon Sep 17 00:00:00 2001 From: markaj-nordic <98948394+markaj-nordic@users.noreply.github.com> Date: Thu, 24 Feb 2022 07:05:45 +0100 Subject: [PATCH] [nrfconnect] Added support all-clusters-app (#15407) * [all-clusters-app] Added support for nrfconnect platform. Signed-off-by: markaj-nordic * Restyled by prettier-markdown * Restyled by prettier-yaml * [all-clusters-app-nrf] Fixed the initialization steps. Signed-off-by: markaj-nordic Co-authored-by: Restyled.io --- .github/workflows/examples-nrfconnect.yaml | 8 + .../nrfconnect/CMakeLists.txt | 84 ++++ examples/all-clusters-app/nrfconnect/Kconfig | 25 ++ .../all-clusters-app/nrfconnect/README.md | 411 ++++++++++++++++++ .../boards/nrf52840dk_nrf52840.conf | 17 + .../boards/nrf52840dk_nrf52840.overlay | 57 +++ .../boards/nrf5340dk_nrf5340_cpuapp.conf | 17 + .../boards/nrf5340dk_nrf5340_cpuapp.overlay | 86 ++++ .../child_image/multiprotocol_rpmsg.conf | 22 + .../mcuboot_multi_image_dfu.conf | 52 +++ .../mcuboot_single_image_dfu.conf | 38 ++ .../nrf52840dk_nrf52840/pm_static.yml | 38 ++ .../nrf5340dk_nrf5340_cpuapp/pm_static.yml | 52 +++ .../nrfconnect/main/AppTask.cpp | 404 +++++++++++++++++ .../nrfconnect/main/include/AppConfig.h | 27 ++ .../nrfconnect/main/include/AppEvent.h | 56 +++ .../nrfconnect/main/include/AppTask.h | 81 ++++ .../main/include/CHIPProjectConfig.h | 33 ++ .../nrfconnect/main/include/Utils.h | 56 +++ .../all-clusters-app/nrfconnect/main/main.cpp | 32 ++ .../nrfconnect/overlay-low_power.conf | 30 ++ examples/all-clusters-app/nrfconnect/prj.conf | 41 ++ .../nrfconnect/third_party/connectedhomeip | 1 + 23 files changed, 1668 insertions(+) create mode 100644 examples/all-clusters-app/nrfconnect/CMakeLists.txt create mode 100644 examples/all-clusters-app/nrfconnect/Kconfig create mode 100644 examples/all-clusters-app/nrfconnect/README.md create mode 100644 examples/all-clusters-app/nrfconnect/boards/nrf52840dk_nrf52840.conf create mode 100644 examples/all-clusters-app/nrfconnect/boards/nrf52840dk_nrf52840.overlay create mode 100644 examples/all-clusters-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.conf create mode 100644 examples/all-clusters-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay create mode 100644 examples/all-clusters-app/nrfconnect/child_image/multiprotocol_rpmsg.conf create mode 100644 examples/all-clusters-app/nrfconnect/configuration/mcuboot_multi_image_dfu.conf create mode 100644 examples/all-clusters-app/nrfconnect/configuration/mcuboot_single_image_dfu.conf create mode 100644 examples/all-clusters-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static.yml create mode 100644 examples/all-clusters-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static.yml create mode 100644 examples/all-clusters-app/nrfconnect/main/AppTask.cpp create mode 100644 examples/all-clusters-app/nrfconnect/main/include/AppConfig.h create mode 100644 examples/all-clusters-app/nrfconnect/main/include/AppEvent.h create mode 100644 examples/all-clusters-app/nrfconnect/main/include/AppTask.h create mode 100644 examples/all-clusters-app/nrfconnect/main/include/CHIPProjectConfig.h create mode 100644 examples/all-clusters-app/nrfconnect/main/include/Utils.h create mode 100644 examples/all-clusters-app/nrfconnect/main/main.cpp create mode 100644 examples/all-clusters-app/nrfconnect/overlay-low_power.conf create mode 100644 examples/all-clusters-app/nrfconnect/prj.conf create mode 120000 examples/all-clusters-app/nrfconnect/third_party/connectedhomeip diff --git a/.github/workflows/examples-nrfconnect.yaml b/.github/workflows/examples-nrfconnect.yaml index 104b298c480b63..596aa1344d14fe 100644 --- a/.github/workflows/examples-nrfconnect.yaml +++ b/.github/workflows/examples-nrfconnect.yaml @@ -144,6 +144,14 @@ jobs: nrfconnect nrf52840dk_nrf52840 pump-controller-app \ examples/pump-controller-app/nrfconnect/build/zephyr/zephyr.elf \ /tmp/bloat_reports/ + - name: Build example nRF Connect SDK All Clusters App on nRF52840 DK + timeout-minutes: 10 + run: | + scripts/examples/nrfconnect_example.sh all-clusters-app nrf52840dk_nrf52840 + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + nrfconnect nrf52840dk_nrf52840 all-clusters-app \ + examples/all-clusters-app/nrfconnect/build/zephyr/zephyr.elf \ + /tmp/bloat_reports/ - name: Run unit tests for Zephyr native_posix_64 platform timeout-minutes: 10 run: | diff --git a/examples/all-clusters-app/nrfconnect/CMakeLists.txt b/examples/all-clusters-app/nrfconnect/CMakeLists.txt new file mode 100644 index 00000000000000..6b826df1873ef4 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/CMakeLists.txt @@ -0,0 +1,84 @@ +# +# Copyright (c) 2022 Project CHIP Authors +# +# 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. +# +cmake_minimum_required(VERSION 3.13.1) + +get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/connectedhomeip REALPATH) +get_filename_component(NLIO_ROOT ${CHIP_ROOT}/third_party/nlio/repo/include REALPATH) +get_filename_component(NRFCONNECT_COMMON ${CHIP_ROOT}/examples/platform/nrfconnect REALPATH) +get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) +get_filename_component(ALL_CLUSTERS_COMMON_DIR ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) + +include(${CHIP_ROOT}/config/nrfconnect/app/check-nrfconnect-version.cmake) + +# Load NCS/Zephyr build system +set(CONF_FILE ${CHIP_ROOT}/config/nrfconnect/app/sample-defaults.conf prj.conf) + +if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD}.conf) + list(APPEND CONF_FILE boards/${BOARD}.conf) +endif() + +option(BUILD_WITH_DFU "Build target with Device Firmware Upgrade support" OFF) +if(BUILD_WITH_DFU) + list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-mcuboot_qspi_nor_support.conf) + # Enable Matter OTA Requestor + list(INSERT OVERLAY_CONFIG 0 ${CHIP_ROOT}/config/nrfconnect/app/overlay-ota_requestor.conf) + if(BOARD STREQUAL "nrf5340dk_nrf5340_cpuapp") + set(mcuboot_OVERLAY_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/configuration/mcuboot_multi_image_dfu.conf CACHE INTERNAL "") + else() + set(mcuboot_OVERLAY_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/configuration/mcuboot_single_image_dfu.conf CACHE INTERNAL "") + endif() + set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static.yml) +endif() + +list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nrfconnect/chip-module) +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) + +# -Wmaybe-uninitialized has too many false positives, including on std::optional +# and chip::Optional. Make it nonfatal. +# +# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635 +target_compile_options(app PRIVATE -Werror -Wno-error=maybe-uninitialized) + +project(chip-nrfconnect-all-clusters-app-example) + +include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) +include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) + +target_include_directories(app PRIVATE + main/include + ${ALL_CLUSTERS_COMMON_DIR}/include + ${GEN_DIR}/app-common + ${GEN_DIR}/all-clusters-app + ${NLIO_ROOT} + ${NRFCONNECT_COMMON}/util/include) + +target_sources(app PRIVATE + main/AppTask.cpp + main/main.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-modes-manager.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/bridged-actions-stub.cpp + ${GEN_DIR}/all-clusters-app/zap-generated/callback-stub.cpp + ${GEN_DIR}/all-clusters-app/zap-generated/IMClusterCommandHandler.cpp + ${NRFCONNECT_COMMON}/util/LEDWidget.cpp + ${CHIP_ROOT}/src/app/clusters/ota-requestor/OTARequestor.cpp + ${CHIP_ROOT}/src/app/clusters/ota-requestor/BDXDownloader.cpp) + + +chip_configure_data_model(app + INCLUDE_SERVER + ZAP_FILE ${ALL_CLUSTERS_COMMON_DIR}/all-clusters-app.zap +) diff --git a/examples/all-clusters-app/nrfconnect/Kconfig b/examples/all-clusters-app/nrfconnect/Kconfig new file mode 100644 index 00000000000000..4d6115b4b87e7c --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/Kconfig @@ -0,0 +1,25 @@ +# +# Copyright (c) 2022 Project CHIP Authors +# +# 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. +# +mainmenu "Matter nRF Connect All Clusters Example Application" + +config STATE_LEDS + bool "Use LEDs to indicate the device state" + default y + help + Use LEDs to render the current state of the device such as the progress of commissioning of + the device into a network or the factory reset initiation. + +source "Kconfig.zephyr" diff --git a/examples/all-clusters-app/nrfconnect/README.md b/examples/all-clusters-app/nrfconnect/README.md new file mode 100644 index 00000000000000..2f994822b9966f --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/README.md @@ -0,0 +1,411 @@ +# Matter nRF Connect All Clusters Example Application + +The nRF All Clusters Example Application implements various ZCL clusters +populated on three endpoints. You can use this example as a reference for +creating your own application. + +

+ Nordic Semiconductor logo + nRF52840 DK +

+ +The example is based on +[Matter](https://github.com/project-chip/connectedhomeip) and Nordic +Semiconductor's nRF Connect SDK, and was created to facilitate testing and +certification of a Matter device communicating over a low-power, 802.15.4 Thread +network. + +The example behaves as a Matter accessory, that is a device that can be paired +into an existing Matter network and can be controlled by this network. + +
+ +- [Overview](#overview) + - [Bluetooth LE advertising](#bluetooth-le-advertising) + - [Bluetooth LE rendezvous](#bluetooth-le-rendezvous) +- [Requirements](#requirements) + - [Supported devices](#supported_devices) +- [Device UI](#device-ui) +- [Setting up the environment](#setting-up-the-environment) + - [Using Docker container for setup](#using-docker-container-for-setup) + - [Using native shell for setup](#using-native-shell-for-setup) +- [Building](#building) + - [Removing build artifacts](#removing-build-artifacts) + - [Building with release configuration](#building-with-release-configuration) + - [Building with low-power configuration](#building-with-low-power-configuration) + - [Building with Device Firmware Upgrade support](#building-with-device-firmware-upgrade-support) +- [Configuring the example](#configuring-the-example) +- [Flashing and debugging](#flashing-and-debugging) +- [Testing the example](#testing-the-example) + - [Testing using CHIPTool](#testing-using-chiptool) + +
+ + + +## Overview + +This example is running on the nRF Connect platform, which is based on Nordic +Semiconductor's +[nRF Connect SDK](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/index.html) +and [Zephyr RTOS](https://zephyrproject.org/). Visit Matter's +[nRF Connect platform overview](../../../docs/guides/nrfconnect_platform_overview.md) +to read more about the platform structure and dependencies. + +The Matter device that runs the all clusters application is controlled by the +Matter controller device over the Thread protocol. By default, the Matter device +has Thread disabled, and it should be paired with Matter controller and get +configuration from it. Some actions required before establishing full +communication are described below. + +### Bluetooth LE advertising + +In this example, to commission the device onto a Matter network, it must be +discoverable over Bluetooth LE. For security reasons, you must start Bluetooth +LE advertising manually after powering up the device by pressing **Button 4**. + +### Bluetooth LE rendezvous + +In this example, the commissioning procedure is done over Bluetooth LE between a +Matter device and the Matter controller, where the controller has the +commissioner role. + +To start the rendezvous, the controller must get the commissioning information +from the Matter device. The data payload is encoded within a QR code, printed to +the UART console. + +#### Thread provisioning + +Last part of the rendezvous procedure, the provisioning operation involves +sending the Thread network credentials from the Matter controller to the Matter +device. As a result, device is able to join the Thread network and communicate +with other Thread devices in the network. + +
+ + + +## Requirements + +The application requires a specific revision of the nRF Connect SDK to work +correctly. See [Setting up the environment](#setting-up-the-environment) for +more information. + + + +### Supported devices + +The example supports building and running on the following devices: + +| Hardware platform | Build target | Platform image | +| ----------------------------------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | +| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk_nrf52840` |
nRF52840 DKnRF52840 DK
| +| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk_nrf5340_cpuapp` |
nRF5340 DKnRF5340 DK
| + +
+ + + +## Device UI + +This section lists the User Interface elements that you can use to control and +monitor the state of the device. These correspond to PCB components on the +platform image. + +**LED 1** shows the overall state of the device and its connectivity. The +following states are possible: + +- _Short Flash On (50 ms on/950 ms off)_ — The device is in the + unprovisioned (unpaired) state and is waiting for a commissioning + application to connect. + +- _Rapid Even Flashing (100 ms on/100 ms off)_ — The device is in the + unprovisioned state and a commissioning application is connected through + Bluetooth LE. + +- _Short Flash Off (950ms on/50ms off)_ — The device is fully + provisioned, but does not yet have full Thread network or service + connectivity. + +- _Solid On_ — The device is fully provisioned and has full Thread + network and service connectivity. + +**Button 1** can be used for the following purposes: + +- _Pressed for 6 s_ — Initiates the factory reset of the device. + Releasing the button within the 6-second window cancels the factory reset + procedure. **LEDs 1-4** blink in unison when the factory reset procedure is + initiated. + +**Button 4** — Pressing the button once starts Bluetooth LE advertising +for the predefined period of time (15 minutes by default). + +**SEGGER J-Link USB port** can be used to get logs from the device or +communicate with it using the +[command line interface](../../../docs/guides/nrfconnect_examples_cli.md). + +
+ +## Setting up the environment + +Before building the example, check out the Matter repository and sync submodules +using the following command: + + $ git submodule update --init + +The example requires a specific revision of the nRF Connect SDK. You can either +install it along with the related tools directly on your system or use a Docker +image that has the tools pre-installed. + +If you are a macOS user, you won't be able to use the Docker container to flash +the application onto a Nordic development kit due to +[certain limitations of Docker for macOS](https://docs.docker.com/docker-for-mac/faqs/#can-i-pass-through-a-usb-device-to-a-container). +Use the [native shell](#using-native-shell) for building instead. + +### Using Docker container for setup + +To use the Docker container for setup, complete the following steps: + +1. If you do not have the nRF Connect SDK installed yet, create a directory for + it by running the following command: + + $ mkdir ~/nrfconnect + +2. Download the latest version of the nRF Connect SDK Docker image by running + the following command: + + $ docker pull nordicsemi/nrfconnect-chip + +3. Start Docker with the downloaded image by running the following command, + customized to your needs as described below: + + $ docker run --rm -it -e RUNAS=$(id -u) -v ~/nrfconnect:/var/ncs -v ~/connectedhomeip:/var/chip \ + -v /dev/bus/usb:/dev/bus/usb --device-cgroup-rule "c 189:* rmw" nordicsemi/nrfconnect-chip + + In this command: + + - _~/nrfconnect_ can be replaced with an absolute path to the nRF Connect + SDK source directory. + - _~/connectedhomeip_ must be replaced with an absolute path to the CHIP + source directory. + - _-v /dev/bus/usb:/dev/bus/usb --device-cgroup-rule "c 189:_ rmw"\* + parameters can be omitted if you are not planning to flash the example + onto hardware. These parameters give the container access to USB devices + connected to your computer such as the nRF52840 DK. + - _--rm_ can be omitted if you do not want the container to be + auto-removed when you exit the container shell session. + - _-e RUNAS=\$(id -u)_ is needed to start the container session as the + current user instead of root. + +4. Update the nRF Connect SDK to the most recent supported revision, by running + the following command: + + $ cd /var/chip + $ python3 scripts/setup/nrfconnect/update_ncs.py --update + +Now you can proceed with the [Building](#building) instruction. + +### Using native shell for setup + +To use the native shell for setup, complete the following steps: + +1. Download and install the following additional software: + + - [nRF Command Line Tools](https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Command-Line-Tools) + - [GN meta-build system](https://gn.googlesource.com/gn/) + +2. If you do not have the nRF Connect SDK installed, follow the + [guide](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/gs_assistant.html#) + in the nRF Connect SDK documentation to install the latest stable nRF + Connect SDK version. Since command-line tools will be used for building the + example, installing SEGGER Embedded Studio is not required. + + If you have the SDK already installed, continue to the next step and update + the nRF Connect SDK after initializing environment variables. + +3. Initialize environment variables referred to by the CHIP and the nRF Connect + SDK build scripts. Replace _nrfconnect-dir_ with the path to your nRF + Connect SDK installation directory, and _toolchain-dir_ with the path to GNU + Arm Embedded Toolchain. + + $ source nrfconnect-dir/zephyr/zephyr-env.sh + $ export ZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb + $ export GNUARMEMB_TOOLCHAIN_PATH=toolchain-dir + +4. Update the nRF Connect SDK to the most recent supported revision by running + the following command (replace _matter-dir_ with the path to Matter + repository directory): + + $ cd matter-dir + $ python3 scripts/setup/nrfconnect/update_ncs.py --update + +Now you can proceed with the [Building](#building) instruction. + +
+ + + +## Building + +Complete the following steps, regardless of the method used for setting up the +environment: + +1. Navigate to the example's directory: + + $ cd examples/all-clusters-app/nrfconnect + +2. Run the following command to build the example, with _build-target_ replaced + with the build target name of the Nordic Semiconductor's kit you own, for + example `nrf52840dk_nrf52840`: + + $ west build -b build-target + + You only need to specify the build target on the first build. See + [Requirements](#requirements) for the build target names of compatible kits. + +The output `zephyr.hex` file will be available in the `build/zephyr/` directory. + +### Removing build artifacts + +If you're planning to build the example for a different kit or make changes to +the configuration, remove all build artifacts before building. To do so, use the +following command: + + $ rm -r build + +### Building with release configuration + +To build the example with release configuration that disables the diagnostic +features like logs and command-line interface, run the following command: + + $ west build -b build-target -- -DOVERLAY_CONFIG=third_party/connectedhomeip/config/nrfconnect/app/release.conf + +Remember to replace _build-target_ with the build target name of the Nordic +Semiconductor's kit you own. + +### Building with low-power configuration + +You can build the example using the low-power configuration, which enables +Thread's Sleepy End Device mode and disables debug features, such as the UART +console or the **LED 1** usage. + +To build for the low-power configuration, run the following command with +_build-target_ replaced with the build target name of the Nordic Semiconductor's +kit you own (for example `nrf52840dk_nrf52840`): + + $ west build -b build-target -- -DOVERLAY_CONFIG=overlay-low_power.conf + +For example, use the following command for `nrf52840dk_nrf52840`: + + $ west build -b nrf52840dk_nrf52840 -- -DOVERLAY_CONFIG=overlay-low_power.conf + +### Building with Device Firmware Upgrade support + +Support for DFU using Matter OTA is disabled by default. + +To build the example with configuration that supports DFU, run the following +command with _build-target_ replaced with the build target name of the Nordic +Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): + + $ west build -b build-target -- -DBUILD_WITH_DFU=1 + +> **Note**: +> +> There are two types of Device Firmware Upgrade modes: single-image DFU and +> multi-image DFU. Single-image mode supports upgrading only one firmware image, +> the application image, and should be used for single-core nRF52840 DK devices. +> Multi-image mode allows to upgrade more firmware images and is suitable for +> upgrading the application core and network core firmware in two-core nRF5340 +> DK devices. +> +> Currently the multi-image mode is not available for the Matter OTA DFU. + +#### Changing Device Firmware Upgrade configuration + +To change the default DFU configuration, edit the following overlay files +corresponding to the selected configuration: + +- `overlay-mcuboot_qspi_nor_support.conf` - general file enabling MCUboot and + QSPI NOR support, used by all DFU configurations +- `overlay-ota_requestor.conf` - file enabling Matter OTA Requestor support. + +The files are located in the `config/nrfconnect/app` directory. You can also +define the desired options in your example's `prj.conf` file. + +#### Changing bootloader configuration + +To change the default MCUboot configuration, edit the +`mcuboot_single_image_dfu.conf` or `mcuboot_multi_image_dfu.conf` overlay files +depending on whether the build target device supports multi-image DFU (nRF5340 +DK) or single-image DFU (nRF52840 DK). The files are located in the +`configuration` directory. + +#### Changing flash memory settings + +In the default configuration, the MCUboot uses the +[Partition Manager](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/scripts/partition_manager/partition_manager.html#partition-manager) +to configure flash partitions used for the bootloader application image slot +purposes. You can change these settings by defining +[static partitions](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/scripts/partition_manager/partition_manager.html#ug-pm-static). +This example uses this option to define using an external flash. + +To modify the flash settings of your board (that is, your _build-target_, for +example `nrf52840dk_nrf52840`), edit the `pm_static.yml` file located in the +`configuration/build-target/` directory. + +
+ + + +## Configuring the example + +The Zephyr ecosystem is based on Kconfig files and the settings can be modified +using the menuconfig utility. + +To open the menuconfig utility, run the following command from the example +directory: + + $ west build -b build-target -t menuconfig + +Remember to replace _build-target_ with the build target name of the Nordic +Semiconductor's kit you own. + +Changes done with menuconfig will be lost if the `build` directory is deleted. +To make them persistent, save the configuration options in the `prj.conf` file. +For more information, see the +[Configuring nRF Connect SDK examples](../../../docs/guides/nrfconnect_examples_configuration.md) +page. + +
+ + + +## Flashing and debugging + +To flash the application to the device, use the west tool and run the following +command from the example directory: + + $ west flash --erase + +If you have multiple development kits connected, west will prompt you to pick +the correct one. + +To debug the application on target, run the following command from the example +directory: + + $ west debug + +
+ +## Testing the example + +Check the [CLI tutorial](../../../docs/guides/nrfconnect_examples_cli.md) to +learn how to use command-line interface of the application. + +### Testing using CHIPTool + +Read the +[Android commissioning guide](../../../docs/guides/nrfconnect_android_commissioning.md) +to see how to use [CHIPTool](../../../src/android/CHIPTool/README.md) for +Android smartphones to commission and control the application within a +Matter-enabled Thread network. diff --git a/examples/all-clusters-app/nrfconnect/boards/nrf52840dk_nrf52840.conf b/examples/all-clusters-app/nrfconnect/boards/nrf52840dk_nrf52840.conf new file mode 100644 index 00000000000000..fb419f0c7aa921 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/boards/nrf52840dk_nrf52840.conf @@ -0,0 +1,17 @@ +# +# Copyright (c) 2022 Project CHIP Authors +# +# 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. +# + +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 diff --git a/examples/all-clusters-app/nrfconnect/boards/nrf52840dk_nrf52840.overlay b/examples/all-clusters-app/nrfconnect/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000000..04253ef9667617 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 Project CHIP Authors + * + * 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. + */ + +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + }; + + /* + * In some default configurations within the nRF Connect SDK, + * e.g. on nRF52840, the chosen zephyr,entropy node is &cryptocell. + * This devicetree overlay ensures that default is overridden wherever it + * is set, as this application uses the RNG node for entropy exclusively. + */ + chosen { + zephyr,entropy = &rng; + }; +}; + +/* Disable unused peripherals to reduce power consumption */ +&adc { + status = "disabled"; +}; +&uart1 { + status = "disabled"; +}; +&gpio1 { + status = "disabled"; +}; +&i2c0 { + status = "disabled"; +}; +&pwm0 { + status = "disabled"; +}; +&spi1 { + status = "disabled"; +}; +&spi3 { + status = "disabled"; +}; +&usbd { + status = "disabled"; +}; diff --git a/examples/all-clusters-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.conf b/examples/all-clusters-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000000..ce2e61edce82ca --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,17 @@ +# +# Copyright (c) 2022 Project CHIP Authors +# +# 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. +# + +CONFIG_XOROSHIRO_RANDOM_GENERATOR=y diff --git a/examples/all-clusters-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/all-clusters-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000000..5be8b8fd5f736f --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022 Project CHIP Authors + * + * 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. + */ + +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + }; + + soc { + /* Add a flash controller which has the compatible + * 'zephyr,sim-flash'. This will ensure that the flash + * simulator can use it. None of the other properties in this + * node is used for anything. + */ + nordic_ram_flash_controller: nordic_ram-flash-controller@0 { + compatible = "zephyr,sim-flash"; + reg = <0x00000000 DT_SIZE_K(40)>; + #address-cells = <1>; + #size-cells = <1>; + erase-value = <0xff>; + label = "nordic_ram_flash_flash_controller"; + + /* This node label must match that used in the flash + * simulator. + */ + flash_sim0: flash_sim@0 { + status = "okay"; + compatible = "soc-nv-flash"; + label = "simulated_flash"; + erase-block-size = <4096>; + write-block-size = <4>; + reg = <0x00000000 DT_SIZE_K(256)>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* This partition must be defined for + * MCUboot to find the partition ID + * of the primary slot for image 1, + * which is stored in this partition. + */ + slot2_partition: partition@0 { + label = "image-2"; + reg = <0x00000000 0x00000A000>; + }; + }; + }; + }; + }; + +}; + +/* Disable unused peripherals to reduce power consumption */ +&adc { + status = "disabled"; +}; +&gpio1 { + status = "disabled"; +}; +&i2c1 { + status = "disabled"; +}; +&pwm0 { + status = "disabled"; +}; +&spi2 { + status = "disabled"; +}; +&usbd { + status = "disabled"; +}; diff --git a/examples/all-clusters-app/nrfconnect/child_image/multiprotocol_rpmsg.conf b/examples/all-clusters-app/nrfconnect/child_image/multiprotocol_rpmsg.conf new file mode 100644 index 00000000000000..b22013c122cf4d --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/child_image/multiprotocol_rpmsg.conf @@ -0,0 +1,22 @@ +# +# Copyright (c) 2022 Project CHIP Authors +# +# 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. +# + +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=n +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 diff --git a/examples/all-clusters-app/nrfconnect/configuration/mcuboot_multi_image_dfu.conf b/examples/all-clusters-app/nrfconnect/configuration/mcuboot_multi_image_dfu.conf new file mode 100644 index 00000000000000..ccc69439f449f0 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/configuration/mcuboot_multi_image_dfu.conf @@ -0,0 +1,52 @@ +# +# Copyright (c) 2021 Project CHIP Authors +# +# 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. +# + +# QSPI configuration +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +CONFIG_BOOT_MAX_IMG_SECTORS=256 + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 +CONFIG_BOOT_UPGRADE_ONLY=y +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +# Enable custom command to erase settings partition. +CONFIG_ENABLE_MGMT_PERUSER=y +CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE=y + +# bootloader size optimization +CONFIG_LOG=n +CONFIG_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_BOOT_BANNER=n +CONFIG_TIMESLICING=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_MULTITHREADING=n +CONFIG_TICKLESS_KERNEL=n +CONFIG_TIMEOUT_64BIT=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_GPIO=n +CONFIG_NRF_ENABLE_ICACHE=n diff --git a/examples/all-clusters-app/nrfconnect/configuration/mcuboot_single_image_dfu.conf b/examples/all-clusters-app/nrfconnect/configuration/mcuboot_single_image_dfu.conf new file mode 100644 index 00000000000000..807ba68b805796 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/configuration/mcuboot_single_image_dfu.conf @@ -0,0 +1,38 @@ +# +# Copyright (c) 2021 Project CHIP Authors +# +# 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. +# + +# QSPI configuration +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +CONFIG_BOOT_MAX_IMG_SECTORS=256 + +# bootloader size optimization +CONFIG_LOG=n +CONFIG_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_BOOT_BANNER=n +CONFIG_TIMESLICING=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_MULTITHREADING=n +CONFIG_TICKLESS_KERNEL=n +CONFIG_TIMEOUT_64BIT=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_GPIO=n +CONFIG_NRF_ENABLE_ICACHE=n diff --git a/examples/all-clusters-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static.yml b/examples/all-clusters-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static.yml new file mode 100644 index 00000000000000..9c26550c0902be --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static.yml @@ -0,0 +1,38 @@ +mcuboot: + address: 0x0 + size: 0x7000 + region: flash_primary +mcuboot_pad: + address: 0x7000 + size: 0x200 +app: + address: 0x7200 + size: 0xf0e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x7000 + size: 0xf1000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x7200 + size: 0xf0e00 +settings_storage: + address: 0xf8000 + size: 0x8000 + region: flash_primary +mcuboot_secondary: + address: 0x0 + size: 0xf1000 + device: MX25R64 + region: external_flash +external_flash: + address: 0xf1000 + size: 0x70f000 + device: MX25R64 + region: external_flash diff --git a/examples/all-clusters-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static.yml b/examples/all-clusters-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static.yml new file mode 100644 index 00000000000000..9f9f677d8af4fc --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static.yml @@ -0,0 +1,52 @@ +mcuboot: + address: 0x0 + size: 0xC000 + region: flash_primary +mcuboot_pad: + address: 0xC000 + size: 0x200 +app: + address: 0xC200 + size: 0xebe00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0xC000 + size: 0xec000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0xC200 + size: 0xebe00 +settings_storage: + address: 0xf8000 + size: 0x8000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xec000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xec000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x12C000 + size: 0x6D4000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/all-clusters-app/nrfconnect/main/AppTask.cpp b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp new file mode 100644 index 00000000000000..48a3dc14252710 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTask.h" +#include "AppConfig.h" +#include "AppEvent.h" +#include "Utils.h" + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#define FACTORY_RESET_TRIGGER_TIMEOUT 3000 +#define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000 +#define APP_EVENT_QUEUE_SIZE 10 +#define BUTTON_PUSH_EVENT 1 +#define BUTTON_RELEASE_EVENT 0 + +LOG_MODULE_DECLARE(app); +K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), APP_EVENT_QUEUE_SIZE, alignof(AppEvent)); + +static LEDWidget sStatusLED; +static UnusedLedsWrapper<3> sUnusedLeds{ { DK_LED2, DK_LED3, DK_LED4 } }; +static k_timer sFunctionTimer; + +namespace LedConsts { +constexpr uint32_t kBlinkRate_ms{ 500 }; +namespace StatusLed { +namespace Unprovisioned { +constexpr uint32_t kOn_ms{ 100 }; +constexpr uint32_t kOff_ms{ kOn_ms }; +} // namespace Unprovisioned +namespace Provisioned { +constexpr uint32_t kOn_ms{ 50 }; +constexpr uint32_t kOff_ms{ 950 }; +} // namespace Provisioned + +} // namespace StatusLed +} // namespace LedConsts + +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; + +CHIP_ERROR AppTask::Init() +{ + // Initialize CHIP stack + LOG_INF("Init CHIP stack"); + + CHIP_ERROR err = chip::Platform::MemoryInit(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("Platform::MemoryInit() failed"); + return err; + } + + err = PlatformMgr().InitChipStack(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("PlatformMgr().InitChipStack() failed"); + return err; + } + + err = ThreadStackMgr().InitThreadStack(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("ThreadStackMgr().InitThreadStack() failed"); + return err; + } + +#ifdef CONFIG_OPENTHREAD_MTD_SED + err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); +#else + err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); +#endif + if (err != CHIP_NO_ERROR) + { + LOG_ERR("ConnectivityMgr().SetThreadDeviceType() failed"); + return err; + } + + // Initialize LEDs + LEDWidget::InitGpio(); + LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); + + sStatusLED.Init(SYSTEM_STATE_LED); + + UpdateStatusLED(); + + // Initialize buttons + auto ret = dk_buttons_init(ButtonEventHandler); + if (ret) + { + LOG_ERR("dk_buttons_init() failed"); + return chip::System::MapErrorZephyr(ret); + } + + // Initialize timer user data + k_timer_init(&sFunctionTimer, &AppTask::TimerEventHandler, nullptr); + k_timer_user_data_set(&sFunctionTimer, this); + + // Initialize CHIP server + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); + ReturnErrorOnFailure(chip::Server::GetInstance().Init()); + ConfigurationMgr().LogDeviceConfig(); + PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE)); + InitOTARequestor(); + + // Add CHIP event handler and start CHIP thread. + // Note that all the initialization code should happen prior to this point to avoid data races + // between the main and the CHIP threads + PlatformMgr().AddEventHandler(ChipEventHandler, 0); + err = PlatformMgr().StartEventLoopTask(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("PlatformMgr().StartEventLoopTask() failed"); + } + + return err; +} + +void AppTask::InitOTARequestor() +{ +#if CONFIG_CHIP_OTA_REQUESTOR + mOTAImageProcessor.SetOTADownloader(&mBDXDownloader); + mBDXDownloader.SetImageProcessorDelegate(&mOTAImageProcessor); + mOTARequestorDriver.Init(&mOTARequestor, &mOTAImageProcessor); + mOTARequestor.Init(&chip::Server::GetInstance(), &mOTARequestorDriver, &mBDXDownloader); + chip::SetRequestorInstance(&mOTARequestor); +#endif +} + +CHIP_ERROR AppTask::StartApp() +{ + ReturnErrorOnFailure(Init()); + + AppEvent event{}; + + while (true) + { + k_msgq_get(&sAppEventQueue, &event, K_FOREVER); + DispatchEvent(&event); + } + + return CHIP_NO_ERROR; +} + +void AppTask::ButtonEventHandler(uint32_t aButtonState, uint32_t aHasChanged) +{ + AppEvent event; + event.Type = AppEvent::Type::Button; + + if (FUNCTION_BUTTON_MASK & aHasChanged) + { + event.ButtonEvent.PinNo = FUNCTION_BUTTON; + event.ButtonEvent.Action = (FUNCTION_BUTTON_MASK & aButtonState) ? BUTTON_PUSH_EVENT : BUTTON_RELEASE_EVENT; + event.Handler = FunctionHandler; + PostEvent(&event); + } + + if (BLE_ADVERTISEMENT_START_BUTTON_MASK & aButtonState & aHasChanged) + { + event.ButtonEvent.PinNo = BLE_ADVERTISEMENT_START_BUTTON; + event.ButtonEvent.Action = BUTTON_PUSH_EVENT; + event.Handler = StartBLEAdvertisementHandler; + PostEvent(&event); + } +} + +void AppTask::TimerEventHandler(k_timer * aTimer) +{ + if (!aTimer) + return; + + AppEvent event; + event.Type = AppEvent::Type::Timer; + event.TimerEvent.Context = k_timer_user_data_get(aTimer); + event.Handler = FunctionTimerEventHandler; + PostEvent(&event); +} + +void AppTask::FunctionTimerEventHandler(AppEvent * aEvent) +{ + if (!aEvent) + return; + if (aEvent->Type != AppEvent::Type::Timer) + return; + + // If we reached here, the button was held past FACTORY_RESET_TRIGGER_TIMEOUT, initiate factory reset + if (Instance().mFunctionTimerActive && Instance().mMode == OperatingMode::Normal) + { + LOG_INF("Factory Reset Triggered. Release button within %ums to cancel.", FACTORY_RESET_TRIGGER_TIMEOUT); + + // Start timer for FACTORY_RESET_CANCEL_WINDOW_TIMEOUT to allow user to cancel, if required. + StartTimer(FACTORY_RESET_CANCEL_WINDOW_TIMEOUT); + Instance().mMode = OperatingMode::FactoryReset; + +#ifdef CONFIG_STATE_LEDS + // Turn off all LEDs before starting blink to make sure blink is co-ordinated. + sStatusLED.Set(false); + sUnusedLeds.Set(false); + + sStatusLED.Blink(LedConsts::kBlinkRate_ms); + sUnusedLeds.Blink(LedConsts::kBlinkRate_ms); +#endif + } + else if (Instance().mFunctionTimerActive && Instance().mMode == OperatingMode::FactoryReset) + { + // Actually trigger Factory Reset + Instance().mMode = OperatingMode::Normal; + ConfigurationMgr().InitiateFactoryReset(); + } +} + +void AppTask::FunctionHandler(AppEvent * aEvent) +{ + if (!aEvent) + return; + if (aEvent->ButtonEvent.PinNo != FUNCTION_BUTTON) + return; + + // To initiate factory reset: press the FUNCTION_BUTTON for FACTORY_RESET_TRIGGER_TIMEOUT + FACTORY_RESET_CANCEL_WINDOW_TIMEOUT + // All LEDs start blinking after FACTORY_RESET_TRIGGER_TIMEOUT to signal factory reset has been initiated. + // To cancel factory reset: release the FUNCTION_BUTTON once all LEDs start blinking within the + // FACTORY_RESET_CANCEL_WINDOW_TIMEOUT + if (aEvent->ButtonEvent.Action == BUTTON_PUSH_EVENT) + { + if (!Instance().mFunctionTimerActive && Instance().mMode == OperatingMode::Normal) + { + StartTimer(FACTORY_RESET_TRIGGER_TIMEOUT); + } + } + else + { + if (Instance().mFunctionTimerActive && Instance().mMode == OperatingMode::FactoryReset) + { + sUnusedLeds.Set(false); + + UpdateStatusLED(); + CancelTimer(); + + // Change the function to none selected since factory reset has been canceled. + Instance().mMode = OperatingMode::Normal; + + LOG_INF("Factory Reset has been Canceled"); + } + else if (Instance().mFunctionTimerActive) + { + CancelTimer(); + Instance().mMode = OperatingMode::Normal; + } + } +} + +void AppTask::StartBLEAdvertisementHandler(AppEvent * aEvent) +{ + if (!aEvent) + return; + if (aEvent->ButtonEvent.PinNo != BLE_ADVERTISEMENT_START_BUTTON) + return; + + // Don't allow on starting Matter service BLE advertising after Thread provisioning. + if (ConnectivityMgr().IsThreadProvisioned()) + { + LOG_INF("Matter service BLE advertising not started - device is commissioned to a Thread network."); + return; + } + + if (ConnectivityMgr().IsBLEAdvertisingEnabled()) + { + LOG_INF("BLE advertising is already enabled"); + return; + } + + if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) + { + LOG_ERR("OpenBasicCommissioningWindow() failed"); + } +} + +void AppTask::UpdateLedStateEventHandler(AppEvent * aEvent) +{ + if (!aEvent) + return; + if (aEvent->Type == AppEvent::Type::UpdateLedState) + { + aEvent->UpdateLedStateEvent.LedWidget->UpdateState(); + } +} + +void AppTask::LEDStateUpdateHandler(LEDWidget & aLedWidget) +{ + AppEvent event; + event.Type = AppEvent::Type::UpdateLedState; + event.Handler = UpdateLedStateEventHandler; + event.UpdateLedStateEvent.LedWidget = &aLedWidget; + PostEvent(&event); +} + +void AppTask::UpdateStatusLED() +{ +#ifdef CONFIG_STATE_LEDS + /* Update the status LED. + * + * If thread and service provisioned, keep the LED On constantly. + * + * If the system has ble connection(s) uptill the stage above, THEN blink the LED at an even + * rate of 100ms. + * + * Otherwise, blink the LED On for a very short time. */ + if (Instance().mIsThreadProvisioned && Instance().mIsThreadEnabled) + { + sStatusLED.Set(true); + } + else if (Instance().mHaveBLEConnections) + { + sStatusLED.Blink(LedConsts::StatusLed::Unprovisioned::kOn_ms, LedConsts::StatusLed::Unprovisioned::kOff_ms); + } + else + { + sStatusLED.Blink(LedConsts::StatusLed::Provisioned::kOn_ms, LedConsts::StatusLed::Provisioned::kOff_ms); + } +#endif +} + +void AppTask::ChipEventHandler(const ChipDeviceEvent * aEvent, intptr_t /* aArg */) +{ + if (!aEvent) + return; + switch (aEvent->Type) + { + case DeviceEventType::kCHIPoBLEAdvertisingChange: + Instance().mHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; + UpdateStatusLED(); + break; + case DeviceEventType::kThreadStateChange: + Instance().mIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); + Instance().mIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); + UpdateStatusLED(); + break; + default: + break; + } +} + +void AppTask::CancelTimer() +{ + k_timer_stop(&sFunctionTimer); + Instance().mFunctionTimerActive = false; +} + +void AppTask::StartTimer(uint32_t aTimeoutInMs) +{ + k_timer_start(&sFunctionTimer, K_MSEC(aTimeoutInMs), K_NO_WAIT); + Instance().mFunctionTimerActive = true; +} + +void AppTask::PostEvent(AppEvent * aEvent) +{ + if (!aEvent) + return; + if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT)) + { + LOG_INF("Failed to post event to app task event queue"); + } +} + +void AppTask::DispatchEvent(AppEvent * aEvent) +{ + if (!aEvent) + return; + if (aEvent->Handler) + { + aEvent->Handler(aEvent); + } + else + { + LOG_INF("Event received with no handler. Dropping event."); + } +} diff --git a/examples/all-clusters-app/nrfconnect/main/include/AppConfig.h b/examples/all-clusters-app/nrfconnect/main/include/AppConfig.h new file mode 100644 index 00000000000000..01465d3bb17a62 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/main/include/AppConfig.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +// ---- All Clusters Application example config ---- + +#define FUNCTION_BUTTON DK_BTN1 +#define FUNCTION_BUTTON_MASK DK_BTN1_MSK +#define BLE_ADVERTISEMENT_START_BUTTON DK_BTN4 +#define BLE_ADVERTISEMENT_START_BUTTON_MASK DK_BTN4_MSK + +#define SYSTEM_STATE_LED DK_LED1 diff --git a/examples/all-clusters-app/nrfconnect/main/include/AppEvent.h b/examples/all-clusters-app/nrfconnect/main/include/AppEvent.h new file mode 100644 index 00000000000000..f6cac85b182b32 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/main/include/AppEvent.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +class LEDWidget; + +struct AppEvent +{ + using EventHandler = void (*)(AppEvent *); + + enum class Type : uint8_t + { + None, + Button, + Timer, + UpdateLedState, + }; + + Type Type{ Type::None }; + + union + { + struct + { + uint8_t PinNo; + uint8_t Action; + } ButtonEvent; + struct + { + void * Context; + } TimerEvent; + struct + { + LEDWidget * LedWidget; + } UpdateLedStateEvent; + }; + + EventHandler Handler; +}; diff --git a/examples/all-clusters-app/nrfconnect/main/include/AppTask.h b/examples/all-clusters-app/nrfconnect/main/include/AppTask.h new file mode 100644 index 00000000000000..3f8b5b82e95422 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/main/include/AppTask.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#if CONFIG_CHIP_OTA_REQUESTOR +#include +#include +#include +#include +#endif + +struct k_timer; +class AppEvent; +class LEDWidget; + +class AppTask +{ +public: + static AppTask & Instance(void) + { + static AppTask sAppTask; + return sAppTask; + }; + CHIP_ERROR StartApp(); + +private: + enum class OperatingMode : uint8_t + { + Normal, + FactoryReset, + Invalid + }; + + CHIP_ERROR Init(); + void DispatchEvent(AppEvent * aEvent); + void InitOTARequestor(); + + // statics needed to interact with zephyr C API + static void CancelTimer(void); + static void StartTimer(uint32_t aTimeoutInMs); + static void FunctionTimerEventHandler(AppEvent * aEvent); + static void FunctionHandler(AppEvent * aEvent); + static void ButtonEventHandler(uint32_t aButtonsState, uint32_t aHasChanged); + static void TimerEventHandler(k_timer * aTimer); + static void PostEvent(AppEvent * aEvent); + static void UpdateStatusLED(); + static void LEDStateUpdateHandler(LEDWidget & aLedWidget); + static void UpdateLedStateEventHandler(AppEvent * aEvent); + static void StartBLEAdvertisementHandler(AppEvent * aEvent); + static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent * aEvent, intptr_t aArg); + + OperatingMode mMode{ OperatingMode::Normal }; + bool mFunctionTimerActive{ false }; + bool mIsThreadProvisioned{ false }; + bool mIsThreadEnabled{ false }; + bool mHaveBLEConnections{ false }; + +#if CONFIG_CHIP_OTA_REQUESTOR + chip::DeviceLayer::GenericOTARequestorDriver mOTARequestorDriver; + chip::DeviceLayer::OTAImageProcessorImpl mOTAImageProcessor; + chip::BDXDownloader mBDXDownloader; + chip::OTARequestor mOTARequestor; +#endif +}; diff --git a/examples/all-clusters-app/nrfconnect/main/include/CHIPProjectConfig.h b/examples/all-clusters-app/nrfconnect/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..49000724fc6c47 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/main/include/CHIPProjectConfig.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 + +#define CHIP_DEVICE_CONFIG_SED_SLOW_POLLING_INTERVAL 2000_ms32 diff --git a/examples/all-clusters-app/nrfconnect/main/include/Utils.h b/examples/all-clusters-app/nrfconnect/main/include/Utils.h new file mode 100644 index 00000000000000..fe02c3aa176ce6 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/main/include/Utils.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "LEDWidget.h" + +#include + +// A lightweight wrrapper for unused LEDs +template +class UnusedLedsWrapper +{ +public: + using Gpio = uint32_t; + using Leds = std::array, size>; + + explicit UnusedLedsWrapper(std::array aLeds) + { + auto idx{ 0 }; + for (const auto & led : aLeds) + mLeds[idx++] = std::make_pair(led, LEDWidget()); + Init(); + } + void Set(bool aState) + { + for (auto & led : mLeds) + led.second.Set(aState); + } + void Blink(uint32_t aRate) + { + for (auto & led : mLeds) + led.second.Blink(aRate); + } + +private: + void Init() + { + LEDWidget::InitGpio(); + for (auto & led : mLeds) + led.second.Init(led.first); + } + Leds mLeds; +}; diff --git a/examples/all-clusters-app/nrfconnect/main/main.cpp b/examples/all-clusters-app/nrfconnect/main/main.cpp new file mode 100644 index 00000000000000..3e3f506d66d1f7 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/main/main.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTask.h" + +#include + +LOG_MODULE_REGISTER(app); + +using namespace ::chip; + +int main() +{ + CHIP_ERROR err = AppTask::Instance().StartApp(); + + LOG_ERR("Exited with code %" CHIP_ERROR_FORMAT, err.Format()); + return err == CHIP_NO_ERROR ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/all-clusters-app/nrfconnect/overlay-low_power.conf b/examples/all-clusters-app/nrfconnect/overlay-low_power.conf new file mode 100644 index 00000000000000..c962425f6ef937 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/overlay-low_power.conf @@ -0,0 +1,30 @@ +# +# Copyright (c) 2022 Project CHIP Authors +# +# 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. +# + +# Enable MTD Sleepy End Device +CONFIG_CHIP_ENABLE_SLEEPY_END_DEVICE_SUPPORT=y + +# Disable UART console +CONFIG_SHELL=n +CONFIG_LOG=n +CONFIG_UART_CONSOLE=n +CONFIG_SERIAL=n + +# Suspend devices when the CPU goes to sleep +CONFIG_PM_DEVICE=y + +# Disable auxiliary state LEDs +CONFIG_STATE_LEDS=n diff --git a/examples/all-clusters-app/nrfconnect/prj.conf b/examples/all-clusters-app/nrfconnect/prj.conf new file mode 100644 index 00000000000000..d3ba4fab874572 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/prj.conf @@ -0,0 +1,41 @@ +# +# Copyright (c) 2022 Project CHIP Authors +# +# 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 sample uses sample-defaults.conf to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Add support for LEDs and buttons on Nordic development kits +CONFIG_DK_LIBRARY=y + +# Default OpenThread network settings +CONFIG_OPENTHREAD_PANID=4660 +CONFIG_OPENTHREAD_CHANNEL=15 +CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" +CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" + +# Bluetooth overrides +CONFIG_BT_DEVICE_NAME="AllClusters" + +# Additional configs for debbugging experience. +CONFIG_THREAD_NAME=y +CONFIG_MPU_STACK_GUARD=y + +# CHIP configuration +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" + +# CHIP PID: 32769 == 0x8001 (all-clusters-app) +CONFIG_CHIP_DEVICE_PRODUCT_ID=32769 diff --git a/examples/all-clusters-app/nrfconnect/third_party/connectedhomeip b/examples/all-clusters-app/nrfconnect/third_party/connectedhomeip new file mode 120000 index 00000000000000..c866b86874994d --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../.. \ No newline at end of file