From 95658603a660c7ccdd00fbc7f28300931ab3c9ca Mon Sep 17 00:00:00 2001 From: adabreuti <76965454+adabreuti@users.noreply.github.com> Date: Wed, 24 May 2023 10:09:08 -0500 Subject: [PATCH] Add CC13x4 Example Application support (#26576) * Add CC13x4 Example Application support Upgrade lock-app to utilize latest UART driver isntances Update README's with clearer CHIP CLI instructions * Deprecate CC13x4 all-clusters-minimal Resovle README CI failures * Restyled by prettier-markdown * Update CI to support CC13x4 * Revert "Update CI to support CC13x4" This reverts commit 7b86eccd30dbe7c3f060e436b8578114d6507952. --------- Co-authored-by: Restyled.io --- docs/guides/darwin.md | 2 +- .../cc13x2x7_26x2x7/README.md | 7 +- examples/all-clusters-app/cc13x4_26x4/.gn | 28 + .../all-clusters-app/cc13x4_26x4/BUILD.gn | 125 ++++ .../all-clusters-app/cc13x4_26x4/README.md | 306 ++++++++ .../all-clusters-app/cc13x4_26x4/args.gni | 50 ++ .../cc13x4_26x4/build_overrides | 1 + .../all-clusters-app/cc13x4_26x4/chip.syscfg | 242 ++++++ .../cc13x4_26x4/main/AppTask.cpp | 402 ++++++++++ .../cc13x4_26x4/main/ClusterManager.cpp | 176 +++++ .../cc13x4_26x4/main/Globals.cpp | 22 + .../cc13x4_26x4/main/ZclCallbacks.cpp | 82 ++ .../cc13x4_26x4/main/include/AppConfig.h | 21 + .../cc13x4_26x4/main/include/AppEvent.h | 60 ++ .../cc13x4_26x4/main/include/AppTask.h | 72 ++ .../main/include/CHIPProjectConfig.h | 132 ++++ .../cc13x4_26x4/main/include/ClusterManager.h | 50 ++ .../cc13x4_26x4/main/include/Globals.h | 35 + .../main/include/OpenThreadConfig.h | 29 + .../cc13x4_26x4/main/main.cpp | 104 +++ .../cc13x4_26x4/third_party/connectedhomeip | 1 + .../lighting-app/cc13x2x7_26x2x7/README.md | 297 ++++++++ examples/lighting-app/cc13x4_26x4/.gn | 28 + examples/lighting-app/cc13x4_26x4/BUILD.gn | 120 +++ examples/lighting-app/cc13x4_26x4/README.md | 297 ++++++++ examples/lighting-app/cc13x4_26x4/args.gni | 50 ++ .../lighting-app/cc13x4_26x4/build_overrides | 1 + examples/lighting-app/cc13x4_26x4/chip.syscfg | 242 ++++++ .../cc13x4_26x4/include/CHIPProjectConfig.h | 122 +++ .../lighting-app/cc13x4_26x4/src/AppConfig.h | 35 + .../lighting-app/cc13x4_26x4/src/AppEvent.h | 85 +++ .../lighting-app/cc13x4_26x4/src/AppTask.cpp | 539 ++++++++++++++ .../lighting-app/cc13x4_26x4/src/AppTask.h | 93 +++ .../cc13x4_26x4/src/LightingManager.cpp | 176 +++++ .../cc13x4_26x4/src/LightingManager.h | 82 ++ .../cc13x4_26x4/src/ZclCallbacks.cpp | 75 ++ .../lighting-app/cc13x4_26x4/src/main.cpp | 104 +++ .../cc13x4_26x4/third_party/connectedhomeip | 1 + examples/lock-app/cc13x2x7_26x2x7/README.md | 152 +++- examples/lock-app/cc13x2x7_26x2x7/chip.syscfg | 78 +- examples/lock-app/cc13x4_26x4/.gn | 28 + examples/lock-app/cc13x4_26x4/BUILD.gn | 120 +++ examples/lock-app/cc13x4_26x4/README.md | 326 ++++++++ examples/lock-app/cc13x4_26x4/args.gni | 49 ++ examples/lock-app/cc13x4_26x4/build_overrides | 1 + examples/lock-app/cc13x4_26x4/chip.syscfg | 242 ++++++ .../cc13x4_26x4/include/CHIPProjectConfig.h | 130 ++++ examples/lock-app/cc13x4_26x4/src/AppConfig.h | 35 + examples/lock-app/cc13x4_26x4/src/AppEvent.h | 68 ++ examples/lock-app/cc13x4_26x4/src/AppTask.cpp | 560 ++++++++++++++ examples/lock-app/cc13x4_26x4/src/AppTask.h | 92 +++ .../lock-app/cc13x4_26x4/src/LockManager.cpp | 703 ++++++++++++++++++ .../lock-app/cc13x4_26x4/src/LockManager.h | 221 ++++++ .../lock-app/cc13x4_26x4/src/ZclCallbacks.cpp | 149 ++++ examples/lock-app/cc13x4_26x4/src/main.cpp | 104 +++ .../cc13x4_26x4/third_party/connectedhomeip | 1 + examples/lock-app/cc32xx/main/AppConfig.h | 1 - examples/lock-app/cc32xx/main/AppEvent.h | 2 +- .../cc13x2x7_26x2x7/README.md | 20 +- .../project_include/OpenThreadConfig.h | 1 + examples/platform/cc13x4_26x4/BUILD.gn | 44 ++ .../CC13X4_26X4DeviceAttestationCreds.cpp | 263 +++++++ .../CC13X4_26X4DeviceAttestationCreds.h | 36 + examples/platform/cc13x4_26x4/args.gni | 27 + .../project_include/OpenThreadConfig.h | 99 +++ examples/pump-app/cc13x2x7_26x2x7/README.md | 248 ++++-- examples/pump-app/cc13x4_26x4/.gn | 28 + examples/pump-app/cc13x4_26x4/BUILD.gn | 119 +++ examples/pump-app/cc13x4_26x4/README.md | 310 ++++++++ examples/pump-app/cc13x4_26x4/args.gni | 48 ++ examples/pump-app/cc13x4_26x4/build_overrides | 1 + examples/pump-app/cc13x4_26x4/chip.syscfg | 242 ++++++ .../pump-app/cc13x4_26x4/main/AppTask.cpp | 676 +++++++++++++++++ .../cc13x4_26x4/main/CHIPDeviceManager.cpp | 91 +++ .../cc13x4_26x4/main/DeviceCallbacks.cpp | 211 ++++++ .../pump-app/cc13x4_26x4/main/PumpManager.cpp | 333 +++++++++ .../cc13x4_26x4/main/ZclCallbacks.cpp | 55 ++ .../cc13x4_26x4/main/include/AppConfig.h | 33 + .../cc13x4_26x4/main/include/AppEvent.h | 63 ++ .../cc13x4_26x4/main/include/AppTask.h | 89 +++ .../main/include/CHIPDeviceManager.h | 144 ++++ .../main/include/CHIPProjectConfig.h | 129 ++++ .../main/include/DeviceCallbacks.h | 49 ++ .../main/include/OpenThreadConfig.h | 29 + .../cc13x4_26x4/main/include/PumpManager.h | 102 +++ examples/pump-app/cc13x4_26x4/main/main.cpp | 104 +++ .../cc13x4_26x4/third_party/connectedhomeip | 1 + .../cc13x2x7_26x2x7/README.md | 233 ++++-- examples/pump-controller-app/cc13x4_26x4/.gn | 28 + .../pump-controller-app/cc13x4_26x4/BUILD.gn | 118 +++ .../pump-controller-app/cc13x4_26x4/README.md | 298 ++++++++ .../pump-controller-app/cc13x4_26x4/args.gni | 48 ++ .../cc13x4_26x4/build_overrides | 1 + .../cc13x4_26x4/chip.syscfg | 242 ++++++ .../cc13x4_26x4/main/AppTask.cpp | 461 ++++++++++++ .../cc13x4_26x4/main/PumpManager.cpp | 204 +++++ .../cc13x4_26x4/main/ZclCallbacks.cpp | 69 ++ .../cc13x4_26x4/main/include/AppConfig.h | 34 + .../cc13x4_26x4/main/include/AppEvent.h | 63 ++ .../cc13x4_26x4/main/include/AppTask.h | 84 +++ .../main/include/CHIPProjectConfig.h | 123 +++ .../main/include/OpenThreadConfig.h | 29 + .../cc13x4_26x4/main/include/PumpManager.h | 88 +++ .../cc13x4_26x4/main/main.cpp | 104 +++ .../cc13x4_26x4/third_party/connectedhomeip | 1 + examples/shell/cc13x2x7_26x2x7/README.md | 45 +- examples/shell/cc13x4_26x4/.gn | 28 + examples/shell/cc13x4_26x4/BUILD.gn | 122 +++ examples/shell/cc13x4_26x4/README.md | 183 +++++ examples/shell/cc13x4_26x4/args.gni | 51 ++ examples/shell/cc13x4_26x4/build_overrides | 1 + examples/shell/cc13x4_26x4/chip.syscfg | 242 ++++++ examples/shell/cc13x4_26x4/include/AppTask.h | 47 ++ .../cc13x4_26x4/include/CHIPProjectConfig.h | 122 +++ .../cc13x4_26x4/include/OpenThreadConfig.h | 28 + examples/shell/cc13x4_26x4/main/AppTask.cpp | 181 +++++ examples/shell/cc13x4_26x4/main/main.cpp | 108 +++ .../cc13x4_26x4/third_party/connectedhomeip | 1 + src/platform/cc13xx_26xx/Logging.cpp | 2 +- 119 files changed, 14111 insertions(+), 229 deletions(-) create mode 100644 examples/all-clusters-app/cc13x4_26x4/.gn create mode 100644 examples/all-clusters-app/cc13x4_26x4/BUILD.gn create mode 100644 examples/all-clusters-app/cc13x4_26x4/README.md create mode 100644 examples/all-clusters-app/cc13x4_26x4/args.gni create mode 120000 examples/all-clusters-app/cc13x4_26x4/build_overrides create mode 100644 examples/all-clusters-app/cc13x4_26x4/chip.syscfg create mode 100644 examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp create mode 100644 examples/all-clusters-app/cc13x4_26x4/main/ClusterManager.cpp create mode 100644 examples/all-clusters-app/cc13x4_26x4/main/Globals.cpp create mode 100644 examples/all-clusters-app/cc13x4_26x4/main/ZclCallbacks.cpp create mode 100644 examples/all-clusters-app/cc13x4_26x4/main/include/AppConfig.h create mode 100644 examples/all-clusters-app/cc13x4_26x4/main/include/AppEvent.h create mode 100644 examples/all-clusters-app/cc13x4_26x4/main/include/AppTask.h create mode 100644 examples/all-clusters-app/cc13x4_26x4/main/include/CHIPProjectConfig.h create mode 100644 examples/all-clusters-app/cc13x4_26x4/main/include/ClusterManager.h create mode 100644 examples/all-clusters-app/cc13x4_26x4/main/include/Globals.h create mode 100644 examples/all-clusters-app/cc13x4_26x4/main/include/OpenThreadConfig.h create mode 100644 examples/all-clusters-app/cc13x4_26x4/main/main.cpp create mode 120000 examples/all-clusters-app/cc13x4_26x4/third_party/connectedhomeip create mode 100644 examples/lighting-app/cc13x2x7_26x2x7/README.md create mode 100644 examples/lighting-app/cc13x4_26x4/.gn create mode 100644 examples/lighting-app/cc13x4_26x4/BUILD.gn create mode 100644 examples/lighting-app/cc13x4_26x4/README.md create mode 100644 examples/lighting-app/cc13x4_26x4/args.gni create mode 120000 examples/lighting-app/cc13x4_26x4/build_overrides create mode 100644 examples/lighting-app/cc13x4_26x4/chip.syscfg create mode 100644 examples/lighting-app/cc13x4_26x4/include/CHIPProjectConfig.h create mode 100644 examples/lighting-app/cc13x4_26x4/src/AppConfig.h create mode 100644 examples/lighting-app/cc13x4_26x4/src/AppEvent.h create mode 100644 examples/lighting-app/cc13x4_26x4/src/AppTask.cpp create mode 100644 examples/lighting-app/cc13x4_26x4/src/AppTask.h create mode 100644 examples/lighting-app/cc13x4_26x4/src/LightingManager.cpp create mode 100644 examples/lighting-app/cc13x4_26x4/src/LightingManager.h create mode 100644 examples/lighting-app/cc13x4_26x4/src/ZclCallbacks.cpp create mode 100644 examples/lighting-app/cc13x4_26x4/src/main.cpp create mode 120000 examples/lighting-app/cc13x4_26x4/third_party/connectedhomeip create mode 100644 examples/lock-app/cc13x4_26x4/.gn create mode 100644 examples/lock-app/cc13x4_26x4/BUILD.gn create mode 100644 examples/lock-app/cc13x4_26x4/README.md create mode 100644 examples/lock-app/cc13x4_26x4/args.gni create mode 120000 examples/lock-app/cc13x4_26x4/build_overrides create mode 100644 examples/lock-app/cc13x4_26x4/chip.syscfg create mode 100644 examples/lock-app/cc13x4_26x4/include/CHIPProjectConfig.h create mode 100644 examples/lock-app/cc13x4_26x4/src/AppConfig.h create mode 100644 examples/lock-app/cc13x4_26x4/src/AppEvent.h create mode 100644 examples/lock-app/cc13x4_26x4/src/AppTask.cpp create mode 100644 examples/lock-app/cc13x4_26x4/src/AppTask.h create mode 100644 examples/lock-app/cc13x4_26x4/src/LockManager.cpp create mode 100644 examples/lock-app/cc13x4_26x4/src/LockManager.h create mode 100644 examples/lock-app/cc13x4_26x4/src/ZclCallbacks.cpp create mode 100644 examples/lock-app/cc13x4_26x4/src/main.cpp create mode 120000 examples/lock-app/cc13x4_26x4/third_party/connectedhomeip create mode 100644 examples/platform/cc13x4_26x4/BUILD.gn create mode 100644 examples/platform/cc13x4_26x4/CC13X4_26X4DeviceAttestationCreds.cpp create mode 100644 examples/platform/cc13x4_26x4/CC13X4_26X4DeviceAttestationCreds.h create mode 100644 examples/platform/cc13x4_26x4/args.gni create mode 100644 examples/platform/cc13x4_26x4/project_include/OpenThreadConfig.h create mode 100644 examples/pump-app/cc13x4_26x4/.gn create mode 100644 examples/pump-app/cc13x4_26x4/BUILD.gn create mode 100644 examples/pump-app/cc13x4_26x4/README.md create mode 100644 examples/pump-app/cc13x4_26x4/args.gni create mode 120000 examples/pump-app/cc13x4_26x4/build_overrides create mode 100644 examples/pump-app/cc13x4_26x4/chip.syscfg create mode 100644 examples/pump-app/cc13x4_26x4/main/AppTask.cpp create mode 100644 examples/pump-app/cc13x4_26x4/main/CHIPDeviceManager.cpp create mode 100644 examples/pump-app/cc13x4_26x4/main/DeviceCallbacks.cpp create mode 100644 examples/pump-app/cc13x4_26x4/main/PumpManager.cpp create mode 100644 examples/pump-app/cc13x4_26x4/main/ZclCallbacks.cpp create mode 100644 examples/pump-app/cc13x4_26x4/main/include/AppConfig.h create mode 100644 examples/pump-app/cc13x4_26x4/main/include/AppEvent.h create mode 100644 examples/pump-app/cc13x4_26x4/main/include/AppTask.h create mode 100644 examples/pump-app/cc13x4_26x4/main/include/CHIPDeviceManager.h create mode 100644 examples/pump-app/cc13x4_26x4/main/include/CHIPProjectConfig.h create mode 100644 examples/pump-app/cc13x4_26x4/main/include/DeviceCallbacks.h create mode 100644 examples/pump-app/cc13x4_26x4/main/include/OpenThreadConfig.h create mode 100644 examples/pump-app/cc13x4_26x4/main/include/PumpManager.h create mode 100644 examples/pump-app/cc13x4_26x4/main/main.cpp create mode 120000 examples/pump-app/cc13x4_26x4/third_party/connectedhomeip create mode 100644 examples/pump-controller-app/cc13x4_26x4/.gn create mode 100644 examples/pump-controller-app/cc13x4_26x4/BUILD.gn create mode 100644 examples/pump-controller-app/cc13x4_26x4/README.md create mode 100644 examples/pump-controller-app/cc13x4_26x4/args.gni create mode 120000 examples/pump-controller-app/cc13x4_26x4/build_overrides create mode 100644 examples/pump-controller-app/cc13x4_26x4/chip.syscfg create mode 100644 examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp create mode 100644 examples/pump-controller-app/cc13x4_26x4/main/PumpManager.cpp create mode 100644 examples/pump-controller-app/cc13x4_26x4/main/ZclCallbacks.cpp create mode 100644 examples/pump-controller-app/cc13x4_26x4/main/include/AppConfig.h create mode 100644 examples/pump-controller-app/cc13x4_26x4/main/include/AppEvent.h create mode 100644 examples/pump-controller-app/cc13x4_26x4/main/include/AppTask.h create mode 100644 examples/pump-controller-app/cc13x4_26x4/main/include/CHIPProjectConfig.h create mode 100644 examples/pump-controller-app/cc13x4_26x4/main/include/OpenThreadConfig.h create mode 100644 examples/pump-controller-app/cc13x4_26x4/main/include/PumpManager.h create mode 100644 examples/pump-controller-app/cc13x4_26x4/main/main.cpp create mode 120000 examples/pump-controller-app/cc13x4_26x4/third_party/connectedhomeip create mode 100644 examples/shell/cc13x4_26x4/.gn create mode 100644 examples/shell/cc13x4_26x4/BUILD.gn create mode 100644 examples/shell/cc13x4_26x4/README.md create mode 100644 examples/shell/cc13x4_26x4/args.gni create mode 120000 examples/shell/cc13x4_26x4/build_overrides create mode 100644 examples/shell/cc13x4_26x4/chip.syscfg create mode 100644 examples/shell/cc13x4_26x4/include/AppTask.h create mode 100644 examples/shell/cc13x4_26x4/include/CHIPProjectConfig.h create mode 100644 examples/shell/cc13x4_26x4/include/OpenThreadConfig.h create mode 100644 examples/shell/cc13x4_26x4/main/AppTask.cpp create mode 100644 examples/shell/cc13x4_26x4/main/main.cpp create mode 120000 examples/shell/cc13x4_26x4/third_party/connectedhomeip diff --git a/docs/guides/darwin.md b/docs/guides/darwin.md index 28a05823d8416b..b83a943e325731 100644 --- a/docs/guides/darwin.md +++ b/docs/guides/darwin.md @@ -268,7 +268,7 @@ Example: - [Simulated Linux](./simulated_device_linux.md) - [Telink](/examples/lighting-app/telink/README.md) - [TI Platform](./ti_platform_overview.md) -- [TI All Clusters](/examples/all-clusters-app/cc13x2x7_26x2x7/README.md) +- [TI All Clusters](/examples/all-clusters-app/cc13x4_26x4/README.md) - [Tizen](/examples/lighting-app/tizen/README.md) ## Providing Feedback to Apple diff --git a/examples/all-clusters-app/cc13x2x7_26x2x7/README.md b/examples/all-clusters-app/cc13x2x7_26x2x7/README.md index d34c57c36d6587..f965d3dd9abbcf 100644 --- a/examples/all-clusters-app/cc13x2x7_26x2x7/README.md +++ b/examples/all-clusters-app/cc13x2x7_26x2x7/README.md @@ -63,9 +63,8 @@ Some initial setup is necessary for preparing the build environment. This section will need to be done when migrating to new versions of the SDK. This guide assumes that the environment is linux based, and recommends Ubuntu 20.04. -- Download and install [SysConfig][sysconfig] ([recommended - version][sysconfig_recommended]). This can be done simply with the following - commands. +- Download and install [SysConfig][sysconfig]. This can be done simply with + the following commands. ``` $ cd ~ @@ -236,8 +235,6 @@ Additionally, we welcome any feedback. [matter-e2e-faq]: https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/1082428/faq-cc2652r7-matter----getting-started-guide [sysconfig]: https://www.ti.com/tool/SYSCONFIG -[sysconfig_recommended]: - https://software-dl.ti.com/ccs/esd/sysconfig/sysconfig-1.11.0_2225-setup.run [ti_thread_dnd]: https://www.ti.com/wireless-connectivity/thread/design-development.html [ot_border_router_setup]: https://openthread.io/guides/border-router/build diff --git a/examples/all-clusters-app/cc13x4_26x4/.gn b/examples/all-clusters-app/cc13x4_26x4/.gn new file mode 100644 index 00000000000000..3d48789e30ab3d --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/.gn @@ -0,0 +1,28 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/build.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "freertos" + + import("//args.gni") +} diff --git a/examples/all-clusters-app/cc13x4_26x4/BUILD.gn b/examples/all-clusters-app/cc13x4_26x4/BUILD.gn new file mode 100644 index 00000000000000..259fbdfa960eeb --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/BUILD.gn @@ -0,0 +1,125 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/openthread.gni") +import("//build_overrides/ti_simplelink_sdk.gni") + +import("${build_root}/config/defaults.gni") + +import("${chip_root}/src/platform/device.gni") + +import("${ti_simplelink_sdk_build_root}/ti_simplelink_executable.gni") +import("${ti_simplelink_sdk_build_root}/ti_simplelink_sdk.gni") + +assert(current_os == "freertos") + +project_dir = "${chip_root}/examples/all-clusters-app/cc13x4_26x4" + +ti_simplelink_sdk("sdk") { + include_dirs = [ "${project_dir}/main/include" ] + public_configs = [ ":all-clusters-app_config" ] +} + +ti_sysconfig("sysconfig") { + sources = [ "${project_dir}/chip.syscfg" ] + + outputs = [ + "ti_devices_config.c", + "ti_radio_config.c", + "ti_radio_config.h", + "ti_drivers_config.c", + "ti_drivers_config.h", + "ti_ble_config.c", + "ti_ble_config.h", + "ti_dmm_application_policy.c", + "ti_dmm_application_policy.h", + + # disabled until upstream generation is aligned + #"tiop_config.h", + #"tiop_config.c", + + # not traditional source files + #"ti_utils_build_linker.cmd.genlibs", + #"syscfg_c.rov.xs", + #"ti_utils_runtime_model.gv", + #"ti_utils_runtime_Makefile", + #"ti_ble_app_config.opt", + #"ti_build_config.opt", + ] + + public_configs = [ ":sdk_dmm_config" ] + + cflags = [ + "-Wno-comment", + "@" + rebase_path("${target_gen_dir}/sysconfig/ti_ble_app_config.opt", + root_build_dir), + "@" + rebase_path("${target_gen_dir}/sysconfig/ti_build_config.opt", + root_build_dir), + ] +} + +ti_simplelink_executable("all-clusters-app") { + output_name = "chip-${ti_simplelink_board}-all-clusters-example.out" + + sources = [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", + "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", + "${project_dir}/main/AppTask.cpp", + "${project_dir}/main/ClusterManager.cpp", + "${project_dir}/main/Globals.cpp", + "${project_dir}/main/ZclCallbacks.cpp", + "${project_dir}/main/main.cpp", + ] + + deps = [ + ":sdk", + ":sysconfig", + "${chip_root}/examples/all-clusters-app/all-clusters-common", + "${chip_root}/examples/platform/cc13x4_26x4:cc13x4_26x4-attestation-credentials", + "${chip_root}/src/lib", + ] + + if (chip_openthread_ftd) { + deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-ftd" ] + } else { + deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-mtd" ] + } + + include_dirs = [ + "${project_dir}", + "${project_dir}/main", + "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/providers/", + ] + + cflags = [ + "-Wno-implicit-fallthrough", + "-Wno-sign-compare", + "-Wconversion", + ] + + output_dir = root_out_dir +} + +group("cc13x4_26x4") { + deps = [ ":all-clusters-app" ] +} + +group("default") { + deps = [ ":cc13x4_26x4" ] +} diff --git a/examples/all-clusters-app/cc13x4_26x4/README.md b/examples/all-clusters-app/cc13x4_26x4/README.md new file mode 100644 index 00000000000000..3415f19f1a4c21 --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/README.md @@ -0,0 +1,306 @@ +# Matter All-clusters Example Application + +An example application showing the use of [Matter][matter] on the Texas +Instruments CC13XX_26XX family of Wireless MCUs. + +--- + +- [Matter All Clusters Example Application](#matter-all-clusters-example-application) + - [Introduction](#introduction) + - [Device UI](#device-ui) + - [Building](#building) + - [Preparation](#preparation) + - [Compilation](#compilation) + - [Programming](#programming) + - [Code Composer Studio](#code-composer-studio) + - [UniFlash](#uniflash) + - [Running the Example](#running-the-example) + - [Provisioning](#provisioning) + - [Bluetooth LE Advertising](#bluetooth-le-advertising) + - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) + - [TI Support](#ti-support) + +--- + +## Introduction + +The CC13XX_26XX all clusters example application provides the basis to query and +run commands for all currently implemented Matter clusters. This uses the +open-source Matter implementation and the Texas Instruments SimpleLinkā„¢ CC13XX +and CC26XX software development kit. + +This example is enabled to build for CC1354P10 devices. + +The all-clusters example is intended to serve both as a means to explore the +workings of Matter, as well as a template for creating real products based on +the Texas Instruments devices. + +## Device UI + +| Action | Functionality | +| ------------------------------------------------ | --------------------------------------------- | +| Left Button (`BTN-1`) Press (more than 1000 ms) | Factory Reset | +| Right Button (`BTN-2`) Press (more than 1000 ms) | BLE Advertisement (Enable/Disable) | +| Red LED Solid Blinking State | Identify Trigger Effect in progress (`EP0/1`) | +| Red LED Off State | No Identify Trigger Effect in progress | +| Green LED Blinking State | Identify Trigger Effect in progress (`EP2`) | +| Green LED Off State | No Identify Trigger Effect in progress | + +## Building + +### Preparation + +Some initial setup is necessary for preparing the build environment. This +section will need to be done when migrating to new versions of the SDK. This +guide assumes that the environment is linux based, and recommends Ubuntu 20.04. + +- Download and install [SysConfig][sysconfig]. This can be done simply with + the following commands. + + ``` + $ cd ~ + $ `wget https://dr-download.ti.com/software-development/ide-configuration-compiler-or-debugger/MD-nsUM6f7Vvb/1.15.0.2826/sysconfig-1.15.0_2826-setup.run` + $ chmod +x sysconfig-1.15.0_2826-setup.run + $ ./sysconfig-1.15.0_2826-setup.run + ``` + +- Run the bootstrap script to setup the build environment. + + ``` + $ cd ~/connectedhomeip + $ source ./scripts/bootstrap.sh + + ``` + +### Compilation + +It is necessary to activate the environment in every new shell. Then run GN and +Ninja to build the executable. + +- Activate the build environment with the repository activate script. + + ``` + $ cd ~/connectedhomeip + $ source ./scripts/activate.sh + + ``` + +- Run the build to produce a default executable. By default on Linux both the + TI SimpleLink SDK and Sysconfig are located in a `ti` folder in the user's + home directory, and you must provide the absolute path to them. For example + `/home/username/ti/sysconfig_1.15.0`. On Windows the default directory is + `C:\ti`. Take note of this install path, as it will be used in the next + step. + + ``` + $ cd ~/connectedhomeip/examples/all-clusters-app/cc13x2x7_26x2x7 + OR + $ cd ~/connectedhomeip/examples/all-clusters-minimal-app/cc13x4_26x4 + $ gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\"" + $ ninja -C out/debug + + ``` + + If you would like to define arguments on the command line you may add them + to the GN call. + + ``` + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + ``` + +## Programming + +Loading the built image onto a LaunchPad is supported through two methods; +Uniflash and Code Composer Studio (CCS). UniFlash can be used to load the image. +Code Composer Studio can be used to load the image and debug the source code. + +### Code Composer Studio + +Programming with CCS will allow for a full debug environment within the IDE. +This is accomplished by creating a target connection to the XDS110 debugger and +starting a project-less debug session. The CCS IDE will attempt to find the +source files on the local machine based on the debug information embedded within +the ELF. CCS may prompt you to find the source code if the image was built on +another machine or the source code is located in a different location than is +recorded within the ELF. + +Download and install [Code Composer Studio][ccs]. + +First open CCS and create a new workspace. + +Create a target connection (sometimes called the CCXML) for your target SoC and +debugger as described in the [Manual Method][ccs_manual_method] section of the +CCS User's Guide. + +Next initiate a project-less debug session as described in the [Manual +Launch][ccs_manual_launch] section of the CCS User's Guide. + +CCS should switch to the debug view described in the [After +Launch][ccs_after_launch] section of the User's Guide. The SoC core will likely +be disconnected and symbols will not be loaded. Connect to the core as described +in the [Debug View][ccs_debug_view] section of the User's Guide. Once the core +is connected, use the `Load` button on the toolbar to load the ELF image. + +Note that the default configuration of the CCXML uses 2-wire cJTAG instead of +the full 4-wire JTAG connection to match the default jumper configuration of the +LaunchPad. + +### UniFlash + +Uniflash is Texas Instrument's uniform programming tool for embedded processors. +This will allow you to erase, flash, and inspect the SoC without setting up a +debugging environment. + +Download and install [UniFlash][uniflash]. + +First open UniFlash. Debug probes connected to the computer will usually be +displayed under the Detected Devices due to the automatic device detection +feature. If your device does not show up in this view it my be disconnected, or +you may have to create a New Configuration. If you already have a CCXML for your +SoC and debug connection you can use that in the section at the bottom. Once +your device is selected, click the `Start` button within the section to launch +the session. + +Select the ELF image to load on the device with the `Browse` button. This file +is placed in the `out/debug` folder by this guide and ends with the `*.out` file +extension. For OTA enabled applications, the standalone image will instead end +with the `*-bim.hex` file extension. This this is a combined image with +application and and `BIM` included. The flag to enable or disable the OTA +feature is determined by "chip_enable_ota_requestor" in the application's +args.gni file. + +Finally click the `Load Image` button to load the executable image onto the +device. You should be able to see the log output over the XDS110 User UART. + +Note that programming the device through JTAG sets the Halt-in-Boot flag and may +cause issues when performing a software reset. This flag can be reset by +power-cycling the LaunchPad. + +## Running the Example + +By default the log output will be sent to the Application/User UART. Open a +terminal emulator to that port to see the output with the following options: + +| Parameter | Value | +| ------------ | -------- | +| Speed (baud) | `115200` | +| Data bits | `8` | +| Stop bits | `1` | +| Parity | `None` | +| Flow control | `None` | + +## Running the Example + +Once a device has been flashed with this example, it can now join and operate in +an existing Matter network. The following sections assume that a Matter network +is already active, and has at least one [OpenThread Border +Router][ot_border_router_setup]. + +For insight into what other components are needed to run this example, please +refer to our [Matter Getting Started Guide][matter-e2e-faq]. + +The steps below should be followed to commission the device onto the network and +control it once it has been commissioned. + +**Step 0** + +Set up the CHIP tool by following the instructions outlined in our [Matter +Getting Started Guide][matter-e2e-faq]. + +**Step 1** + +Commission the device onto the Matter network. Run the following command on the +CHIP tool: + +``` + +./chip-tool pairing ble-thread hex: 20202021 3840 + +``` + +Interacting with the application begins by enabling BLE advertisements and then +pairing the device into a Thread network. To provision this example onto a +Matter network, the device must be discoverable over Bluetooth LE. + +On the LaunchPad, press and hold the right button, labeled `BTN-2`, for more +than 1 second. Upon release, the Bluetooth LE advertising will begin. Once the +device is fully provisioned, BLE advertising will stop. + +Once the device has been successfully commissioned, you will see the following +message on the CHIP tool output: + +``` + +[1677648218.370754][39785:39790] CHIP:CTL: Received CommissioningComplete response, errorCode=0 +[1677648218.370821][39785:39790] CHIP:CTL: Successfully finished commissioning step 'SendComplete' + +``` + +An accompanying message will be seen from the device: + +``` + +Commissioning complete, notify platform driver to persist network credentials. + +``` + +**Step 2** + +Send commands to the all-cluster-app. Here are some example commands: + +Basic + +``` +./chip-tool basic read e.g. ./chip-tool basic read product-id 1 0 +``` + +Identify + +``` +./chip-tool identify identify e.g. ./chip-tool identify identify 100 1 1 +``` + +### Provisioning + +Interacting with the application begins by enabling BLE advertisements and then +pairing the device into a Thread network. + +#### Bluetooth LE Advertising + +To provision this example onto a Thread network, the device must be discoverable +over Bluetooth LE. BLE advertising is started by long pressing the right button +(greater than 1000ms), labeled `BTN-2` on the silkscreen. Once the device is +fully provisioned, BLE advertising will stop. + +#### Bluetooth LE Rendezvous + +Pairing this application with `ble-thread` can be done with any of the enabled +[CHIP Controller](../../../src/controller/README.md) applications. Use the +information printed on the console to aide in pairing the device. The controller +application can also be used to control the example app with the cluster +commands. + +## TI Support + +For technical support, please consider creating a post on TI's [E2E forum][e2e]. +Additionally, we welcome any feedback. + +[matter]: https://csa-iot.org/all-solutions/matter/ +[ccs]: https://www.ti.com/tool/CCSTUDIO +[ccs_after_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#after-launch +[ccs_debug_view]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#debug-view +[ccs_manual_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-launch +[ccs_manual_method]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-method +[e2e]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum +[matter-e2e-faq]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/1082428/faq-cc2652r7-matter----getting-started-guide +[sysconfig]: https://www.ti.com/tool/SYSCONFIG +[ti_thread_dnd]: + https://www.ti.com/wireless-connectivity/thread/design-development.html +[ot_border_router_setup]: https://openthread.io/guides/border-router/build +[uniflash]: https://www.ti.com/tool/download/UNIFLASH diff --git a/examples/all-clusters-app/cc13x4_26x4/args.gni b/examples/all-clusters-app/cc13x4_26x4/args.gni new file mode 100644 index 00000000000000..a524bf977b9a23 --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/args.gni @@ -0,0 +1,50 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/chip.gni") +import("${chip_root}/examples/platform/cc13x4_26x4/args.gni") + +ti_simplelink_sdk_target = get_label_info(":sdk", "label_no_toolchain") +ti_simplelink_sysconfig_target = + get_label_info(":sysconfig", "label_no_toolchain") + +ti_simplelink_board = "LP_EM_CC1354P10_6" + +# Size Optimizations +# use -Os instead of -Og, LWIP release build +optimize_debug_level = "s" +lwip_debug = false + +chip_enable_ota_requestor = false + +openthread_external_platform = "${chip_root}/third_party/openthread/platforms/cc13x4_26x4:libopenthread-cc13x4_cc26x4" + +# Disable CHIP Logging +#chip_progress_logging = false + +# Disable verbose logs for all-clusters app to save Flash +#chip_detail_logging = false +#chip_automation_logging = false + +# BLE options +chip_config_network_layer_ble = true + +# Disable lock tracking, since our FreeRTOS configuration does not set +# INCLUDE_xSemaphoreGetMutexHolder +chip_stack_lock_tracking = "none" + +matter_device_vid = "0xFFF1" +matter_device_pid = "0x8006" +matter_software_ver = "0x0001" +matter_software_ver_str = "1.0d1" diff --git a/examples/all-clusters-app/cc13x4_26x4/build_overrides b/examples/all-clusters-app/cc13x4_26x4/build_overrides new file mode 120000 index 00000000000000..e578e73312ebd1 --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/build_overrides @@ -0,0 +1 @@ +../../build_overrides \ No newline at end of file diff --git a/examples/all-clusters-app/cc13x4_26x4/chip.syscfg b/examples/all-clusters-app/cc13x4_26x4/chip.syscfg new file mode 100644 index 00000000000000..e9cb55c3e22f07 --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/chip.syscfg @@ -0,0 +1,242 @@ +/* + * + * Copyright (c) 2020 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. + */ + + +/* Modules */ +var AESCCM = scripting.addModule("/ti/drivers/AESCCM"); +var AESECB = scripting.addModule("/ti/drivers/AESECB"); +var Button = scripting.addModule("/ti/drivers/apps/Button"); +var LED = scripting.addModule("/ti/drivers/apps/LED"); +var NVS = scripting.addModule("/ti/drivers/NVS"); +var RF = scripting.addModule("/ti/drivers/RF"); +var RFDesign = scripting.addModule("ti/devices/radioconfig/rfdesign"); +var RFCustom = scripting.addModule("/ti/devices/radioconfig/custom"); +var TRNG = scripting.addModule("/ti/drivers/TRNG"); +var SHA2 = scripting.addModule("/ti/drivers/SHA2"); +var UART2 = scripting.addModule("/ti/drivers/UART2"); +var ble = scripting.addModule("/ti/ble5stack/ble"); +var dmm = scripting.addModule("/ti/dmm/dmm"); +var AESCTRDRBG = scripting.addModule("/ti/drivers/AESCTRDRBG"); +var ECDH = scripting.addModule("/ti/drivers/ECDH"); + +/* Instances */ +var AESCCM1 = AESCCM.addInstance(); +var AESECB1 = AESECB.addInstance(); +var AESECB2 = AESECB.addInstance(); +var Button1 = Button.addInstance(); +var Button2 = Button.addInstance(); +var NVS1 = NVS.addInstance(); +var NVS2 = NVS.addInstance(); +var SHA21 = SHA2.addInstance(); +var LED1 = LED.addInstance(); +var LED2 = LED.addInstance(); +var TRNG1 = TRNG.addInstance(); +var TRNG2 = TRNG.addInstance(); +var TRNG3 = TRNG.addInstance(); +var UART2 = UART2.addInstance(); +var AESCTRDRBG1 = AESCTRDRBG.addInstance(); +var ECDH1 = ECDH.addInstance(); + +AESCTRDRBG1.$name = "CONFIG_AESCTRDRBG_0"; + +AESCCM1.$name = "CONFIG_AESCCM0"; + +AESECB1.$name = "CONFIG_AESECB0"; +AESECB2.$name = "CONFIG_AESECB_1"; + +ECDH1.$name = "CONFIG_ECDH0"; + +/* Left Button */ +Button1.$name = "CONFIG_BTN_LEFT"; +Button1.$hardware = system.deviceData.board.components["BTN-1"]; +Button1.gpioPin.$name = "CONFIG_GPIO_BTN1"; +Button1.gpioPin.pull = "Pull Up"; +Button1.gpioPin.interruptTrigger = "Falling Edge"; + +/* Left Button */ +Button2.$name = "CONFIG_BTN_RIGHT"; +Button2.$hardware = system.deviceData.board.components["BTN-2"]; +Button2.gpioPin.$name = "CONFIG_GPIO_BTN2"; +Button2.gpioPin.pull = "Pull Up"; +Button2.gpioPin.interruptTrigger = "Falling Edge"; + +/* ======== CCFG ======== */ +var CCFG = scripting.addModule("/ti/devices/CCFG"); +const ccfgSettings = system.getScript("/ti/common/lprf_ccfg_settings.js").ccfgSettings; +for(var setting in ccfgSettings) +{ + CCFG[setting] = ccfgSettings[setting]; +} + +CCFG.enableCodeGeneration = true; + + +/* NVS */ +NVS1.$name = "CONFIG_NVSINTERNAL"; +NVS1.internalFlash.regionBase = 0xFB800; +NVS1.internalFlash.regionSize = 0x2800; + + +NVS2.$name = "CONFIG_NVSEXTERNAL"; +NVS2.nvsType = "External"; // NVS Region Type +NVS2.$hardware = system.deviceData.board.components.MX25R8035F; + +/* RF */ +/* if an antenna component exists, assign it to the rf instance */ +if (system.deviceData.board && system.deviceData.board.components.RF) { + RF.$hardware = system.deviceData.board.components.RF; +} + +const rfDesignSettings = system.getScript("/ti/common/lprf_rf_design_settings.js").rfDesignSettings; +for(var setting in rfDesignSettings) +{ + RFDesign[setting] = rfDesignSettings[setting]; +} + + + +/* Handling for RF frontend characterization */ +if(RFDesign.rfDesign.match(/LP_CC2652PSIP/)) +{ + RFCustom.ieee = ["ieee154p10"]; + var rfCodeExportConfig = RFCustom.radioConfigieee154p10.codeExportConfig +} +else +{ + RFCustom.ieee = ["ieee154"]; + var rfCodeExportConfig = RFCustom.radioConfigieee154.codeExportConfig +} + +var cmdList = [ + "cmdIeeeTx", + "cmdIeeeRx", + "cmdIeeeCsma", + "cmdIeeeEdScan", + "cmdIeeeRxAck", + "cmdTxTest" +]; + +rfCodeExportConfig.useConst = true; +rfCodeExportConfig.useMulti = true; +rfCodeExportConfig.symGenMethod = "Custom"; + +const deviceId = system.deviceData.deviceId; + +// Add high PA options if present +if(deviceId.match(/CC(265[12]R|2674R|1352R1|1354R)/)) +{ + cmdList.push("cmdRadioSetup"); + rfCodeExportConfig.cmdRadioSetup = "RF_cmdIeeeRadioSetup"; +} +else if(deviceId.match(/CC(265[12]P|2674P|1352P)/)) +{ + cmdList.push("cmdRadioSetupPa"); + rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; + rfCodeExportConfig.paExport = "combined"; +} +else if(deviceId.match(/CC(265[34]|1354)P/)) +{ + cmdList.push("cmdRadioSetupPa"); + rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; + // currently not characterized for high PA +} +else +{ + throw new Error("Could not match platform to any known platform types"); +} + +rfCodeExportConfig.cmdList_ieee_15_4 = cmdList; + +/* Red LED */ +LED1.$name = "CONFIG_LED_RED"; +LED1.$hardware = system.deviceData.board.components.LED_RED; +LED1.gpioPin.$name = "CONFIG_GPIO_RLED"; +LED1.gpioPin.mode = "Output"; +LED1.gpioPin.callbackFunction = ""; + +/* Green LED */ +LED2.$name = "CONFIG_LED_GREEN"; +LED2.$hardware = system.deviceData.board.components.LED_GREEN; +LED2.gpioPin.$name = "CONFIG_GPIO_GLED"; +LED2.gpioPin.mode = "Output"; +LED2.gpioPin.callbackFunction = ""; + +/* Debug UART */ +UART2.$hardware = system.deviceData.board.components.XDS110UART; +UART2.$name = "CONFIG_UART2_DEBUG"; + +/* TRNG */ +TRNG1.$name = "CONFIG_TRNG_0"; +TRNG2.$name = "CONFIG_TRNG_THREAD"; +TRNG3.$name = "CONFIG_TRNG_APP"; + +/* BLE */ +ble.addressMode = "ADDRMODE_RP_WITH_PUBLIC_ID"; +ble.maxConnNum = 1; +ble.numOfAdvSets = 1; +ble.lockProject = true; +ble.oneLibSizeOpt = true; +ble.maxPDUSize = 255; +ble.radioConfig.codeExportConfig.$name = "ti_devices_radioconfig_code_export_param1"; +ble.connUpdateParamsPeripheral.$name = "ti_ble5stack_general_ble_conn_update_params0"; +ble.connUpdateParamsPeripheral.reqMinConnInt = 30; +ble.connUpdateParamsPeripheral.reqMaxConnInt = 50; + +ble.advSet1.$name = "ti_ble5stack_broadcaster_advertisement_set0"; +ble.advSet1.advParam1.$name = "ti_ble5stack_broadcaster_advertisement_params0"; + +ble.rfDesign = "LP_EM_CC1354P10_6"; + +ble.thorPg = 2; +/* DMM */ +dmm.project = "ti_thread_thermostat_remote_display"; +dmm.stackRoles = ["blePeripheral","threadFTD"]; +dmm.lockStackRoles = true; +dmm.numApplicationStates = 10; +dmm.applicationState0 = "ANY"; +dmm.applicationState1 = "DMMPOLICY_BLE_IDLE"; +dmm.applicationState2 = "DMMPOLICY_BLE_ADV"; +dmm.applicationState3 = "DMMPOLICY_BLE_CONNECTING"; +dmm.applicationState4 = "DMMPOLICY_BLE_HIGH_BANDWIDTH"; +dmm.applicationState5 = "DMMPOLICY_BLE_CONNECTED"; +dmm.applicationState6 = "DMMPOLICY_BLE_OAD"; +dmm.applicationState7 = "DMMPOLICY_THREAD_IDLE"; +dmm.applicationState8 = "DMMPOLICY_THREAD_LINK_EST"; +dmm.applicationState9 = "DMMPOLICY_THREAD_DATA"; +dmm.policyArray.create(4); +dmm.policyArray[0].$name = "ti_dmm_policy_dmm_policy0"; +dmm.policyArray[0].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble0"; +dmm.policyArray[0].blePeripheral.applicationStates = ["applicationState6"]; +dmm.policyArray[0].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread0"; +dmm.policyArray[0].threadFTD.pause = "DMMPOLICY_PAUSED"; +dmm.policyArray[1].$name = "ti_dmm_policy_dmm_policy1"; +dmm.policyArray[1].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble1"; +dmm.policyArray[1].blePeripheral.applicationStates = ["applicationState3","applicationState4"]; +dmm.policyArray[1].blePeripheral.weight = 25; +dmm.policyArray[1].blePeripheral.appliedActivity = ["DMMPOLICY_APPLIED_ACTIVITY_BLE_CONNECTION"]; +dmm.policyArray[1].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread1"; +dmm.policyArray[2].$name = "ti_dmm_policy_dmm_policy2"; +dmm.policyArray[2].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble2"; +dmm.policyArray[2].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread2"; +dmm.policyArray[2].threadFTD.weight = 30; +dmm.policyArray[2].threadFTD.applicationStates = ["applicationState8"]; +dmm.policyArray[2].threadFTD.appliedActivity = ["DMMPOLICY_APPLIED_ACTIVITY_ALL"]; +dmm.policyArray[3].$name = "ti_dmm_policy_dmm_policy3"; +dmm.policyArray[3].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble3"; +dmm.policyArray[3].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread3"; +dmm.policyArray[3].threadFTD.weight = 1; diff --git a/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp b/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp new file mode 100644 index 00000000000000..b8fa3a21a4f9d8 --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp @@ -0,0 +1,402 @@ +/* + * + * Copyright (c) 2020 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 +#include + +#include "FreeRTOS.h" +#include "Globals.h" +#include +#include + +#include +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +#include +#include +#include +#include +#include +#endif +#include +#include + +#ifdef AUTO_PRINT_METRICS +#include +#endif +#include + +#include +#include + +/* syscfg */ +#include + +#define APP_TASK_STACK_SIZE (5000) +#define APP_TASK_PRIORITY 4 +#define APP_EVENT_QUEUE_SIZE 10 + +using namespace ::chip; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; + +static TaskHandle_t sAppTaskHandle; +static QueueHandle_t sAppEventQueue; + +static Button_Handle sAppLeftHandle; +static Button_Handle sAppRightHandle; +static DeviceInfoProviderImpl sExampleDeviceInfoProvider; + +AppTask AppTask::sAppTask; + +constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE; + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +static DefaultOTARequestor sRequestorCore; +static DefaultOTARequestorStorage sRequestorStorage; +static DefaultOTARequestorDriver sRequestorUser; +static BDXDownloader sDownloader; +static OTAImageProcessorImpl sImageProcessor; + +void InitializeOTARequestor(void) +{ + // Initialize and interconnect the Requestor and Image Processor objects + SetRequestorInstance(&sRequestorCore); + + sRequestorStorage.Init(Server::GetInstance().GetPersistentStorage()); + sRequestorCore.Init(Server::GetInstance(), sRequestorStorage, sRequestorUser, sDownloader); + sImageProcessor.SetOTADownloader(&sDownloader); + sDownloader.SetImageProcessorDelegate(&sImageProcessor); + sRequestorUser.Init(&sRequestorCore, &sImageProcessor); +} +#endif + +#ifdef AUTO_PRINT_METRICS +static void printMetrics(void) +{ + chip::DeviceLayer::ThreadMetrics *threadMetricsOut, *currThread; + uint64_t heapFree, heapUsed; + + DiagnosticDataProviderImpl::GetDefaultInstance().GetCurrentHeapUsed(heapUsed); + DiagnosticDataProviderImpl::GetDefaultInstance().GetCurrentHeapFree(heapFree); + DiagnosticDataProviderImpl::GetDefaultInstance().GetThreadMetrics(&threadMetricsOut); + + PLAT_LOG("Heap Metrics\n Heap Free: %d Heap Used: %d", (uint32_t) heapFree, (uint32_t) heapUsed); + + PLAT_LOG("Thread Metrics\n"); + + currThread = threadMetricsOut; + while (currThread) + { + PLAT_LOG("Task Name: %s ID: %d Stack Free Min: %d", currThread->name, (uint32_t) currThread->id, + (uint32_t) currThread->stackFreeMinimum); + + currThread = currThread->Next; + } + + DiagnosticDataProviderImpl::GetDefaultInstance().ReleaseThreadMetrics(threadMetricsOut); +} +#endif + +void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) +{ + switch (event->Type) + { + case DeviceEventType::kCHIPoBLEConnectionEstablished: + PLAT_LOG("CHIPoBLE connection established"); + break; + + case DeviceEventType::kCHIPoBLEConnectionClosed: + PLAT_LOG("CHIPoBLE disconnected"); + break; + + case DeviceEventType::kCommissioningComplete: + PLAT_LOG("Commissioning complete"); + break; + } + +#ifdef AUTO_PRINT_METRICS + printMetrics(); +#endif +} + +int AppTask::StartAppTask() +{ + int ret = 0; + + sAppEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent)); + if (sAppEventQueue == NULL) + { + PLAT_LOG("Failed to allocate app event queue"); + while (1) + ; + } + + // Start App task. + if (xTaskCreate(AppTaskMain, "APP", APP_TASK_STACK_SIZE / sizeof(StackType_t), NULL, APP_TASK_PRIORITY, &sAppTaskHandle) != + pdPASS) + { + PLAT_LOG("Failed to create app task"); + while (1) + ; + } + return ret; +} + +int AppTask::Init() +{ + LED_Params ledParams; + Button_Params buttonParams; + + cc13xx_26xxLogInit(); + + // Initialize LEDs + PLAT_LOG("Initialize LEDs"); + LED_init(); + + LED_Params_init(&ledParams); // default PWM LED + sAppRedHandle = LED_open(CONFIG_LED_RED, &ledParams); + LED_setOff(sAppRedHandle); + + LED_Params_init(&ledParams); // default PWM LED + sAppGreenHandle = LED_open(CONFIG_LED_GREEN, &ledParams); + LED_setOff(sAppGreenHandle); + + // Initialize buttons + PLAT_LOG("Initialize buttons"); + Button_init(); + + Button_Params_init(&buttonParams); + buttonParams.buttonEventMask = Button_EV_CLICKED | Button_EV_LONGCLICKED; + buttonParams.longPressDuration = 1000U; // ms + sAppLeftHandle = Button_open(CONFIG_BTN_LEFT, &buttonParams); + Button_setCallback(sAppLeftHandle, ButtonLeftEventHandler); + + Button_Params_init(&buttonParams); + buttonParams.buttonEventMask = Button_EV_CLICKED | Button_EV_LONGCLICKED; + buttonParams.longPressDuration = 1000U; // ms + sAppRightHandle = Button_open(CONFIG_BTN_RIGHT, &buttonParams); + Button_setCallback(sAppRightHandle, ButtonRightEventHandler); + + // Init Chip memory management before the stack + Platform::MemoryInit(); + + CHIP_ERROR ret = PlatformMgr().InitChipStack(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("PlatformMgr().InitChipStack() failed"); + while (1) + ; + } + + ret = ThreadStackMgr().InitThreadStack(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("ThreadStackMgr().InitThreadStack() failed"); + while (1) + ; + } + +#ifdef CONFIG_OPENTHREAD_MTD_SED + ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); +#elif CONFIG_OPENTHREAD_MTD + ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); +#else + ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); +#endif + + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("ConnectivityMgr().SetThreadDeviceType() failed"); + while (1) + ; + } + + ret = PlatformMgr().StartEventLoopTask(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("PlatformMgr().StartEventLoopTask() failed"); + while (1) + ; + } + + ret = ThreadStackMgrImpl().StartThreadTask(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("ThreadStackMgr().StartThreadTask() failed"); + while (1) + ; + } + + // Init ZCL Data Model and start server + PLAT_LOG("Initialize Server"); + static chip::CommonCaseDeviceServerInitParams initParams; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + + // Initialize info provider + sExampleDeviceInfoProvider.SetStorageDelegate(initParams.persistentStorageDelegate); + SetDeviceInfoProvider(&sExampleDeviceInfoProvider); + + chip::Server::GetInstance().Init(initParams); + + ConfigurationMgr().LogDeviceConfig(); + + // Initialize device attestation config +#ifdef CC13X4_26X4_ATTESTATION_CREDENTIALS + SetDeviceAttestationCredentialsProvider(CC13X4_26X4::GetCC13X4_26X4DacProvider()); +#else + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif + + // We only have network commissioning on endpoint 0. + emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false); + + // Register a function to receive events from the CHIP device layer. Note that calls to + // this function will happen on the CHIP event loop thread, not the app_main thread. + PlatformMgr().AddEventHandler(DeviceEventCallback, reinterpret_cast(nullptr)); + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + InitializeOTARequestor(); +#endif + // QR code will be used with CHIP Tool + PrintOnboardingCodes(RendezvousInformationFlags(RendezvousInformationFlag::kBLE)); + + return 0; +} + +void AppTask::AppTaskMain(void * pvParameter) +{ + AppEvent event; + + sAppTask.Init(); + + while (1) + { + /* Task pend until we have stuff to do */ + if (xQueueReceive(sAppEventQueue, &event, portMAX_DELAY) == pdTRUE) + { + sAppTask.DispatchEvent(&event); + } + } +} + +void AppTask::PostEvent(const AppEvent * aEvent) +{ + if (xQueueSend(sAppEventQueue, aEvent, 0) != pdPASS) + { + /* Failed to post the message */ + } +} + +void AppTask::ButtonLeftEventHandler(Button_Handle handle, Button_EventMask events) +{ + AppEvent event; + event.Type = AppEvent::kEventType_ButtonLeft; + + if (events & Button_EV_CLICKED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_Clicked; + } + else if (events & Button_EV_LONGCLICKED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_LongClicked; + } + // button callbacks are in ISR context + if (xQueueSendFromISR(sAppEventQueue, &event, NULL) != pdPASS) + { + /* Failed to post the message */ + } +} + +void AppTask::ButtonRightEventHandler(Button_Handle handle, Button_EventMask events) +{ + AppEvent event; + event.Type = AppEvent::kEventType_ButtonRight; + + if (events & Button_EV_CLICKED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_Clicked; + } + else if (events & Button_EV_LONGCLICKED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_LongClicked; + } + // button callbacks are in ISR context + if (xQueueSendFromISR(sAppEventQueue, &event, NULL) != pdPASS) + { + /* Failed to post the message */ + } +} + +void AppTask::DispatchEvent(AppEvent * aEvent) +{ + switch (aEvent->Type) + { + case AppEvent::kEventType_ButtonLeft: + if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) + { + } + else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) + { + chip::Server::GetInstance().ScheduleFactoryReset(); + } + break; + + case AppEvent::kEventType_ButtonRight: + if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) + { + } + else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) + { + // Enable BLE advertisements + if (!ConnectivityMgr().IsBLEAdvertisingEnabled()) + { + if (Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() == CHIP_NO_ERROR) + { + PLAT_LOG("Enabled BLE Advertisements"); + } + else + { + PLAT_LOG("OpenBasicCommissioningWindow() failed"); + } + } + else + { + // Disable BLE advertisements + ConnectivityMgr().SetBLEAdvertisingEnabled(false); + PLAT_LOG("Disabled BLE Advertisements"); + } + } + break; + + case AppEvent::kEventType_AppEvent: + if (NULL != aEvent->Handler) + { + aEvent->Handler(aEvent); + } + break; + + case AppEvent::kEventType_None: + default: + break; + } +} diff --git a/examples/all-clusters-app/cc13x4_26x4/main/ClusterManager.cpp b/examples/all-clusters-app/cc13x4_26x4/main/ClusterManager.cpp new file mode 100644 index 00000000000000..7e6173a5a5b6a1 --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/main/ClusterManager.cpp @@ -0,0 +1,176 @@ +/* + * + * 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 "ClusterManager.h" +#include "Globals.h" +#include +#include +#include +#include +#include + +#ifdef AUTO_PRINT_METRICS +#include +#endif + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::System; +using namespace ::chip::DeviceLayer; + +constexpr uint32_t kIdentifyTimerDelayMS = 250; +constexpr uint32_t kIdentifyTimerDelayPerSec = 4; +ClusterManager ClusterManager::sCluster; + +#define ENDPOINT_ID_0 (0) +#define ENDPOINT_ID_1 (1) +#define ENDPOINT_ID_2 (2) + +void OnIdentifyTriggerEffect(Identify * identify) +{ + switch (identify->mCurrentEffectIdentifier) + { + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: + PLAT_LOG("EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: + PLAT_LOG("EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: + PLAT_LOG("EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: + PLAT_LOG("EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); + break; + default: + PLAT_LOG("No identifier effect"); + break; + } + return; +} + +Identify gIdentify0 = { + chip::EndpointId{ 0 }, + [](Identify *) { PLAT_LOG("onIdentifyStart"); }, + [](Identify *) { PLAT_LOG("onIdentifyStop"); }, + EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, + OnIdentifyTriggerEffect, +}; + +Identify gIdentify1 = { + chip::EndpointId{ 1 }, + [](Identify *) { PLAT_LOG("onIdentifyStart"); }, + [](Identify *) { PLAT_LOG("onIdentifyStop"); }, + EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, + OnIdentifyTriggerEffect, +}; + +void ClusterManager::OnOnOffPostAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value) +{ + using namespace app::Clusters::OnOff::Attributes; + VerifyOrExit(attributeId == OnOff::Id, PLAT_LOG("Unhandled Attribute ID: '0x%04x", attributeId)); + VerifyOrExit(endpointId == ENDPOINT_ID_1 || endpointId == ENDPOINT_ID_2, + PLAT_LOG("Unexpected EndPoint ID: `0x%02x'", endpointId)); + + // At this point we can assume that value points to a bool value. + mEndpointOnOffState[endpointId - 1] = *value; + endpointId == ENDPOINT_ID_1 ? LED_write(sAppGreenHandle, *value) : LED_write(sAppRedHandle, *value); + +exit: + return; +} + +void ClusterManager::OnLevelControlAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value) +{ + using namespace app::Clusters::LevelControl::Attributes; + bool onOffState = mEndpointOnOffState[endpointId - 1]; + uint8_t brightness = onOffState ? *value : 0; + + VerifyOrExit(brightness > 0, PLAT_LOG("Brightness set to 0, ignoring")); + VerifyOrExit(attributeId == CurrentLevel::Id, PLAT_LOG("Unhandled Attribute ID: '0x%04x", attributeId)); + VerifyOrExit(endpointId == ENDPOINT_ID_1 || endpointId == ENDPOINT_ID_2, + PLAT_LOG("Unexpected EndPoint ID: `0x%02x'", endpointId)); + + if (brightness > LED_BRIGHTNESS_MAX) + { + brightness = LED_BRIGHTNESS_MAX; + } + + endpointId == ENDPOINT_ID_1 ? LED_setOn(sAppGreenHandle, brightness) : LED_setOn(sAppRedHandle, brightness); + +exit: + return; +} + +void ClusterManager::OnColorControlAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value) +{ + using namespace app::Clusters::ColorControl::Attributes; + + VerifyOrExit(attributeId == CurrentHue::Id || attributeId == CurrentSaturation::Id, + PLAT_LOG("Unhandled AttributeId ID: '0x%04x", attributeId)); + VerifyOrExit(endpointId == ENDPOINT_ID_1 || endpointId == ENDPOINT_ID_2, + PLAT_LOG("Unexpected EndPoint ID: `0x%02x'", endpointId)); + + if (endpointId == ENDPOINT_ID_1) + { + uint8_t hue, saturation; + if (attributeId == CurrentHue::Id) + { + hue = *value; + /* Read Current Saturation value when Attribute change callback for HUE Attribute */ + CurrentSaturation::Get(endpointId, &saturation); + } + else + { + saturation = *value; + /* Read Current Hue value when Attribute change callback for SATURATION Attribute */ + CurrentHue::Get(endpointId, &hue); + } + PLAT_LOG("Color Control triggered: Hue: %d Saturation: %d", hue, saturation); + } +exit: + return; +} + +void ClusterManager::OnIdentifyPostAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint16_t size, + uint8_t * value) +{ + if (attributeId == app::Clusters::Identify::Attributes::IdentifyTime::Id && size == 2) + { + uint16_t identifyTime; + memcpy(&identifyTime, value, size); + if (identifyTime) + { + // Currently we have no separate indicator LEDs on each endpoints. + // We are using LED1 for endpoint 0,1 and LED2 for endpoint 2 + if (endpointId == ENDPOINT_ID_2) + { + LED_startBlinking(sAppGreenHandle, kIdentifyTimerDelayMS, identifyTime * kIdentifyTimerDelayPerSec); + } + else + { + LED_startBlinking(sAppRedHandle, kIdentifyTimerDelayMS, identifyTime * kIdentifyTimerDelayPerSec); + } + } + else + { + bool onOffState; + endpointId == ENDPOINT_ID_0 ? onOffState = mEndpointOnOffState[0] : onOffState = mEndpointOnOffState[endpointId - 1]; + endpointId == ENDPOINT_ID_2 ? LED_write(sAppRedHandle, onOffState) : LED_write(sAppGreenHandle, onOffState); + } + } +} diff --git a/examples/all-clusters-app/cc13x4_26x4/main/Globals.cpp b/examples/all-clusters-app/cc13x4_26x4/main/Globals.cpp new file mode 100644 index 00000000000000..01a945e1a33d12 --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/main/Globals.cpp @@ -0,0 +1,22 @@ +/* + * + * 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 "Globals.h" + +LED_Handle sAppRedHandle; +LED_Handle sAppGreenHandle; diff --git a/examples/all-clusters-app/cc13x4_26x4/main/ZclCallbacks.cpp b/examples/all-clusters-app/cc13x4_26x4/main/ZclCallbacks.cpp new file mode 100644 index 00000000000000..09505504315cad --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/main/ZclCallbacks.cpp @@ -0,0 +1,82 @@ +/* + * + * 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. + */ + +/** + * @file + * This file implements the handler for data model messages. + */ + +#include "AppConfig.h" +#include "Globals.h" +#include + +#include "ClusterManager.h" + +#include +#include +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::app::Clusters; + +void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size, + uint8_t * value) +{ + EndpointId endpoint = attributePath.mEndpointId; + ClusterId clusterId = attributePath.mClusterId; + AttributeId attributeId = attributePath.mAttributeId; + PLAT_LOG("MatterPostAttributeChangeCallback - Cluster ID: " ChipLogFormatMEI + ", EndPoint ID: '0x%02x', Attribute ID: " ChipLogFormatMEI, + ChipLogValueMEI(clusterId), endpoint, ChipLogValueMEI(attributeId)); + + switch (clusterId) + { + case OnOff::Id: + ClusterMgr().OnOnOffPostAttributeChangeCallback(endpoint, attributeId, value); + break; + + case Identify::Id: + ClusterMgr().OnIdentifyPostAttributeChangeCallback(endpoint, attributeId, size, value); + break; + + case LevelControl::Id: + ClusterMgr().OnLevelControlAttributeChangeCallback(endpoint, attributeId, value); + break; + + case ColorControl::Id: + ClusterMgr().OnColorControlAttributeChangeCallback(endpoint, attributeId, value); + break; + default: + PLAT_LOG("Unhandled cluster ID: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); + break; + } +} +/** @brief OnOff Cluster Init + * + * This function is called when a specific cluster is initialized. It gives the + * application an opportunity to take care of cluster initialization procedures. + * It is called exactly once for each endpoint where cluster is present. + * + * @param endpoint Ver.: always + */ +void emberAfOnOffClusterInitCallback(EndpointId endpoint) +{ + // TODO: implement any additional Cluster Server init actions +} diff --git a/examples/all-clusters-app/cc13x4_26x4/main/include/AppConfig.h b/examples/all-clusters-app/cc13x4_26x4/main/include/AppConfig.h new file mode 100644 index 00000000000000..7f6ce19a384bdc --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/main/include/AppConfig.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef APP_CONFIG_H +#define APP_CONFIG_H + +#endif // APP_CONFIG_H diff --git a/examples/all-clusters-app/cc13x4_26x4/main/include/AppEvent.h b/examples/all-clusters-app/cc13x4_26x4/main/include/AppEvent.h new file mode 100644 index 00000000000000..1d1efd369495b6 --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/main/include/AppEvent.h @@ -0,0 +1,60 @@ +/* + * + * Copyright (c) 2021 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. + */ + +#ifndef APP_EVENT_H +#define APP_EVENT_H + +struct AppEvent; +typedef void (*EventHandler)(AppEvent *); + +struct AppEvent +{ + enum AppEventType + { + kEventType_None = 0, + kEventType_ButtonLeft, + kEventType_ButtonRight, + kEventType_AppEvent, + }; + + enum AppEventButtonType + { + kAppEventButtonType_None = 0, + kAppEventButtonType_Clicked, + kAppEventButtonType_LongClicked, + }; + + enum AppEventType Type; + + union + { + struct + { + enum AppEventButtonType Type; + } ButtonEvent; + + struct + { + void * Context; + } BoltLockEvent; + }; + + EventHandler Handler; +}; + +#endif // APP_EVENT_H diff --git a/examples/all-clusters-app/cc13x4_26x4/main/include/AppTask.h b/examples/all-clusters-app/cc13x4_26x4/main/include/AppTask.h new file mode 100644 index 00000000000000..002e1b3f70557c --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/main/include/AppTask.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APP_TASK_H +#define APP_TASK_H + +#include +#include + +#include "FreeRTOS.h" +#include "semphr.h" +#include "task.h" + +#include "AppEvent.h" + +#include + +class AppTask +{ +public: + int StartAppTask(); + static void AppTaskMain(void * pvParameter); + + void PostEvent(const AppEvent * event); + +private: + friend AppTask & GetAppTask(void); + + int Init(); + + void DispatchEvent(AppEvent * event); + + static void ButtonLeftEventHandler(Button_Handle handle, Button_EventMask events); + static void ButtonRightEventHandler(Button_Handle handle, Button_EventMask events); + static void TimerEventHandler(void * p_context); + + enum Function_t + { + kFunction_NoneSelected = 0, + kFunction_SoftwareUpdate = 0, + kFunction_FactoryReset, + + kFunction_Invalid + } Function; + + Function_t mFunction; + bool mFunctionTimerActive; + + static AppTask sAppTask; +}; + +inline AppTask & GetAppTask(void) +{ + return AppTask::sAppTask; +} + +#endif // APP_TASK_H diff --git a/examples/all-clusters-app/cc13x4_26x4/main/include/CHIPProjectConfig.h b/examples/all-clusters-app/cc13x4_26x4/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..939f01d93b8e6c --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/main/include/CHIPProjectConfig.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * 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. + * + */ + +#ifndef CHIP_PROJECT_CONFIG_H +#define CHIP_PROJECT_CONFIG_H + +#if BUILD_RELEASE // release build +// Note: Default Pairing/PIN/Serial Numbers being used. These should not be enabled for production builds +#endif // BUILD_RELEASE + +// 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 + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" + +/** + * CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER + * + * Enables the use of a hard-coded default serial number if none + * is found in CHIP NV storage. + */ +#define CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER "TEST_SN" + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 1 + +/** + * Values set by args.gni: + * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION + */ + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + * + * Enable support for CHIP-over-BLE (CHIPOBLE). + */ +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote CHIP Time service + * using the CHIP Time Sync protocol. + */ +// #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 + +/** + * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE + * + * A size, in bytes, of the individual debug event logging buffer. + */ +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) + +#define MATTER_CC13XX_26XX_PLATFORM_LOG_ENABLED 1 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + * + * Enable the OpenThread SRP client to allow for CHIP device discovery. + */ +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT 1 + +/** + * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE + * + * For a development build, set the default importance of events to be logged as Debug. + * Since debug is the lowest importance level, this means all standard, critical, info and + * debug importance level vi events get logged. + */ +#if BUILD_RELEASE +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production +#else +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug +#endif // BUILD_RELEASE + +#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 + +/** + * @def CHIP_IM_MAX_NUM_COMMAND_HANDLER + * + * @brief Defines the maximum number of CommandHandler, limits the number of active commands transactions on server. + */ +#define CHIP_IM_MAX_NUM_COMMAND_HANDLER 1 + +/** + * @def CHIP_IM_MAX_NUM_WRITE_HANDLER + * + * @brief Defines the maximum number of WriteHandler, limits the number of active write transactions on server. + */ +#define CHIP_IM_MAX_NUM_WRITE_HANDLER 1 + +// All clusters app has 3 group endpoints. This needs to defined here so that +// CHIP_CONFIG_MAX_GROUPS_PER_FABRIC is properly configured. +#define CHIP_CONFIG_MAX_GROUP_ENDPOINTS_PER_FABRIC 3 + +#endif // CHIP_PROJECT_CONFIG_H diff --git a/examples/all-clusters-app/cc13x4_26x4/main/include/ClusterManager.h b/examples/all-clusters-app/cc13x4_26x4/main/include/ClusterManager.h new file mode 100644 index 00000000000000..7a9a363980ca6f --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/main/include/ClusterManager.h @@ -0,0 +1,50 @@ +/* + * + * Copyright (c) 2021 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 ClusterManager.h + * + * Declarations for the ClusterManager callbacks for this application + * + **/ + +#pragma once + +#include +#include +#include + +class ClusterManager +{ +public: + void OnOnOffPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); + void OnLevelControlAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); + void OnColorControlAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); + void OnIdentifyPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint16_t size, + uint8_t * value); + +private: + friend ClusterManager & ClusterMgr(void); + bool mEndpointOnOffState[2]; + static ClusterManager sCluster; +}; + +inline ClusterManager & ClusterMgr(void) +{ + return ClusterManager::sCluster; +} diff --git a/examples/all-clusters-app/cc13x4_26x4/main/include/Globals.h b/examples/all-clusters-app/cc13x4_26x4/main/include/Globals.h new file mode 100644 index 00000000000000..4cdc0b69174d60 --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/main/include/Globals.h @@ -0,0 +1,35 @@ +/* + * + * Copyright (c) 2020 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 +// Logging +#ifdef __cplusplus +extern "C" { +#endif + +int cc13xx_26xxLogInit(void); +void cc13xx_26xxLog(const char * aFormat, ...); +#define PLAT_LOG(...) cc13xx_26xxLog(__VA_ARGS__); + +#ifdef __cplusplus +} +#endif +extern LED_Handle sAppRedHandle; +extern LED_Handle sAppGreenHandle; diff --git a/examples/all-clusters-app/cc13x4_26x4/main/include/OpenThreadConfig.h b/examples/all-clusters-app/cc13x4_26x4/main/include/OpenThreadConfig.h new file mode 100644 index 00000000000000..7d227258b1eaae --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/main/include/OpenThreadConfig.h @@ -0,0 +1,29 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * 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 + * Overrides to default OpenThread configuration. + * + */ + +#pragma once + +// Use the TI-supplied default platform configuration for remainder +#include "openthread-core-cc13x4_26x4-config.h" diff --git a/examples/all-clusters-app/cc13x4_26x4/main/main.cpp b/examples/all-clusters-app/cc13x4_26x4/main/main.cpp new file mode 100644 index 00000000000000..5a7f6a6b8df072 --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/main/main.cpp @@ -0,0 +1,104 @@ +/* + * + * Copyright (c) 2020 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. + */ + +#include +#include + +#include + +#include +#include + +#include + +/* Driver Header files */ +#include +#include +#include + +#include +#include +#include +#include + +#include +#define TOTAL_ICALL_HEAP_SIZE (0xd000) + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::DeviceLayer; + +__attribute__((section(".heap"))) uint8_t GlobalHeapZoneBuffer[TOTAL_ICALL_HEAP_SIZE]; +uint32_t heapSize = TOTAL_ICALL_HEAP_SIZE; + +// ================================================================================ +// FreeRTOS Callbacks +// ================================================================================ +extern "C" void vApplicationStackOverflowHook(void) +{ + while (1) + { + ; + } +} + +/* Wrapper functions for using the queue registry regardless of whether it is enabled or disabled */ +extern "C" void vQueueAddToRegistryWrapper(QueueHandle_t xQueue, const char * pcQueueName) +{ + /* This function is intentionally left empty as the Queue Registry is disabled */ +} + +extern "C" void vQueueUnregisterQueueWrapper(QueueHandle_t xQueue) +{ + /* This function is intentionally left empty as the Queue Registry is disabled */ +} + +// ================================================================================ +// Main Code +// ================================================================================ +int main(void) +{ + Board_init(); + bpool((void *) GlobalHeapZoneBuffer, TOTAL_ICALL_HEAP_SIZE); + + GPIO_init(); + + NVS_init(); + + ECDH_init(); + + ECDSA_init(); + + AESECB_init(); + + SHA2_init(); + + int ret = GetAppTask().StartAppTask(); + if (ret != 0) + { + // can't log until the kernel is started + // PLAT_LOG("GetAppTask().StartAppTask() failed"); + while (1) + ; + } + + vTaskStartScheduler(); + + // Should never get here. + while (1) + ; +} diff --git a/examples/all-clusters-app/cc13x4_26x4/third_party/connectedhomeip b/examples/all-clusters-app/cc13x4_26x4/third_party/connectedhomeip new file mode 120000 index 00000000000000..c866b86874994d --- /dev/null +++ b/examples/all-clusters-app/cc13x4_26x4/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../.. \ No newline at end of file diff --git a/examples/lighting-app/cc13x2x7_26x2x7/README.md b/examples/lighting-app/cc13x2x7_26x2x7/README.md new file mode 100644 index 00000000000000..a9eacd879f5070 --- /dev/null +++ b/examples/lighting-app/cc13x2x7_26x2x7/README.md @@ -0,0 +1,297 @@ +# Matter Lighting Example Application + +An example application showing the use of [Matter][matter] on the Texas +Instruments CC13XX_26XX family of Wireless MCUs. + +--- + +- [Matter Lighting Example Application](#matter-lighting-example-application) + - [Introduction](#introduction) + - [Device UI](#device-ui) + - [Building](#building) + - [Preparation](#preparation) + - [Compilation](#compilation) + - [Programming](#programming) + - [Code Composer Studio](#code-composer-studio) + - [UniFlash](#uniflash) + - [Viewing Logging Output](#viewing-logging-output) + - [Running the Example](#running-the-example) + - [TI Support](#ti-support) + +--- + +## Introduction + +The CC13XX_26XX lighting example application provides a working demonstration of +a connected light device. This uses the open-source Matter implementation and +the Texas Instruments SimpleLinkā„¢ CC13XX and CC26XX software development kit. + +This example is enabled to build for CC2652R7 devices. + +The lighting example is intended to serve both as a means to explore the +workings of Matter, as well as a template for creating real products based on +the Texas Instruments devices. + +## Device UI + +| Action | Functionality | +| ------------------------------------------------ | -------------------------------------- | +| Left Button (`BTN-1`) Press (less than 1000 ms) | Light is turned on | +| Left Button (`BTN-1`) Press (more than 1000 ms) | Factory Reset | +| Right Button (`BTN-2`) Press (less than 1000 ms) | Light is turned off | +| Right Button (`BTN-2`) Press (more than 1000 ms) | BLE Advertisement (Enable/Disable) | +| Red LED Solid On State | Light is turned on | +| Red LED Off State | Light is turned off | +| Green LED Blinking State | Identify Trigger Effect in progress | +| Green LED Off State | No Identify Trigger Effect in progress | + +## Building + +### Preparation + +Some initial setup is necessary for preparing the build environment. This +section will need to be done when migrating to new versions of the SDK. This +guide assumes that the environment is linux based, and recommends Ubuntu 20.04. + +- Download and install [SysConfig][sysconfig]. This can be done simply with + the following commands. + + ``` + $ cd ~ + $ `wget https://dr-download.ti.com/software-development/ide-configuration-compiler-or-debugger/MD-nsUM6f7Vvb/1.15.0.2826/sysconfig-1.15.0_2826-setup.run` + $ chmod +x sysconfig-1.15.0_2826-setup.run + $ ./sysconfig-1.15.0_2826-setup.run + ``` + +- Run the bootstrap script to setup the build environment. + + ``` + $ cd ~/connectedhomeip + $ source ./scripts/bootstrap.sh + + ``` + +### Compilation + +It is necessary to activate the environment in every new shell. Then run GN and +Ninja to build the executable. + +- Activate the build environment with the repository activate script. + + ``` + $ cd ~/connectedhomeip + $ source ./scripts/activate.sh + + ``` + +- Run the build to produce a default executable. By default on Linux both the + TI SimpleLink SDK and Sysconfig are located in a `ti` folder in the user's + home directory, and you must provide the absolute path to them. For example + `/home/username/ti/sysconfig_1.15.0`. On Windows the default directory is + `C:\ti`. Take note of this install path, as it will be used in the next + step. + + ``` + $ cd ~/connectedhomeip/examples/lock-app/cc13x2x7_26x2x7 + $ gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\"" + $ ninja -C out/debug + + ``` + + If you would like to define arguments on the command line you may add them + to the GN call. + + + ``` + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\"" + ``` + +## Programming + +Loading the built image onto a LaunchPad is supported through two methods; +Uniflash and Code Composer Studio (CCS). UniFlash can be used to load the image. +Code Composer Studio can be used to load the image and debug the source code. + +### Code Composer Studio + +Programming with CCS will allow for a full debug environment within the IDE. +This is accomplished by creating a target connection to the XDS110 debugger and +starting a project-less debug session. The CCS IDE will attempt to find the +source files on the local machine based on the debug information embedded within +the ELF. CCS may prompt you to find the source code if the image was built on +another machine or the source code is located in a different location than is +recorded within the ELF. + +Download and install [Code Composer Studio][ccs]. + +First open CCS and create a new workspace. + +Create a target connection (sometimes called the CCXML) for your target SoC and +debugger as described in the [Manual Method][ccs_manual_method] section of the +CCS User's Guide. + +Next initiate a project-less debug session as described in the [Manual +Launch][ccs_manual_launch] section of the CCS User's Guide. + +CCS should switch to the debug view described in the [After +Launch][ccs_after_launch] section of the User's Guide. The SoC core will likely +be disconnected and symbols will not be loaded. Connect to the core as described +in the [Debug View][ccs_debug_view] section of the User's Guide. Once the core +is connected, use the `Load` button on the toolbar to load the ELF image. + +Note that the default configuration of the CCXML uses 2-wire cJTAG instead of +the full 4-wire JTAG connection to match the default jumper configuration of the +LaunchPad. + +### UniFlash + +Uniflash is Texas Instrument's uniform programming tool for embedded processors. +This will allow you to erase, flash, and inspect the SoC without setting up a +debugging environment. + +Download and install [UniFlash][uniflash]. + +First open UniFlash. Debug probes connected to the computer will usually be +displayed under the Detected Devices due to the automatic device detection +feature. If your device does not show up in this view it my be disconnected, or +you may have to create a New Configuration. If you already have a CCXML for your +SoC and debug connection you can use that in the section at the bottom. Once +your device is selected, click the `Start` button within the section to launch +the session. + +Select the ELF image to load on the device with the `Browse` button. This file +is placed in the `out/debug` folder by this guide and ends with the `*.out` file +extension. For OTA enabled applications, the standalone image will instead end +with the `*-bim.hex` file extension. This this is a combined image with +application and and `BIM` included. The flag to enable or disable the OTA +feature is determined by "chip_enable_ota_requestor" in the application's +args.gni file. + +Finally click the `Load Image` button to load the executable image onto the +device. You should be able to see the log output over the XDS110 User UART. + +Note that programming the device through JTAG sets the Halt-in-Boot flag and may +cause issues when performing a software reset. This flag can be reset by +power-cycling the LaunchPad. + +## Viewing Logging Output + +By default the log output will be sent to the Application/User UART. Open a +terminal emulator to that port to see the output with the following options: + +| Parameter | Value | +| ------------ | -------- | +| Speed (baud) | `115200` | +| Data bits | `8` | +| Stop bits | `1` | +| Parity | `None` | +| Flow control | `None` | + +## Running the Example + +Once a device has been flashed with this example, it can now join and operate in +an existing Matter network. The following sections assume that a Matter network +is already active, and has at least one [OpenThread Border +Router][ot_border_router_setup]. + +For insight into what other components are needed to run this example, please +refer to our [Matter Getting Started Guide][matter-e2e-faq]. + +The steps below should be followed to commission the lighting device onto the +network and control it once it has been commissioned. + +**Step 0** + +Set up the CHIP tool by following the instructions outlined in our [Matter +Getting Started Guide][matter-e2e-faq]. + +**Step 1** + +Commission the light device onto the Matter network. Run the following command +on the CHIP tool: + +``` + +./chip-tool pairing ble-thread hex: 20202021 3840 + +``` + +Interacting with the application begins by enabling BLE advertisements and then +pairing the device into a Thread network. To provision this example onto a +Matter network, the device must be discoverable over Bluetooth LE. + +On the LaunchPad, press and hold the right button, labeled `BTN-2`, for more +than 1 second. Upon release, the Bluetooth LE advertising will begin. Once the +device is fully provisioned, BLE advertising will stop. + +Once the device has been successfully commissioned, you will see the following +message on the CHIP tool output: + +``` + +[1677648218.370754][39785:39790] CHIP:CTL: Received CommissioningComplete response, errorCode=0 +[1677648218.370821][39785:39790] CHIP:CTL: Successfully finished commissioning step 'SendComplete' + +``` + +An accompanying message will be seen from the device: + +``` + +Commissioning complete, notify platform driver to persist network credentials. + +``` + +**Step 2** + +Send commands to the lighting app. Here are some example commands: + +On + +``` +./chip-tool onoff on 1 +./chip-tool onoff toggee 1 (assuming the light is off) + +``` + +Off + +``` +./chip-tool onoff off 1 +./chip-tool onoff toggle 1 (assuming the light is on) + +``` + +Identify + +``` +./chip-tool identify identify 1 e.g. ./chip-tool identify identify 100 1 1 + +./chip-tool identify trigger-effect e.g. ./chip-tool identify trigger-effect 0x0000 0 1 1 + +``` + +## TI Support + +For technical support, please consider creating a post on TI's [E2E forum][e2e]. +Additionally, we welcome any feedback. + +[matter]: https://csa-iot.org/all-solutions/matter/ +[ccs]: https://www.ti.com/tool/CCSTUDIO +[ccs_after_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#after-launch +[ccs_debug_view]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#debug-view +[ccs_manual_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-launch +[ccs_manual_method]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-method +[e2e]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum +[matter-e2e-faq]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/1082428/faq-cc2652r7-matter----getting-started-guide +[sysconfig]: https://www.ti.com/tool/SYSCONFIG +[ti_thread_dnd]: + https://www.ti.com/wireless-connectivity/thread/design-development.html +[ot_border_router_setup]: https://openthread.io/guides/border-router/build +[uniflash]: https://www.ti.com/tool/download/UNIFLASH diff --git a/examples/lighting-app/cc13x4_26x4/.gn b/examples/lighting-app/cc13x4_26x4/.gn new file mode 100644 index 00000000000000..3d48789e30ab3d --- /dev/null +++ b/examples/lighting-app/cc13x4_26x4/.gn @@ -0,0 +1,28 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/build.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "freertos" + + import("//args.gni") +} diff --git a/examples/lighting-app/cc13x4_26x4/BUILD.gn b/examples/lighting-app/cc13x4_26x4/BUILD.gn new file mode 100644 index 00000000000000..e2f105d8f85fed --- /dev/null +++ b/examples/lighting-app/cc13x4_26x4/BUILD.gn @@ -0,0 +1,120 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/openthread.gni") +import("//build_overrides/ti_simplelink_sdk.gni") + +import("${build_root}/config/defaults.gni") + +import("${chip_root}/src/platform/device.gni") + +import("${ti_simplelink_sdk_build_root}/ti_simplelink_executable.gni") +import("${ti_simplelink_sdk_build_root}/ti_simplelink_sdk.gni") + +assert(current_os == "freertos") + +project_dir = "${chip_root}/examples/lighting-app/cc13x4_26x4" + +ti_simplelink_sdk("sdk") { + include_dirs = [ "${project_dir}/include" ] + public_configs = [ ":lighting_app_config" ] +} + +ti_sysconfig("sysconfig") { + sources = [ "${project_dir}/chip.syscfg" ] + + outputs = [ + "ti_radio_config.c", + "ti_radio_config.h", + "ti_drivers_config.c", + "ti_drivers_config.h", + "ti_ble_config.c", + "ti_ble_config.h", + "ti_dmm_application_policy.c", + "ti_dmm_application_policy.h", + "ti_devices_config.c", + "ti_devices_config.h", + + # disabled until upstream generation is aligned + #"tiop_config.h", + #"tiop_config.c", + + # not traditional source files + #"ti_utils_build_linker.cmd.genlibs", + #"syscfg_c.rov.xs", + #"ti_utils_runtime_model.gv", + #"ti_utils_runtime_Makefile", + #"ti_ble_app_config.opt", + #"ti_build_config.opt", + ] + + public_configs = [ ":sdk_dmm_config" ] + + cflags = [ + "-Wno-comment", + "@" + rebase_path("${target_gen_dir}/sysconfig/ti_ble_app_config.opt", + root_build_dir), + "@" + rebase_path("${target_gen_dir}/sysconfig/ti_build_config.opt", + root_build_dir), + ] +} + +ti_simplelink_executable("lighting_app") { + output_name = "chip-${ti_simplelink_board}-lighting-example.out" + + sources = [ + "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", + "${project_dir}/src/AppTask.cpp", + "${project_dir}/src/LightingManager.cpp", + "${project_dir}/src/ZclCallbacks.cpp", + "${project_dir}/src/main.cpp", + ] + + deps = [ + ":sdk", + ":sysconfig", + "${chip_root}/examples/lighting-app/lighting-common", + "${chip_root}/examples/platform/cc13x4_26x4:cc13x4_26x4-attestation-credentials", + "${chip_root}/src/lib", + ] + + if (chip_openthread_ftd) { + deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-ftd" ] + } else { + deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-mtd" ] + } + + include_dirs = [ + "${project_dir}", + "${chip_root}/examples/providers/", + ] + + cflags = [ + "-Wno-implicit-fallthrough", + "-Wno-sign-compare", + "-Wconversion", + ] + + output_dir = root_out_dir +} + +group("cc13x4_26x4") { + deps = [ ":lighting_app" ] +} + +group("default") { + deps = [ ":cc13x4_26x4" ] +} diff --git a/examples/lighting-app/cc13x4_26x4/README.md b/examples/lighting-app/cc13x4_26x4/README.md new file mode 100644 index 00000000000000..beb1bfc42507be --- /dev/null +++ b/examples/lighting-app/cc13x4_26x4/README.md @@ -0,0 +1,297 @@ +# Matter Lighting Example Application + +An example application showing the use of [Matter][matter] on the Texas +Instruments CC13XX_26XX family of Wireless MCUs. + +--- + +- [Matter Lighting Example Application](#matter-lighting-example-application) + - [Introduction](#introduction) + - [Device UI](#device-ui) + - [Building](#building) + - [Preparation](#preparation) + - [Compilation](#compilation) + - [Programming](#programming) + - [Code Composer Studio](#code-composer-studio) + - [UniFlash](#uniflash) + - [Viewing Logging Output](#viewing-logging-output) + - [Running the Example](#running-the-example) + - [TI Support](#ti-support) + +--- + +## Introduction + +The CC13XX_26XX lighting example application provides a working demonstration of +a connected light device. This uses the open-source Matter implementation and +the Texas Instruments SimpleLinkā„¢ CC13XX and CC26XX software development kit. + +This example is enabled to build for CC1354P10 devices. + +The lighting example is intended to serve both as a means to explore the +workings of Matter, as well as a template for creating real products based on +the Texas Instruments devices. + +## Device UI + +| Action | Functionality | +| ------------------------------------------------ | -------------------------------------- | +| Left Button (`BTN-1`) Press (less than 1000 ms) | Light is turned on | +| Left Button (`BTN-1`) Press (more than 1000 ms) | Factory Reset | +| Right Button (`BTN-2`) Press (less than 1000 ms) | Light is turned off | +| Right Button (`BTN-2`) Press (more than 1000 ms) | BLE Advertisement (Enable/Disable) | +| Red LED Solid On State | Light is turned on | +| Red LED Off State | Light is turned off | +| Green LED Blinking State | Identify Trigger Effect in progress | +| Green LED Off State | No Identify Trigger Effect in progress | + +## Building + +### Preparation + +Some initial setup is necessary for preparing the build environment. This +section will need to be done when migrating to new versions of the SDK. This +guide assumes that the environment is linux based, and recommends Ubuntu 20.04. + +- Download and install [SysConfig][sysconfig]. This can be done simply with + the following commands. + + ``` + $ cd ~ + $ `wget https://dr-download.ti.com/software-development/ide-configuration-compiler-or-debugger/MD-nsUM6f7Vvb/1.15.0.2826/sysconfig-1.15.0_2826-setup.run` + $ chmod +x sysconfig-1.15.0_2826-setup.run + $ ./sysconfig-1.15.0_2826-setup.run + ``` + +- Run the bootstrap script to setup the build environment. + + ``` + $ cd ~/connectedhomeip + $ source ./scripts/bootstrap.sh + + ``` + +### Compilation + +It is necessary to activate the environment in every new shell. Then run GN and +Ninja to build the executable. + +- Activate the build environment with the repository activate script. + + ``` + $ cd ~/connectedhomeip + $ source ./scripts/activate.sh + + ``` + +- Run the build to produce a default executable. By default on Linux both the + TI SimpleLink SDK and Sysconfig are located in a `ti` folder in the user's + home directory, and you must provide the absolute path to them. For example + `/home/username/ti/sysconfig_1.15.0`. On Windows the default directory is + `C:\ti`. Take note of this install path, as it will be used in the next + step. + + ``` + $ cd ~/connectedhomeip/examples/lock-app/cc13x4_26x4 + $ gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\"" + $ ninja -C out/debug + + ``` + + If you would like to define arguments on the command line you may add them + to the GN call. + + + ``` + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\"" + ``` + +## Programming + +Loading the built image onto a LaunchPad is supported through two methods; +Uniflash and Code Composer Studio (CCS). UniFlash can be used to load the image. +Code Composer Studio can be used to load the image and debug the source code. + +### Code Composer Studio + +Programming with CCS will allow for a full debug environment within the IDE. +This is accomplished by creating a target connection to the XDS110 debugger and +starting a project-less debug session. The CCS IDE will attempt to find the +source files on the local machine based on the debug information embedded within +the ELF. CCS may prompt you to find the source code if the image was built on +another machine or the source code is located in a different location than is +recorded within the ELF. + +Download and install [Code Composer Studio][ccs]. + +First open CCS and create a new workspace. + +Create a target connection (sometimes called the CCXML) for your target SoC and +debugger as described in the [Manual Method][ccs_manual_method] section of the +CCS User's Guide. + +Next initiate a project-less debug session as described in the [Manual +Launch][ccs_manual_launch] section of the CCS User's Guide. + +CCS should switch to the debug view described in the [After +Launch][ccs_after_launch] section of the User's Guide. The SoC core will likely +be disconnected and symbols will not be loaded. Connect to the core as described +in the [Debug View][ccs_debug_view] section of the User's Guide. Once the core +is connected, use the `Load` button on the toolbar to load the ELF image. + +Note that the default configuration of the CCXML uses 2-wire cJTAG instead of +the full 4-wire JTAG connection to match the default jumper configuration of the +LaunchPad. + +### UniFlash + +Uniflash is Texas Instrument's uniform programming tool for embedded processors. +This will allow you to erase, flash, and inspect the SoC without setting up a +debugging environment. + +Download and install [UniFlash][uniflash]. + +First open UniFlash. Debug probes connected to the computer will usually be +displayed under the Detected Devices due to the automatic device detection +feature. If your device does not show up in this view it my be disconnected, or +you may have to create a New Configuration. If you already have a CCXML for your +SoC and debug connection you can use that in the section at the bottom. Once +your device is selected, click the `Start` button within the section to launch +the session. + +Select the ELF image to load on the device with the `Browse` button. This file +is placed in the `out/debug` folder by this guide and ends with the `*.out` file +extension. For OTA enabled applications, the standalone image will instead end +with the `*-bim.hex` file extension. This this is a combined image with +application and and `BIM` included. The flag to enable or disable the OTA +feature is determined by "chip_enable_ota_requestor" in the application's +args.gni file. + +Finally click the `Load Image` button to load the executable image onto the +device. You should be able to see the log output over the XDS110 User UART. + +Note that programming the device through JTAG sets the Halt-in-Boot flag and may +cause issues when performing a software reset. This flag can be reset by +power-cycling the LaunchPad. + +## Viewing Logging Output + +By default the log output will be sent to the Application/User UART. Open a +terminal emulator to that port to see the output with the following options: + +| Parameter | Value | +| ------------ | -------- | +| Speed (baud) | `115200` | +| Data bits | `8` | +| Stop bits | `1` | +| Parity | `None` | +| Flow control | `None` | + +## Running the Example + +Once a device has been flashed with this example, it can now join and operate in +an existing Matter network. The following sections assume that a Matter network +is already active, and has at least one [OpenThread Border +Router][ot_border_router_setup]. + +For insight into what other components are needed to run this example, please +refer to our [Matter Getting Started Guide][matter-e2e-faq]. + +The steps below should be followed to commission the lighting device onto the +network and control it once it has been commissioned. + +**Step 0** + +Set up the CHIP tool by following the instructions outlined in our [Matter +Getting Started Guide][matter-e2e-faq]. + +**Step 1** + +Commission the light device onto the Matter network. Run the following command +on the CHIP tool: + +``` + +./chip-tool pairing ble-thread hex: 20202021 3840 + +``` + +Interacting with the application begins by enabling BLE advertisements and then +pairing the device into a Thread network. To provision this example onto a +Matter network, the device must be discoverable over Bluetooth LE. + +On the LaunchPad, press and hold the right button, labeled `BTN-2`, for more +than 1 second. Upon release, the Bluetooth LE advertising will begin. Once the +device is fully provisioned, BLE advertising will stop. + +Once the device has been successfully commissioned, you will see the following +message on the CHIP tool output: + +``` + +[1677648218.370754][39785:39790] CHIP:CTL: Received CommissioningComplete response, errorCode=0 +[1677648218.370821][39785:39790] CHIP:CTL: Successfully finished commissioning step 'SendComplete' + +``` + +An accompanying message will be seen from the device: + +``` + +Commissioning complete, notify platform driver to persist network credentials. + +``` + +**Step 2** + +Send commands to the lighting app. Here are some example commands: + +On + +``` +./chip-tool onoff on 1 +./chip-tool onoff toggee 1 (assuming the light is off) + +``` + +Off + +``` +./chip-tool onoff off 1 +./chip-tool onoff toggle 1 (assuming the light is on) + +``` + +Identify + +``` +./chip-tool identify identify 1 e.g. ./chip-tool identify identify 100 1 1 + +./chip-tool identify trigger-effect e.g. ./chip-tool identify trigger-effect 0x0000 0 1 1 + +``` + +## TI Support + +For technical support, please consider creating a post on TI's [E2E forum][e2e]. +Additionally, we welcome any feedback. + +[matter]: https://csa-iot.org/all-solutions/matter/ +[ccs]: https://www.ti.com/tool/CCSTUDIO +[ccs_after_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#after-launch +[ccs_debug_view]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#debug-view +[ccs_manual_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-launch +[ccs_manual_method]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-method +[e2e]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum +[matter-e2e-faq]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/1082428/faq-cc2652r7-matter----getting-started-guide +[sysconfig]: https://www.ti.com/tool/SYSCONFIG +[ti_thread_dnd]: + https://www.ti.com/wireless-connectivity/thread/design-development.html +[ot_border_router_setup]: https://openthread.io/guides/border-router/build +[uniflash]: https://www.ti.com/tool/download/UNIFLASH diff --git a/examples/lighting-app/cc13x4_26x4/args.gni b/examples/lighting-app/cc13x4_26x4/args.gni new file mode 100644 index 00000000000000..b3aabaa8d985ff --- /dev/null +++ b/examples/lighting-app/cc13x4_26x4/args.gni @@ -0,0 +1,50 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/chip.gni") +import("${chip_root}/config/standalone/args.gni") +import("${chip_root}/examples/platform/cc13x4_26x4/args.gni") + +ti_simplelink_sdk_target = get_label_info(":sdk", "label_no_toolchain") +ti_simplelink_sysconfig_target = + get_label_info(":sysconfig", "label_no_toolchain") + +ti_simplelink_board = "LP_EM_CC1354P10_6" + +# Size Optimizations +# use -Os instead of -Og, LWIP release build +optimize_debug_level = "s" +lwip_debug = false + +chip_enable_ota_requestor = false + +chip_openthread_ftd = true +openthread_external_platform = "${chip_root}/third_party/openthread/platforms/cc13x4_26x4:libopenthread-cc13x4_cc26x4" + +# Disable CHIP Logging +#chip_progress_logging = false +#chip_detail_logging = false +#chip_automation_logging = false + +# BLE options +chip_config_network_layer_ble = true + +# Disable lock tracking, since our FreeRTOS configuration does not set +# INCLUDE_xSemaphoreGetMutexHolder +chip_stack_lock_tracking = "none" + +matter_device_vid = "0xFFF1" +matter_device_pid = "0x8005" +matter_software_ver = "0x0001" +matter_software_ver_str = "1.0d1" diff --git a/examples/lighting-app/cc13x4_26x4/build_overrides b/examples/lighting-app/cc13x4_26x4/build_overrides new file mode 120000 index 00000000000000..e578e73312ebd1 --- /dev/null +++ b/examples/lighting-app/cc13x4_26x4/build_overrides @@ -0,0 +1 @@ +../../build_overrides \ No newline at end of file diff --git a/examples/lighting-app/cc13x4_26x4/chip.syscfg b/examples/lighting-app/cc13x4_26x4/chip.syscfg new file mode 100644 index 00000000000000..e9cb55c3e22f07 --- /dev/null +++ b/examples/lighting-app/cc13x4_26x4/chip.syscfg @@ -0,0 +1,242 @@ +/* + * + * Copyright (c) 2020 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. + */ + + +/* Modules */ +var AESCCM = scripting.addModule("/ti/drivers/AESCCM"); +var AESECB = scripting.addModule("/ti/drivers/AESECB"); +var Button = scripting.addModule("/ti/drivers/apps/Button"); +var LED = scripting.addModule("/ti/drivers/apps/LED"); +var NVS = scripting.addModule("/ti/drivers/NVS"); +var RF = scripting.addModule("/ti/drivers/RF"); +var RFDesign = scripting.addModule("ti/devices/radioconfig/rfdesign"); +var RFCustom = scripting.addModule("/ti/devices/radioconfig/custom"); +var TRNG = scripting.addModule("/ti/drivers/TRNG"); +var SHA2 = scripting.addModule("/ti/drivers/SHA2"); +var UART2 = scripting.addModule("/ti/drivers/UART2"); +var ble = scripting.addModule("/ti/ble5stack/ble"); +var dmm = scripting.addModule("/ti/dmm/dmm"); +var AESCTRDRBG = scripting.addModule("/ti/drivers/AESCTRDRBG"); +var ECDH = scripting.addModule("/ti/drivers/ECDH"); + +/* Instances */ +var AESCCM1 = AESCCM.addInstance(); +var AESECB1 = AESECB.addInstance(); +var AESECB2 = AESECB.addInstance(); +var Button1 = Button.addInstance(); +var Button2 = Button.addInstance(); +var NVS1 = NVS.addInstance(); +var NVS2 = NVS.addInstance(); +var SHA21 = SHA2.addInstance(); +var LED1 = LED.addInstance(); +var LED2 = LED.addInstance(); +var TRNG1 = TRNG.addInstance(); +var TRNG2 = TRNG.addInstance(); +var TRNG3 = TRNG.addInstance(); +var UART2 = UART2.addInstance(); +var AESCTRDRBG1 = AESCTRDRBG.addInstance(); +var ECDH1 = ECDH.addInstance(); + +AESCTRDRBG1.$name = "CONFIG_AESCTRDRBG_0"; + +AESCCM1.$name = "CONFIG_AESCCM0"; + +AESECB1.$name = "CONFIG_AESECB0"; +AESECB2.$name = "CONFIG_AESECB_1"; + +ECDH1.$name = "CONFIG_ECDH0"; + +/* Left Button */ +Button1.$name = "CONFIG_BTN_LEFT"; +Button1.$hardware = system.deviceData.board.components["BTN-1"]; +Button1.gpioPin.$name = "CONFIG_GPIO_BTN1"; +Button1.gpioPin.pull = "Pull Up"; +Button1.gpioPin.interruptTrigger = "Falling Edge"; + +/* Left Button */ +Button2.$name = "CONFIG_BTN_RIGHT"; +Button2.$hardware = system.deviceData.board.components["BTN-2"]; +Button2.gpioPin.$name = "CONFIG_GPIO_BTN2"; +Button2.gpioPin.pull = "Pull Up"; +Button2.gpioPin.interruptTrigger = "Falling Edge"; + +/* ======== CCFG ======== */ +var CCFG = scripting.addModule("/ti/devices/CCFG"); +const ccfgSettings = system.getScript("/ti/common/lprf_ccfg_settings.js").ccfgSettings; +for(var setting in ccfgSettings) +{ + CCFG[setting] = ccfgSettings[setting]; +} + +CCFG.enableCodeGeneration = true; + + +/* NVS */ +NVS1.$name = "CONFIG_NVSINTERNAL"; +NVS1.internalFlash.regionBase = 0xFB800; +NVS1.internalFlash.regionSize = 0x2800; + + +NVS2.$name = "CONFIG_NVSEXTERNAL"; +NVS2.nvsType = "External"; // NVS Region Type +NVS2.$hardware = system.deviceData.board.components.MX25R8035F; + +/* RF */ +/* if an antenna component exists, assign it to the rf instance */ +if (system.deviceData.board && system.deviceData.board.components.RF) { + RF.$hardware = system.deviceData.board.components.RF; +} + +const rfDesignSettings = system.getScript("/ti/common/lprf_rf_design_settings.js").rfDesignSettings; +for(var setting in rfDesignSettings) +{ + RFDesign[setting] = rfDesignSettings[setting]; +} + + + +/* Handling for RF frontend characterization */ +if(RFDesign.rfDesign.match(/LP_CC2652PSIP/)) +{ + RFCustom.ieee = ["ieee154p10"]; + var rfCodeExportConfig = RFCustom.radioConfigieee154p10.codeExportConfig +} +else +{ + RFCustom.ieee = ["ieee154"]; + var rfCodeExportConfig = RFCustom.radioConfigieee154.codeExportConfig +} + +var cmdList = [ + "cmdIeeeTx", + "cmdIeeeRx", + "cmdIeeeCsma", + "cmdIeeeEdScan", + "cmdIeeeRxAck", + "cmdTxTest" +]; + +rfCodeExportConfig.useConst = true; +rfCodeExportConfig.useMulti = true; +rfCodeExportConfig.symGenMethod = "Custom"; + +const deviceId = system.deviceData.deviceId; + +// Add high PA options if present +if(deviceId.match(/CC(265[12]R|2674R|1352R1|1354R)/)) +{ + cmdList.push("cmdRadioSetup"); + rfCodeExportConfig.cmdRadioSetup = "RF_cmdIeeeRadioSetup"; +} +else if(deviceId.match(/CC(265[12]P|2674P|1352P)/)) +{ + cmdList.push("cmdRadioSetupPa"); + rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; + rfCodeExportConfig.paExport = "combined"; +} +else if(deviceId.match(/CC(265[34]|1354)P/)) +{ + cmdList.push("cmdRadioSetupPa"); + rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; + // currently not characterized for high PA +} +else +{ + throw new Error("Could not match platform to any known platform types"); +} + +rfCodeExportConfig.cmdList_ieee_15_4 = cmdList; + +/* Red LED */ +LED1.$name = "CONFIG_LED_RED"; +LED1.$hardware = system.deviceData.board.components.LED_RED; +LED1.gpioPin.$name = "CONFIG_GPIO_RLED"; +LED1.gpioPin.mode = "Output"; +LED1.gpioPin.callbackFunction = ""; + +/* Green LED */ +LED2.$name = "CONFIG_LED_GREEN"; +LED2.$hardware = system.deviceData.board.components.LED_GREEN; +LED2.gpioPin.$name = "CONFIG_GPIO_GLED"; +LED2.gpioPin.mode = "Output"; +LED2.gpioPin.callbackFunction = ""; + +/* Debug UART */ +UART2.$hardware = system.deviceData.board.components.XDS110UART; +UART2.$name = "CONFIG_UART2_DEBUG"; + +/* TRNG */ +TRNG1.$name = "CONFIG_TRNG_0"; +TRNG2.$name = "CONFIG_TRNG_THREAD"; +TRNG3.$name = "CONFIG_TRNG_APP"; + +/* BLE */ +ble.addressMode = "ADDRMODE_RP_WITH_PUBLIC_ID"; +ble.maxConnNum = 1; +ble.numOfAdvSets = 1; +ble.lockProject = true; +ble.oneLibSizeOpt = true; +ble.maxPDUSize = 255; +ble.radioConfig.codeExportConfig.$name = "ti_devices_radioconfig_code_export_param1"; +ble.connUpdateParamsPeripheral.$name = "ti_ble5stack_general_ble_conn_update_params0"; +ble.connUpdateParamsPeripheral.reqMinConnInt = 30; +ble.connUpdateParamsPeripheral.reqMaxConnInt = 50; + +ble.advSet1.$name = "ti_ble5stack_broadcaster_advertisement_set0"; +ble.advSet1.advParam1.$name = "ti_ble5stack_broadcaster_advertisement_params0"; + +ble.rfDesign = "LP_EM_CC1354P10_6"; + +ble.thorPg = 2; +/* DMM */ +dmm.project = "ti_thread_thermostat_remote_display"; +dmm.stackRoles = ["blePeripheral","threadFTD"]; +dmm.lockStackRoles = true; +dmm.numApplicationStates = 10; +dmm.applicationState0 = "ANY"; +dmm.applicationState1 = "DMMPOLICY_BLE_IDLE"; +dmm.applicationState2 = "DMMPOLICY_BLE_ADV"; +dmm.applicationState3 = "DMMPOLICY_BLE_CONNECTING"; +dmm.applicationState4 = "DMMPOLICY_BLE_HIGH_BANDWIDTH"; +dmm.applicationState5 = "DMMPOLICY_BLE_CONNECTED"; +dmm.applicationState6 = "DMMPOLICY_BLE_OAD"; +dmm.applicationState7 = "DMMPOLICY_THREAD_IDLE"; +dmm.applicationState8 = "DMMPOLICY_THREAD_LINK_EST"; +dmm.applicationState9 = "DMMPOLICY_THREAD_DATA"; +dmm.policyArray.create(4); +dmm.policyArray[0].$name = "ti_dmm_policy_dmm_policy0"; +dmm.policyArray[0].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble0"; +dmm.policyArray[0].blePeripheral.applicationStates = ["applicationState6"]; +dmm.policyArray[0].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread0"; +dmm.policyArray[0].threadFTD.pause = "DMMPOLICY_PAUSED"; +dmm.policyArray[1].$name = "ti_dmm_policy_dmm_policy1"; +dmm.policyArray[1].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble1"; +dmm.policyArray[1].blePeripheral.applicationStates = ["applicationState3","applicationState4"]; +dmm.policyArray[1].blePeripheral.weight = 25; +dmm.policyArray[1].blePeripheral.appliedActivity = ["DMMPOLICY_APPLIED_ACTIVITY_BLE_CONNECTION"]; +dmm.policyArray[1].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread1"; +dmm.policyArray[2].$name = "ti_dmm_policy_dmm_policy2"; +dmm.policyArray[2].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble2"; +dmm.policyArray[2].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread2"; +dmm.policyArray[2].threadFTD.weight = 30; +dmm.policyArray[2].threadFTD.applicationStates = ["applicationState8"]; +dmm.policyArray[2].threadFTD.appliedActivity = ["DMMPOLICY_APPLIED_ACTIVITY_ALL"]; +dmm.policyArray[3].$name = "ti_dmm_policy_dmm_policy3"; +dmm.policyArray[3].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble3"; +dmm.policyArray[3].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread3"; +dmm.policyArray[3].threadFTD.weight = 1; diff --git a/examples/lighting-app/cc13x4_26x4/include/CHIPProjectConfig.h b/examples/lighting-app/cc13x4_26x4/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..0f5090d7d9f320 --- /dev/null +++ b/examples/lighting-app/cc13x4_26x4/include/CHIPProjectConfig.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * 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. + * + */ + +#ifndef CHIP_PROJECT_CONFIG_H +#define CHIP_PROJECT_CONFIG_H + +#if BUILD_RELEASE // release build +// Note: Default Pairing/PIN/Serial Numbers being used. These should not be enabled for production builds +#endif // BUILD_RELEASE + +// 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 + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" + +/** + * CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER + * + * Enables the use of a hard-coded default serial number if none + * is found in CHIP NV storage. + */ +#define CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER "TEST_SN" + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 1 +#endif + +/** + * Values set by args.gni: + * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION + */ + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + * + * Enable support for CHIP-over-BLE (CHIPOBLE). + */ +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 + +/** + * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE + * + * A size, in bytes, of the individual debug event logging buffer. + */ +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) + +#define MATTER_CC13XX_26XX_PLATFORM_LOG_ENABLED 1 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + * + * Enable the OpenThread SRP client to allow for CHIP device discovery. + */ +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT 1 + +/** + * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE + * + * For a development build, set the default importance of events to be logged as Debug. + * Since debug is the lowest importance level, this means all standard, critical, info and + * debug importance level vi events get logged. + */ +#if BUILD_RELEASE +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production +#else +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug +#endif // BUILD_RELEASE + +#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 + +/** + * @def CHIP_IM_MAX_NUM_COMMAND_HANDLER + * + * @brief Defines the maximum number of CommandHandler, limits the number of active commands transactions on server. + */ +#define CHIP_IM_MAX_NUM_COMMAND_HANDLER 2 + +/** + * @def CHIP_IM_MAX_NUM_WRITE_HANDLER + * + * @brief Defines the maximum number of WriteHandler, limits the number of active write transactions on server. + */ +#define CHIP_IM_MAX_NUM_WRITE_HANDLER 2 + +#endif // CHIP_PROJECT_CONFIG_H diff --git a/examples/lighting-app/cc13x4_26x4/src/AppConfig.h b/examples/lighting-app/cc13x4_26x4/src/AppConfig.h new file mode 100644 index 00000000000000..a818b21d641875 --- /dev/null +++ b/examples/lighting-app/cc13x4_26x4/src/AppConfig.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef APP_CONFIG_H +#define APP_CONFIG_H + +// Logging +#ifdef __cplusplus +extern "C" { +#endif + +int cc13xx_26xxLogInit(void); +void cc13xx_26xxLog(const char * aFormat, ...); +#define PLAT_LOG(...) cc13xx_26xxLog(__VA_ARGS__); + +#define ACTUATOR_MOVEMENT_PERIOD_MS 1000 + +#ifdef __cplusplus +} +#endif +#endif // APP_CONFIG_H diff --git a/examples/lighting-app/cc13x4_26x4/src/AppEvent.h b/examples/lighting-app/cc13x4_26x4/src/AppEvent.h new file mode 100644 index 00000000000000..b6138ec479949c --- /dev/null +++ b/examples/lighting-app/cc13x4_26x4/src/AppEvent.h @@ -0,0 +1,85 @@ +/* + * + * Copyright (c) 2021 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. + */ + +#ifndef APP_EVENT_H +#define APP_EVENT_H + +struct AppEvent; +typedef void (*EventHandler)(AppEvent *); + +struct AppEvent +{ + enum AppEventType + { + kEventType_None = 0, + kEventType_ButtonLeft, + kEventType_ButtonRight, + kEventType_AppEvent, + kEventType_IdentifyStart, + kEventType_IdentifyStop, + kEventType_Light, + kEventType_Timer, + }; + + enum AppEventButtonType + { + kAppEventButtonType_None = 0, + kAppEventButtonType_Clicked, + kAppEventButtonType_LongClicked, + }; + + enum AppEventIdentifyType + { + kAppEventIdentifyType_Blink = 0, + kAppEventIdentifyType_Breathe, + kAppEventIdentifyType_Okay, + kAppEventIdentifyType_Finish, + kAppEventIdentifyType_Stop, + }; + + enum AppEventType Type; + + union + { + struct + { + enum AppEventButtonType Type; + } ButtonEvent; + + struct + { + void * Context; + } TimerEvent; + + struct + { + uint8_t Action; + int32_t Actor; + void * Context; + } LightEvent; + + struct + { + enum AppEventIdentifyType Type; + } IdentifyEvent; + }; + + EventHandler Handler; +}; + +#endif // APP_EVENT_H diff --git a/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp b/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp new file mode 100644 index 00000000000000..d7b45b5b54e6bc --- /dev/null +++ b/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp @@ -0,0 +1,539 @@ +/* + * + * Copyright (c) 2020 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 "FreeRTOS.h" + +#include +#include +#include + +#include +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +#include +#include +#include +#include +#include +#endif + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +/* syscfg */ +#include + +#define APP_TASK_STACK_SIZE (4096) +#define APP_TASK_PRIORITY 4 +#define APP_EVENT_QUEUE_SIZE 10 + +#define IDENTIFY_TRIGGER_EFFECT_BLINK 0 +#define IDENTIFY_TRIGGER_EFFECT_BREATHE 1 +#define IDENTIFY_TRIGGER_EFFECT_OKAY 2 +#define IDENTIFY_TRIGGER_EFFECT_FINISH_STOP 3 + +static uint32_t identify_trigger_effect = IDENTIFY_TRIGGER_EFFECT_FINISH_STOP; + +#define LIGHTING_APPLICATION_IDENTIFY_ENDPOINT 1 + +using namespace ::chip; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; + +static TaskHandle_t sAppTaskHandle; +static QueueHandle_t sAppEventQueue; + +static LED_Handle sAppRedHandle; +static LED_Handle sAppGreenHandle; +static Button_Handle sAppLeftHandle; +static Button_Handle sAppRightHandle; +static DeviceInfoProviderImpl sExampleDeviceInfoProvider; + +AppTask AppTask::sAppTask; + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +static DefaultOTARequestor sRequestorCore; +static DefaultOTARequestorStorage sRequestorStorage; +static DefaultOTARequestorDriver sRequestorUser; +static BDXDownloader sDownloader; +static OTAImageProcessorImpl sImageProcessor; + +void InitializeOTARequestor(void) +{ + // Initialize and interconnect the Requestor and Image Processor objects + SetRequestorInstance(&sRequestorCore); + + sRequestorStorage.Init(Server::GetInstance().GetPersistentStorage()); + sRequestorCore.Init(Server::GetInstance(), sRequestorStorage, sRequestorUser, sDownloader); + sImageProcessor.SetOTADownloader(&sDownloader); + sDownloader.SetImageProcessorDelegate(&sImageProcessor); + sRequestorUser.Init(&sRequestorCore, &sImageProcessor); +} +#endif + +::Identify stIdentify = { LIGHTING_APPLICATION_IDENTIFY_ENDPOINT, AppTask::IdentifyStartHandler, AppTask::IdentifyStopHandler, + EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, AppTask::TriggerIdentifyEffectHandler }; + +int AppTask::StartAppTask() +{ + int ret = 0; + + sAppEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent)); + if (sAppEventQueue == NULL) + { + PLAT_LOG("Failed to allocate app event queue"); + while (1) + ; + } + + // Start App task. + if (xTaskCreate(AppTaskMain, "APP", APP_TASK_STACK_SIZE / sizeof(StackType_t), NULL, APP_TASK_PRIORITY, &sAppTaskHandle) != + pdPASS) + { + PLAT_LOG("Failed to create app task"); + while (1) + ; + } + return ret; +} + +// Action initiated callback +void uiTurnOn(void) +{ + PLAT_LOG("Light On initiated"); + LED_setOn(sAppRedHandle, LED_BRIGHTNESS_MAX); + LED_startBlinking(sAppRedHandle, 110 /* ms */, LED_BLINK_FOREVER); +} + +// Action completed callback +void uiTurnedOn(void) +{ + PLAT_LOG("Light On completed"); + LED_stopBlinking(sAppRedHandle); + LED_setOn(sAppRedHandle, LED_BRIGHTNESS_MAX); +} + +// Action initiated callback +void uiTurnOff(void) +{ + PLAT_LOG("Light Off initiated"); + LED_setOn(sAppRedHandle, LED_BRIGHTNESS_MAX); + LED_startBlinking(sAppRedHandle, 110 /* ms */, LED_BLINK_FOREVER); +} + +// Action completed callback +void uiTurnedOff(void) +{ + PLAT_LOG("Light Off completed"); + LED_stopBlinking(sAppRedHandle); + LED_setOff(sAppRedHandle); +} + +int AppTask::Init() +{ + LED_Params ledParams; + Button_Params buttonParams; + + cc13xx_26xxLogInit(); + + // Init Chip memory management before the stack + Platform::MemoryInit(); + + CHIP_ERROR ret = PlatformMgr().InitChipStack(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("PlatformMgr().InitChipStack() failed"); + while (1) + ; + } + + ret = ThreadStackMgr().InitThreadStack(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("ThreadStackMgr().InitThreadStack() failed"); + while (1) + ; + } +#if CHIP_DEVICE_CONFIG_THREAD_FTD + ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); +#else + ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); +#endif + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("ConnectivityMgr().SetThreadDeviceType() failed"); + while (1) + ; + } + + ret = PlatformMgr().StartEventLoopTask(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("PlatformMgr().StartEventLoopTask() failed"); + while (1) + ; + } + + ret = ThreadStackMgrImpl().StartThreadTask(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("ThreadStackMgr().StartThreadTask() failed"); + while (1) + ; + } + + // Init ZCL Data Model and start server + PLAT_LOG("Initialize Server"); + static CommonCaseDeviceServerInitParams initParams; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + + // Initialize info provider + sExampleDeviceInfoProvider.SetStorageDelegate(initParams.persistentStorageDelegate); + SetDeviceInfoProvider(&sExampleDeviceInfoProvider); + + Server::GetInstance().Init(initParams); + + // Initialize device attestation config +#ifdef CC13X4_26X4_ATTESTATION_CREDENTIALS + SetDeviceAttestationCredentialsProvider(CC13X4_26X4::GetCC13X4_26X4DacProvider()); +#else + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif + + // Initialize LEDs + PLAT_LOG("Initialize LEDs"); + LED_init(); + + LED_Params_init(&ledParams); // default PWM LED + sAppRedHandle = LED_open(CONFIG_LED_RED, &ledParams); + LED_setOff(sAppRedHandle); + + LED_Params_init(&ledParams); // default PWM LED + sAppGreenHandle = LED_open(CONFIG_LED_GREEN, &ledParams); + LED_setOff(sAppGreenHandle); + + // Initialize buttons + PLAT_LOG("Initialize buttons"); + Button_init(); + + Button_Params_init(&buttonParams); + buttonParams.buttonEventMask = Button_EV_CLICKED | Button_EV_LONGCLICKED; + buttonParams.longPressDuration = 1000U; // ms + sAppLeftHandle = Button_open(CONFIG_BTN_LEFT, &buttonParams); + Button_setCallback(sAppLeftHandle, ButtonLeftEventHandler); + + Button_Params_init(&buttonParams); + buttonParams.buttonEventMask = Button_EV_CLICKED | Button_EV_LONGCLICKED; + buttonParams.longPressDuration = 1000U; // ms + sAppRightHandle = Button_open(CONFIG_BTN_RIGHT, &buttonParams); + Button_setCallback(sAppRightHandle, ButtonRightEventHandler); + + ret = LightMgr().Init(); + + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("LightMgr().Init() failed"); + while (1) + ; + } + + LightMgr().SetCallbacks(ActionInitiated, ActionCompleted); + + ConfigurationMgr().LogDeviceConfig(); + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + InitializeOTARequestor(); +#endif + // QR code will be used with CHIP Tool + PrintOnboardingCodes(RendezvousInformationFlags(RendezvousInformationFlag::kBLE)); + + return 0; +} + +void AppTask::AppTaskMain(void * pvParameter) +{ + AppEvent event; + + sAppTask.Init(); + + while (1) + { + /* Task pend until we have stuff to do */ + if (xQueueReceive(sAppEventQueue, &event, portMAX_DELAY) == pdTRUE) + { + sAppTask.DispatchEvent(&event); + } + } +} + +void AppTask::ButtonLeftEventHandler(Button_Handle handle, Button_EventMask events) +{ + AppEvent event; + event.Type = AppEvent::kEventType_ButtonLeft; + + if (events & Button_EV_CLICKED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_Clicked; + } + else if (events & Button_EV_LONGCLICKED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_LongClicked; + } + // button callbacks are in ISR context + if (xQueueSendFromISR(sAppEventQueue, &event, NULL) != pdPASS) + { + /* Failed to post the message */ + } +} + +void AppTask::ButtonRightEventHandler(Button_Handle handle, Button_EventMask events) +{ + AppEvent event; + event.Type = AppEvent::kEventType_ButtonRight; + + if (events & Button_EV_CLICKED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_Clicked; + } + else if (events & Button_EV_LONGCLICKED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_LongClicked; + } + // button callbacks are in ISR context + if (xQueueSendFromISR(sAppEventQueue, &event, NULL) != pdPASS) + { + /* Failed to post the message */ + } +} + +void AppTask::ActionInitiated(LightingManager::Action_t aAction, int32_t aActor) +{ + if (aAction == LightingManager::ON_ACTION) + { + uiTurnOn(); + } + else if (aAction == LightingManager::OFF_ACTION) + { + uiTurnOff(); + } +} + +void AppTask::ActionCompleted(LightingManager::Action_t aAction) +{ + if (aAction == LightingManager::ON_ACTION) + { + uiTurnedOn(); + } + else if (aAction == LightingManager::OFF_ACTION) + { + uiTurnedOff(); + } +} + +void AppTask::PostEvent(const AppEvent * aEvent) +{ + if (sAppEventQueue != NULL) + { + BaseType_t status; + if (xPortIsInsideInterrupt()) + { + BaseType_t higherPrioTaskWoken = pdFALSE; + status = xQueueSendFromISR(sAppEventQueue, aEvent, &higherPrioTaskWoken); + +#ifdef portYIELD_FROM_ISR + portYIELD_FROM_ISR(higherPrioTaskWoken); +#elif portEND_SWITCHING_ISR // portYIELD_FROM_ISR or portEND_SWITCHING_ISR + portEND_SWITCHING_ISR(higherPrioTaskWoken); +#else // portYIELD_FROM_ISR or portEND_SWITCHING_ISR +#error "Must have portYIELD_FROM_ISR or portEND_SWITCHING_ISR" +#endif // portYIELD_FROM_ISR or portEND_SWITCHING_ISR + } + else + { + status = xQueueSend(sAppEventQueue, aEvent, 1); + } + + if (status != pdTRUE) + { + PLAT_LOG("Failed to post event to app task event queue"); + } + } + else + { + PLAT_LOG("Event Queue is NULL should never happen"); + } +} + +void AppTask::DispatchEvent(AppEvent * aEvent) +{ + int32_t actor; + + switch (aEvent->Type) + { + case AppEvent::kEventType_Light: { + actor = aEvent->LightEvent.Actor; + LightMgr().IsLightOn() ? LightMgr().InitiateAction(actor, LightingManager::OFF_ACTION) + : LightMgr().InitiateAction(actor, LightingManager::ON_ACTION); + } + case AppEvent::kEventType_ButtonLeft: + if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) + { + actor = AppEvent::kEventType_ButtonLeft; + LightMgr().InitiateAction(actor, LightingManager::ON_ACTION); + } + else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) + { + chip::Server::GetInstance().ScheduleFactoryReset(); + } + break; + + case AppEvent::kEventType_ButtonRight: + if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) + { + actor = AppEvent::kEventType_ButtonRight; + LightMgr().InitiateAction(actor, LightingManager::OFF_ACTION); + } + else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) + { + // Enable BLE advertisements + if (!ConnectivityMgr().IsBLEAdvertisingEnabled()) + { + if (Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() == CHIP_NO_ERROR) + { + PLAT_LOG("Enabled BLE Advertisements"); + } + else + { + PLAT_LOG("OpenBasicCommissioningWindow() failed"); + } + } + else + { + // Disable BLE advertisements + ConnectivityMgr().SetBLEAdvertisingEnabled(false); + PLAT_LOG("Disabled BLE Advertisements"); + } + } + break; + + case AppEvent::kEventType_IdentifyStart: + switch (identify_trigger_effect) + { + case IDENTIFY_TRIGGER_EFFECT_BLINK: + LED_setOn(sAppGreenHandle, LED_BRIGHTNESS_MAX); + LED_startBlinking(sAppGreenHandle, 1000, LED_BLINK_FOREVER); + break; + case IDENTIFY_TRIGGER_EFFECT_BREATHE: + LED_setOn(sAppGreenHandle, LED_BRIGHTNESS_MAX); + LED_startBlinking(sAppGreenHandle, 100, LED_BLINK_FOREVER); + break; + case IDENTIFY_TRIGGER_EFFECT_OKAY: + LED_setOn(sAppGreenHandle, LED_BRIGHTNESS_MAX); + LED_startBlinking(sAppGreenHandle, 500, LED_BLINK_FOREVER); + break; + default: + break; + } + PLAT_LOG("Identify started"); + break; + + case AppEvent::kEventType_IdentifyStop: + LED_stopBlinking(sAppGreenHandle); + LED_setOff(sAppGreenHandle); + PLAT_LOG("Identify stopped"); + break; + + case AppEvent::kEventType_AppEvent: + if (NULL != aEvent->Handler) + { + aEvent->Handler(aEvent); + } + break; + + case AppEvent::kEventType_None: + default: + break; + } +} + +void AppTask::IdentifyStartHandler(::Identify *) +{ + AppEvent event; + event.Type = AppEvent::kEventType_IdentifyStart; + sAppTask.PostEvent(&event); +} + +void AppTask::IdentifyStopHandler(::Identify *) +{ + AppEvent event; + event.Type = AppEvent::kEventType_IdentifyStop; + sAppTask.PostEvent(&event); +} + +void AppTask::TriggerIdentifyEffectHandler(::Identify * identify) +{ + switch (identify->mCurrentEffectIdentifier) + { + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: + PLAT_LOG("Starting blink identifier effect"); + identify_trigger_effect = IDENTIFY_TRIGGER_EFFECT_BLINK; + IdentifyStartHandler(identify); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: + PLAT_LOG("Starting breathe identifier effect"); + identify_trigger_effect = IDENTIFY_TRIGGER_EFFECT_BREATHE; + IdentifyStartHandler(identify); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: + PLAT_LOG("Starting okay identifier effect"); + identify_trigger_effect = IDENTIFY_TRIGGER_EFFECT_OKAY; + IdentifyStartHandler(identify); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: + PLAT_LOG("Channel Change identifier effect not implemented"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: + PLAT_LOG("Finish identifier effect"); + identify_trigger_effect = IDENTIFY_TRIGGER_EFFECT_FINISH_STOP; + IdentifyStopHandler(identify); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: + PLAT_LOG("Stop identifier effect"); + identify_trigger_effect = IDENTIFY_TRIGGER_EFFECT_FINISH_STOP; + IdentifyStopHandler(identify); + break; + default: + PLAT_LOG("No identifier effect"); + } +} diff --git a/examples/lighting-app/cc13x4_26x4/src/AppTask.h b/examples/lighting-app/cc13x4_26x4/src/AppTask.h new file mode 100644 index 00000000000000..3d305601bc12f7 --- /dev/null +++ b/examples/lighting-app/cc13x4_26x4/src/AppTask.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * 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 +#include + +#include "FreeRTOS.h" +#include "semphr.h" +#include "task.h" + +#include "AppEvent.h" +#include "LightingManager.h" + +#include + +// Application-defined error codes in the CHIP_ERROR space. +#define APP_ERROR_EVENT_QUEUE_FAILED CHIP_APPLICATION_ERROR(0x01) +#define APP_ERROR_CREATE_TASK_FAILED CHIP_APPLICATION_ERROR(0x02) +#define APP_ERROR_UNHANDLED_EVENT CHIP_APPLICATION_ERROR(0x03) +#define APP_ERROR_CREATE_TIMER_FAILED CHIP_APPLICATION_ERROR(0x04) +#define APP_ERROR_START_TIMER_FAILED CHIP_APPLICATION_ERROR(0x05) +#define APP_ERROR_STOP_TIMER_FAILED CHIP_APPLICATION_ERROR(0x06) +#define APP_ERROR_ALLOCATION_FAILED CHIP_APPLICATION_ERROR(0x07) +struct Identify; + +class AppTask +{ + +public: + int StartAppTask(); + static void AppTaskMain(void * pvParameter); + + static AppTask & GetAppTask() { return sAppTask; } + + void PostLightActionRequest(int32_t aActor, LightingManager::Action_t aAction); + void PostEvent(const AppEvent * event); + + static void IdentifyStartHandler(::Identify *); + static void IdentifyStopHandler(::Identify *); + static void TriggerIdentifyEffectHandler(::Identify * identify); + +private: + friend AppTask & GetAppTask(void); + + int Init(); + + static void ActionInitiated(LightingManager::Action_t aAction, int32_t aActor); + static void ActionCompleted(LightingManager::Action_t aAction); + + void DispatchEvent(AppEvent * event); + static void UpdateClusterState(intptr_t context); + static void SingleButtonEventHandler(AppEvent * aEvent); + static void ButtonTimerEventHandler(AppEvent * aEvent); + + static void ButtonLeftEventHandler(Button_Handle handle, Button_EventMask events); + static void ButtonRightEventHandler(Button_Handle handle, Button_EventMask events); + static void TimerEventHandler(void * p_context); + + enum Function_t + { + kFunction_NoneSelected = 0, + kFunction_SoftwareUpdate = 0, + kFunction_FactoryReset, + kFunction_Invalid + } Function; + + Function_t mFunction; + bool mFunctionTimerActive; + + static AppTask sAppTask; +}; + +inline AppTask & GetAppTask(void) +{ + return AppTask::sAppTask; +} diff --git a/examples/lighting-app/cc13x4_26x4/src/LightingManager.cpp b/examples/lighting-app/cc13x4_26x4/src/LightingManager.cpp new file mode 100644 index 00000000000000..ed5fc52e7e5638 --- /dev/null +++ b/examples/lighting-app/cc13x4_26x4/src/LightingManager.cpp @@ -0,0 +1,176 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * 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 "LightingManager.h" + +#include "AppConfig.h" +#include "AppTask.h" +#include + +using namespace chip; +using namespace ::chip::DeviceLayer; + +LightingManager LightingManager::sLight; + +TimerHandle_t sLightTimer; + +CHIP_ERROR LightingManager::Init() +{ + // Create FreeRTOS sw timer for light timer. + sLightTimer = xTimerCreate("lightTmr", // Just a text name, not used by the RTOS kernel + 1, // == default timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = light obj context + TimerEventHandler // timer callback handler + ); + + if (sLightTimer == NULL) + { + PLAT_LOG("sLightTimer timer create failed"); + } + + bool currentLedState; + // read current on/off value on endpoint one. + OnOffServer::Instance().getOnOffValue(1, ¤tLedState); + + mState = currentLedState ? kState_OnCompleted : kState_OffCompleted; + + return CHIP_NO_ERROR; +} + +void LightingManager::SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB) +{ + mActionInitiated_CB = aActionInitiated_CB; + mActionCompleted_CB = aActionCompleted_CB; +} + +bool LightingManager::IsActionInProgress() +{ + return (mState == kState_OffInitiated || mState == kState_OnInitiated); +} + +bool LightingManager::IsLightOn() +{ + return (mState == kState_OnCompleted); +} + +bool LightingManager::InitiateAction(int32_t aActor, Action_t aAction) +{ + bool action_initiated = false; + State_t new_state; + + // Initiate Turn On/Off Action only when the previous one is complete. + if (mState == kState_OffCompleted && aAction == ON_ACTION) + { + action_initiated = true; + + new_state = kState_OnInitiated; + } + else if (mState == kState_OnCompleted && aAction == OFF_ACTION) + { + action_initiated = true; + + new_state = kState_OffInitiated; + } + + if (action_initiated) + { + StartTimer(ACTUATOR_MOVEMENT_PERIOD_MS); + + // Since the timer started successfully, update the state and trigger callback + mState = new_state; + + if (mActionInitiated_CB) + { + mActionInitiated_CB(aAction, aActor); + } + } + + return action_initiated; +} + +void LightingManager::StartTimer(uint32_t aTimeoutMs) +{ + if (xTimerIsTimerActive(sLightTimer)) + { + PLAT_LOG("app timer already started!"); + CancelTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sLightTimer, pdMS_TO_TICKS(aTimeoutMs), 100) != pdPASS) + { + PLAT_LOG("sLightTimer timer start() failed"); + } +} + +void LightingManager::CancelTimer(void) +{ + if (xTimerStop(sLightTimer, 0) == pdFAIL) + { + PLAT_LOG("sLightTimer stop() failed"); + } +} + +void LightingManager::TimerEventHandler(TimerHandle_t xTimer) +{ + // Get light obj context from timer id. + LightingManager * light = static_cast(pvTimerGetTimerID(xTimer)); + + // The timer event handler will be called in the context of the timer task + // once sLightTimer expires. Post an event to apptask queue with the actual handler + // so that the event can be handled in the context of the apptask. + AppEvent event; + event.Type = AppEvent::kEventType_AppEvent; + event.LightEvent.Context = light; + + event.Handler = ActuatorMovementTimerEventHandler; + + AppTask::GetAppTask().PostEvent(&event); +} + +void LightingManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent) +{ + Action_t actionCompleted = INVALID_ACTION; + + LightingManager * light = static_cast(aEvent->LightEvent.Context); + + if (light->mState == kState_OffInitiated) + { + light->mState = kState_OffCompleted; + actionCompleted = OFF_ACTION; + OnOffServer::Instance().setOnOffValue(1, 0, false); + } + else if (light->mState == kState_OnInitiated) + { + light->mState = kState_OnCompleted; + actionCompleted = ON_ACTION; + OnOffServer::Instance().setOnOffValue(1, 1, false); + } + + if (actionCompleted != INVALID_ACTION) + { + if (light->mActionCompleted_CB) + { + light->mActionCompleted_CB(actionCompleted); + } + } +} diff --git a/examples/lighting-app/cc13x4_26x4/src/LightingManager.h b/examples/lighting-app/cc13x4_26x4/src/LightingManager.h new file mode 100644 index 00000000000000..818feed45ee87a --- /dev/null +++ b/examples/lighting-app/cc13x4_26x4/src/LightingManager.h @@ -0,0 +1,82 @@ +/* + * + * Copyright (c) 2019 Google LLC. + * 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 +#include + +#include "AppEvent.h" + +#include "FreeRTOS.h" +#include "timers.h" // provides FreeRTOS timer support +#include + +#include + +class LightingManager +{ +public: + enum Action_t + { + ON_ACTION = 0, + OFF_ACTION, + + INVALID_ACTION + } Action; + + enum State_t + { + kState_OffInitiated = 0, + kState_OffCompleted, + kState_OnInitiated, + kState_OnCompleted, + } State; + + CHIP_ERROR Init(); + bool IsLightOn(); + bool IsActionInProgress(); + bool InitiateAction(int32_t aActor, Action_t aAction); + + typedef void (*Callback_fn_initiated)(Action_t, int32_t aActor); + typedef void (*Callback_fn_completed)(Action_t); + void SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB); + + static void OnTriggerOffWithEffect(OnOffEffect * effect); + +private: + friend LightingManager & LightMgr(void); + State_t mState; + + Callback_fn_initiated mActionInitiated_CB; + Callback_fn_completed mActionCompleted_CB; + + void CancelTimer(void); + void StartTimer(uint32_t aTimeoutMs); + + static void TimerEventHandler(TimerHandle_t xTimer); + static void ActuatorMovementTimerEventHandler(AppEvent * aEvent); + static void OffEffectTimerEventHandler(AppEvent * aEvent); + + static LightingManager sLight; +}; + +inline LightingManager & LightMgr(void) +{ + return LightingManager::sLight; +} diff --git a/examples/lighting-app/cc13x4_26x4/src/ZclCallbacks.cpp b/examples/lighting-app/cc13x4_26x4/src/ZclCallbacks.cpp new file mode 100644 index 00000000000000..7bb20a45944545 --- /dev/null +++ b/examples/lighting-app/cc13x4_26x4/src/ZclCallbacks.cpp @@ -0,0 +1,75 @@ +/* + * + * Copyright (c) 2020 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. + */ + +/** + * @file + * This file implements the handler for data model messages. + */ + +#include "AppConfig.h" +#include "LightingManager.h" + +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::app::Clusters; + +void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size, + uint8_t * value) +{ + ClusterId clusterId = attributePath.mClusterId; + AttributeId attributeId = attributePath.mAttributeId; + ChipLogProgress(Zcl, "Cluster callback: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); + + if (clusterId == OnOff::Id && attributeId == OnOff::Attributes::OnOff::Id) + { + LightMgr().InitiateAction(AppEvent::kEventType_Light, *value ? LightingManager::ON_ACTION : LightingManager::OFF_ACTION); + } + else if (clusterId == Identify::Id) + { + ChipLogProgress(Zcl, "Identify attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u", + ChipLogValueMEI(attributeId), type, *value, size); + } + else if (clusterId == Groups::Id) + { + ChipLogProgress(Zcl, "Groups attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u", + ChipLogValueMEI(attributeId), type, *value, size); + } +} + +/** @brief OnOff Cluster Init + * + * This function is called when a specific cluster is initialized. It gives the + * application an opportunity to take care of cluster initialization procedures. + * It is called exactly once for each endpoint where cluster is present. + * + * @param endpoint Ver.: always + * + * TODO Issue #3841 + * emberAfOnOffClusterInitCallback happens before the stack initialize the cluster + * attributes to the default value. + * The logic here expects something similar to the deprecated Plugins callback + * emberAfPluginOnOffClusterServerPostInitCallback. + * + */ +void emberAfOnOffClusterInitCallback(EndpointId endpoint) +{ + // TODO: implement any additional Cluster Server init actions +} diff --git a/examples/lighting-app/cc13x4_26x4/src/main.cpp b/examples/lighting-app/cc13x4_26x4/src/main.cpp new file mode 100644 index 00000000000000..6cf27cf79a35fb --- /dev/null +++ b/examples/lighting-app/cc13x4_26x4/src/main.cpp @@ -0,0 +1,104 @@ +/* + * + * Copyright (c) 2020 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. + */ + +#include +#include + +#include + +#include "AppConfig.h" +#include "AppTask.h" + +#include + +/* Driver Header files */ +#include +#include +#include + +#include +#include +#include +#include + +#include +#define TOTAL_ICALL_HEAP_SIZE (0xc600) + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::DeviceLayer; + +__attribute__((section(".heap"))) uint8_t GlobalHeapZoneBuffer[TOTAL_ICALL_HEAP_SIZE]; +uint32_t heapSize = TOTAL_ICALL_HEAP_SIZE; + +// ================================================================================ +// FreeRTOS Callbacks +// ================================================================================ +extern "C" void vApplicationStackOverflowHook(void) +{ + while (1) + { + ; + } +} + +/* Wrapper functions for using the queue registry regardless of whether it is enabled or disabled */ +extern "C" void vQueueAddToRegistryWrapper(QueueHandle_t xQueue, const char * pcQueueName) +{ + /* This function is intentionally left empty as the Queue Registry is disabled */ +} + +extern "C" void vQueueUnregisterQueueWrapper(QueueHandle_t xQueue) +{ + /* This function is intentionally left empty as the Queue Registry is disabled */ +} + +// ================================================================================ +// Main Code +// ================================================================================ +int main(void) +{ + Board_init(); + bpool((void *) GlobalHeapZoneBuffer, TOTAL_ICALL_HEAP_SIZE); + + GPIO_init(); + + NVS_init(); + + ECDH_init(); + + ECDSA_init(); + + AESECB_init(); + + SHA2_init(); + + int ret = GetAppTask().StartAppTask(); + if (ret != 0) + { + // can't log until the kernel is started + // PLAT_LOG("GetAppTask().StartAppTask() failed"); + while (1) + ; + } + + vTaskStartScheduler(); + + // Should never get here. + while (1) + ; +} diff --git a/examples/lighting-app/cc13x4_26x4/third_party/connectedhomeip b/examples/lighting-app/cc13x4_26x4/third_party/connectedhomeip new file mode 120000 index 00000000000000..c866b86874994d --- /dev/null +++ b/examples/lighting-app/cc13x4_26x4/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../.. \ No newline at end of file diff --git a/examples/lock-app/cc13x2x7_26x2x7/README.md b/examples/lock-app/cc13x2x7_26x2x7/README.md index 541bffe7c000c6..01e2f1a189d839 100644 --- a/examples/lock-app/cc13x2x7_26x2x7/README.md +++ b/examples/lock-app/cc13x2x7_26x2x7/README.md @@ -1,11 +1,11 @@ -# Matter CC1352 CC2652 Lock Example Application +# Matter Lock Example Application An example application showing the use of [Matter][matter] on the Texas Instruments CC13XX_26XX family of Wireless MCUs. --- -- [Matter CC1352 CC2652 Lock Example Application](#matter-cc1352-cc2652-lock-example-application) +- [Matter Lock Example Application](#matter-lock-example-application) - [Introduction](#introduction) - [Device UI](#device-ui) - [Building](#building) @@ -14,7 +14,6 @@ Instruments CC13XX_26XX family of Wireless MCUs. - [Programming](#programming) - [Code Composer Studio](#code-composer-studio) - [UniFlash](#uniflash) - - [Viewing Logging Output](#viewing-logging-output) - [Running the Example](#running-the-example) - [Provisioning](#provisioning) - [Bluetooth LE Advertising](#bluetooth-le-advertising) @@ -25,8 +24,6 @@ Instruments CC13XX_26XX family of Wireless MCUs. ## Introduction -![CC1352R1_LAUNCHXL](../../pump-app/cc13x2x7_26x2x7/doc/images/cc1352r1_launchxl.jpg) - The CC13XX_26XX lock example application provides a working demonstration of a connected door lock device. This uses the open-source Matter implementation and the Texas Instruments SimpleLinkā„¢ CC13XX and CC26XX software development kit. @@ -39,19 +36,15 @@ Instruments devices. ## Device UI -This example application has a simple User Interface to depict the state of the -door lock and to control the state. The user LEDs on the LaunchPad are set on -when the lock is locked, and are set off when unlocked. The LEDs will flash when -in the transition state between locked and unlocked. - -Short presses (less than 1000ms) of the user buttons are used for requesting -lock and unlock of the door lock. The left button (`BTN-1`) is used to request -locking. The right button (`BTN-2`) is used to request unlocking. - -Long presses (greater than 1000ms) of the user buttons are used for controlling -BLE advertisements and resets. The left button (`BTN-1`) is used to perform a -factory reset of the device. The Right button (`BTN-2`) is used to disable BLE -advertisements (if enabled) or enable advertisements (if disabled). +| Action | Functionality | +| ------------------------------------------------ | ---------------------------------------- | +| Left Button (`BTN-1`) Press (less than 1000 ms) | Change state to unlocked | +| Right Button (`BTN-2`) Press (less than 1000 ms) | Change state to locked | +| Left Button (`BTN-1`) Press (more than 1000 ms) | Factory Reset | +| Right Button (`BTN-2`) Press (more than 1000 ms) | BLE Advertisement (Enable/Disable) | +| Red & Green LED Blinking State | Lock state transition to locked/unlocked | +| Red LED On State | Lock state locked | +| Red & Green LED Off State | Lock state unlocked | ## Building @@ -61,15 +54,14 @@ Some initial setup is necessary for preparing the build environment. This section will need to be done when migrating to new versions of the SDK. This guide assumes that the environment is linux based, and recommends Ubuntu 20.04. -- Download and install [SysConfig][sysconfig] ([recommended - version][sysconfig_recommended]). This can be done simply with the following - commands. +- Download and install [SysConfig][sysconfig]. This can be done simply with + the following commands. ``` $ cd ~ - $ wget https://software-dl.ti.com/ccs/esd/sysconfig/sysconfig-1.11.0_2225-setup.run - $ chmod +x sysconfig-1.11.0_2225-setup.run - $ ./sysconfig-1.11.0_2225-setup.run + $ `wget https://dr-download.ti.com/software-development/ide-configuration-compiler-or-debugger/MD-nsUM6f7Vvb/1.15.0.2826/sysconfig-1.15.0_2826-setup.run` + $ chmod +x sysconfig-1.15.0_2826-setup.run + $ ./sysconfig-1.15.0_2826-setup.run ``` - Run the bootstrap script to setup the build environment. @@ -96,17 +88,27 @@ Ninja to build the executable. - Run the build to produce a default executable. By default on Linux both the TI SimpleLink SDK and Sysconfig are located in a `ti` folder in the user's home directory, and you must provide the absolute path to them. For example - `/home/username/ti/sysconfig_1.11.0`. On Windows the default directory is + `/home/username/ti/sysconfig_1.15.0`. On Windows the default directory is `C:\ti`. Take note of this install path, as it will be used in the next step. ``` $ cd ~/connectedhomeip/examples/lock-app/cc13x2x7_26x2x7 - $ gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.11.0\"" + OR + $ cd ~/connectedhomeip/examples/lock-app/cc13x4_26x4 + $ gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\"" $ ninja -C out/debug ``` + If you would like to define arguments on the command line you may add them + to the GN call. + + + ``` + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\" target_defines=[\"CC13X2_26X2_ATTESTATION_CREDENTIALS=1\"]" + ``` + ## Programming Loading the built image onto a LaunchPad is supported through two methods; @@ -162,7 +164,11 @@ the session. Select the ELF image to load on the device with the `Browse` button. This file is placed in the `out/debug` folder by this guide and ends with the `*.out` file -extension. +extension. For OTA enabled applications, the standalone image will instead end +with the `*-bim.hex` file extension. This this is a combined image with +application and and `BIM` included. The flag to enable or disable the OTA +feature is determined by "chip_enable_ota_requestor" in the application's +args.gni file. Finally click the `Load Image` button to load the executable image onto the device. You should be able to see the log output over the XDS110 User UART. @@ -171,7 +177,7 @@ Note that programming the device through JTAG sets the Halt-in-Boot flag and may cause issues when performing a software reset. This flag can be reset by power-cycling the LaunchPad. -## Viewing Logging Output +## Running the Example By default the log output will be sent to the Application/User UART. Open a terminal emulator to that port to see the output with the following options: @@ -187,13 +193,93 @@ terminal emulator to that port to see the output with the following options: ## Running the Example Once a device has been flashed with this example, it can now join and operate in -an existing Thread network. The following sections assume that a Thread network +an existing Matter network. The following sections assume that a Matter network is already active, and has at least one [OpenThread Border Router][ot_border_router_setup]. For insight into what other components are needed to run this example, please refer to our [Matter Getting Started Guide][matter-e2e-faq]. +The steps below should be followed to commission the device onto the network and +control it once it has been commissioned. + +**Step 0** + +Set up the CHIP tool by following the instructions outlined in our [Matter +Getting Started Guide][matter-e2e-faq]. + +**Step 1** + +Commission the device onto the Matter network. Run the following command on the +CHIP tool: + +``` + +./chip-tool pairing ble-thread hex: 20202021 3840 + +``` + +Interacting with the application begins by enabling BLE advertisements and then +pairing the device into a Thread network. To provision this example onto a +Matter network, the device must be discoverable over Bluetooth LE. + +On the LaunchPad, press and hold the right button, labeled `BTN-2`, for more +than 1 second. Upon release, the Bluetooth LE advertising will begin. Once the +device is fully provisioned, BLE advertising will stop. + +Once the device has been successfully commissioned, you will see the following +message on the CHIP tool output: + +``` + +[1677648218.370754][39785:39790] CHIP:CTL: Received CommissioningComplete response, errorCode=0 +[1677648218.370821][39785:39790] CHIP:CTL: Successfully finished commissioning step 'SendComplete' + +``` + +An accompanying message will be seen from the device: + +``` + +Commissioning complete, notify platform driver to persist network credentials. + +``` + +**Step 2** The example Doorlock cluster operations have the following format: + +``` +./chip-tool doorlock +./chip-tool doorlock set-user +./chip-tool +``` + +Send commands to the lock-app. Here are some example commands: + +Set a new user "`TST`" with user index of 1 with a default pin of 123456 + +``` +./chip-tool doorlock set-user 0 1 `TST` 6452 1 0 0 1 1 --timedInteractionTimeoutMs 1000 +./chip-tool doorlock set-credential 0 '{ "credentialType" : 1 , "credentialIndex" : 1 }' 123456 1 null null 1 1 --timedInteractionTimeoutMs 1000 +``` + +Require a pin mode for lock operations: + +``` +./chip-tool doorlock write require-pinfor-remote-operation 1 1 1 +``` + +Lock the Door + +``` +./chip-tool doorlock lock-door 1 1 --timedInteractionTimeoutMs 1000 --PinCode 123456 +``` + +Unlock the door + +``` +./chip-tool doorlock unlock-door 1 1 --timedInteractionTimeoutMs 1000 --PinCode 123456 +``` + ### Provisioning Interacting with the application begins by enabling BLE advertisements and then @@ -219,7 +305,7 @@ commands. For technical support, please consider creating a post on TI's [E2E forum][e2e]. Additionally, we welcome any feedback. -[matter]: https://github.com/project-chip/connectedhomeip +[matter]: https://csa-iot.org/all-solutions/matter/ [ccs]: https://www.ti.com/tool/CCSTUDIO [ccs_after_launch]: https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#after-launch @@ -229,13 +315,11 @@ Additionally, we welcome any feedback. https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-launch [ccs_manual_method]: https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-method -[cc1352r1_launchxl]: https://www.ti.com/tool/LAUNCHXL-CC1352R1 -[e2e]: https://e2e.ti.com/support/wireless-connectivity/zigbee-and-thread +[e2e]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum [matter-e2e-faq]: https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/1082428/faq-cc2652r7-matter----getting-started-guide [sysconfig]: https://www.ti.com/tool/SYSCONFIG -[sysconfig_recommended]: - https://software-dl.ti.com/ccs/esd/sysconfig/sysconfig-1.11.0_2225-setup.run [ti_thread_dnd]: https://www.ti.com/wireless-connectivity/thread/design-development.html [ot_border_router_setup]: https://openthread.io/guides/border-router/build diff --git a/examples/lock-app/cc13x2x7_26x2x7/chip.syscfg b/examples/lock-app/cc13x2x7_26x2x7/chip.syscfg index 47cd09c1a31165..995ad22af6b435 100644 --- a/examples/lock-app/cc13x2x7_26x2x7/chip.syscfg +++ b/examples/lock-app/cc13x2x7_26x2x7/chip.syscfg @@ -26,11 +26,10 @@ var LED = scripting.addModule("/ti/drivers/apps/LED"); var NVS = scripting.addModule("/ti/drivers/NVS"); var RF = scripting.addModule("/ti/drivers/RF"); var RFDesign = scripting.addModule("ti/devices/radioconfig/rfdesign"); -var RTOS = scripting.addModule("/ti/drivers/RTOS"); +var RFCustom = scripting.addModule("/ti/devices/radioconfig/custom"); var TRNG = scripting.addModule("/ti/drivers/TRNG"); -var Thread = scripting.addModule("/ti/thread/thread"); var SHA2 = scripting.addModule("/ti/drivers/SHA2"); -var UART = scripting.addModule("/ti/drivers/UART"); +var UART2 = scripting.addModule("/ti/drivers/UART2"); var ble = scripting.addModule("/ti/ble5stack/ble"); var dmm = scripting.addModule("/ti/dmm/dmm"); var AESCTRDRBG = scripting.addModule("/ti/drivers/AESCTRDRBG"); @@ -50,12 +49,11 @@ var LED2 = LED.addInstance(); var TRNG1 = TRNG.addInstance(); var TRNG2 = TRNG.addInstance(); var TRNG3 = TRNG.addInstance(); -var UART1 = UART.addInstance(); +var UART2 = UART2.addInstance(); var AESCTRDRBG1 = AESCTRDRBG.addInstance(); var ECDH1 = ECDH.addInstance(); AESCTRDRBG1.$name = "CONFIG_AESCTRDRBG_0"; -AESCTRDRBG1.aesctrObject.$name = "CONFIG_AESCTR_0"; AESCCM1.$name = "CONFIG_AESCCM0"; @@ -64,9 +62,6 @@ AESECB2.$name = "CONFIG_AESECB_1"; ECDH1.$name = "CONFIG_ECDH0"; -/* RTOS */ -RTOS.name = "FreeRTOS"; - /* Left Button */ Button1.$name = "CONFIG_BTN_LEFT"; Button1.$hardware = system.deviceData.board.components["BTN-1"]; @@ -113,6 +108,58 @@ for(var setting in rfDesignSettings) RFDesign[setting] = rfDesignSettings[setting]; } +/* Handling for RF frontend characterization */ +if(RFDesign.rfDesign.match(/LP_CC2652PSIP/)) +{ + RFCustom.ieee = ["ieee154p10"]; + var rfCodeExportConfig = RFCustom.radioConfigieee154p10.codeExportConfig +} +else +{ + RFCustom.ieee = ["ieee154"]; + var rfCodeExportConfig = RFCustom.radioConfigieee154.codeExportConfig +} + +var cmdList = [ + "cmdIeeeTx", + "cmdIeeeRx", + "cmdIeeeCsma", + "cmdIeeeEdScan", + "cmdIeeeRxAck", + "cmdTxTest" +]; + +rfCodeExportConfig.useConst = true; +rfCodeExportConfig.useMulti = true; +rfCodeExportConfig.symGenMethod = "Custom"; + +const deviceId = system.deviceData.deviceId; + +// Add high PA options if present +if(deviceId.match(/CC(265[12]R|2674R|1352R1|1354R)/)) +{ + cmdList.push("cmdRadioSetup"); + rfCodeExportConfig.cmdRadioSetup = "RF_cmdIeeeRadioSetup"; +} +else if(deviceId.match(/CC(265[12]P|2674P|1352P)/)) +{ + cmdList.push("cmdRadioSetupPa"); + rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; + rfCodeExportConfig.paExport = "combined"; +} +else if(deviceId.match(/CC(265[34]|1354)P/)) +{ + cmdList.push("cmdRadioSetupPa"); + rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; + // currently not characterized for high PA +} +else +{ + throw new Error("Could not match platform to any known platform types"); +} + +rfCodeExportConfig.cmdList_ieee_15_4 = cmdList; + /* Red LED */ LED1.$name = "CONFIG_LED_RED"; LED1.$hardware = system.deviceData.board.components.LED_RED; @@ -128,15 +175,13 @@ LED2.gpioPin.mode = "Output"; LED2.gpioPin.callbackFunction = ""; /* Debug UART */ -UART1.$hardware = system.deviceData.board.components.XDS110UART; -UART1.$name = "CONFIG_UART_DEBUG"; +UART2.$hardware = system.deviceData.board.components.XDS110UART; +UART2.$name = "CONFIG_UART2_DEBUG"; /* TRNG */ TRNG1.$name = "CONFIG_TRNG_0"; -TRNG2.$name = "CONFIG_TRNG_APP"; -TRNG3.$name = "CONFIG_TRNG_THREAD"; - -RTOS.name = "FreeRTOS"; +TRNG2.$name = "CONFIG_TRNG_THREAD"; +TRNG3.$name = "CONFIG_TRNG_APP"; /* BLE */ ble.addressMode = "ADDRMODE_RP_WITH_PUBLIC_ID"; @@ -145,15 +190,14 @@ ble.numOfAdvSets = 1; ble.lockProject = true; ble.oneLibSizeOpt = true; ble.maxPDUSize = 255; -ble.radioConfig.codeExportConfig.$name = "ti_devices_radioconfig_code_export_param1"; +ble.radioConfig.codeExportConfig.$name = "ti_devices_radioconfig_code_export_param2"; ble.connUpdateParamsPeripheral.$name = "ti_ble5stack_general_ble_conn_update_params0"; ble.connUpdateParamsPeripheral.reqMinConnInt = 30; ble.connUpdateParamsPeripheral.reqMaxConnInt = 50; + ble.advSet1.$name = "ti_ble5stack_broadcaster_advertisement_set0"; ble.advSet1.advParam1.$name = "ti_ble5stack_broadcaster_advertisement_params0"; -ble.advSet1.advParam1.primIntMin = 100; -ble.advSet1.advParam1.primIntMax = 200; /* DMM */ dmm.project = "ti_thread_thermostat_remote_display"; diff --git a/examples/lock-app/cc13x4_26x4/.gn b/examples/lock-app/cc13x4_26x4/.gn new file mode 100644 index 00000000000000..3d48789e30ab3d --- /dev/null +++ b/examples/lock-app/cc13x4_26x4/.gn @@ -0,0 +1,28 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/build.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "freertos" + + import("//args.gni") +} diff --git a/examples/lock-app/cc13x4_26x4/BUILD.gn b/examples/lock-app/cc13x4_26x4/BUILD.gn new file mode 100644 index 00000000000000..2aad7a5f06134b --- /dev/null +++ b/examples/lock-app/cc13x4_26x4/BUILD.gn @@ -0,0 +1,120 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/openthread.gni") +import("//build_overrides/ti_simplelink_sdk.gni") + +import("${build_root}/config/defaults.gni") + +import("${chip_root}/src/platform/device.gni") + +import("${ti_simplelink_sdk_build_root}/ti_simplelink_executable.gni") +import("${ti_simplelink_sdk_build_root}/ti_simplelink_sdk.gni") + +assert(current_os == "freertos") + +project_dir = "${chip_root}/examples/lock-app/cc13x4_26x4" + +ti_simplelink_sdk("sdk") { + include_dirs = [ "${project_dir}/include" ] + public_configs = [ ":lock_app_config" ] +} + +ti_sysconfig("sysconfig") { + sources = [ "${project_dir}/chip.syscfg" ] + + outputs = [ + "ti_radio_config.c", + "ti_radio_config.h", + "ti_drivers_config.c", + "ti_drivers_config.h", + "ti_devices_config.c", + "ti_devices_config.h", + "ti_ble_config.c", + "ti_ble_config.h", + "ti_dmm_application_policy.c", + "ti_dmm_application_policy.h", + + # disabled until upstream generation is aligned + #"tiop_config.h", + #"tiop_config.c", + + # not traditional source files + #"ti_utils_build_linker.cmd.genlibs", + #"syscfg_c.rov.xs", + #"ti_utils_runtime_model.gv", + #"ti_utils_runtime_Makefile", + #"ti_ble_app_config.opt", + #"ti_build_config.opt", + ] + + public_configs = [ ":sdk_dmm_config" ] + + cflags = [ + "-Wno-comment", + "@" + rebase_path("${target_gen_dir}/sysconfig/ti_ble_app_config.opt", + root_build_dir), + "@" + rebase_path("${target_gen_dir}/sysconfig/ti_build_config.opt", + root_build_dir), + ] +} + +ti_simplelink_executable("lock_app") { + output_name = "chip-${ti_simplelink_board}-lock-example.out" + + sources = [ + "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", + "${project_dir}/src/AppTask.cpp", + "${project_dir}/src/LockManager.cpp", + "${project_dir}/src/ZclCallbacks.cpp", + "${project_dir}/src/main.cpp", + ] + + deps = [ + ":sdk", + ":sysconfig", + "${chip_root}/examples/lock-app/lock-common", + "${chip_root}/examples/platform/cc13x4_26x4:cc13x4_26x4-attestation-credentials", + "${chip_root}/src/lib", + ] + + if (chip_openthread_ftd) { + deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-ftd" ] + } else { + deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-mtd" ] + } + + include_dirs = [ + "${project_dir}", + "${chip_root}/examples/providers/", + ] + + cflags = [ + "-Wno-implicit-fallthrough", + "-Wno-sign-compare", + "-Wconversion", + ] + + output_dir = root_out_dir +} + +group("cc13x4_26x4") { + deps = [ ":lock_app" ] +} + +group("default") { + deps = [ ":cc13x4_26x4" ] +} diff --git a/examples/lock-app/cc13x4_26x4/README.md b/examples/lock-app/cc13x4_26x4/README.md new file mode 100644 index 00000000000000..45c3a1c67309cd --- /dev/null +++ b/examples/lock-app/cc13x4_26x4/README.md @@ -0,0 +1,326 @@ +# Matter Lock Example Application + +An example application showing the use of [Matter][matter] on the Texas +Instruments CC13XX_26XX family of Wireless MCUs. + +--- + +- [Matter Lock Example Application](#matter-lock-example-application) + - [Introduction](#introduction) + - [Device UI](#device-ui) + - [Building](#building) + - [Preparation](#preparation) + - [Compilation](#compilation) + - [Programming](#programming) + - [Code Composer Studio](#code-composer-studio) + - [UniFlash](#uniflash) + - [Running the Example](#running-the-example) + - [Provisioning](#provisioning) + - [Bluetooth LE Advertising](#bluetooth-le-advertising) + - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) + - [TI Support](#ti-support) + +--- + +## Introduction + +The CC13XX_26XX lock example application provides a working demonstration of a +connected door lock device. This uses the open-source Matter implementation and +the Texas Instruments SimpleLinkā„¢ CC13XX and CC26XX software development kit. + +This example is enabled to build for CC1354P10 devices. + +The lock example is intended to serve both as a means to explore the workings of +Matter, as well as a template for creating real products based on the Texas +Instruments devices. + +## Device UI + +| Action | Functionality | +| ------------------------------------------------ | ---------------------------------------- | +| Left Button (`BTN-1`) Press (less than 1000 ms) | Change state to unlocked | +| Right Button (`BTN-2`) Press (less than 1000 ms) | Change state to locked | +| Left Button (`BTN-1`) Press (more than 1000 ms) | Factory Reset | +| Right Button (`BTN-2`) Press (more than 1000 ms) | BLE Advertisement (Enable/Disable) | +| Red & Green LED Blinking State | Lock state transition to locked/unlocked | +| Red LED On State | Lock state locked | +| Red & Green LED Off State | Lock state unlocked | + +## Building + +### Preparation + +Some initial setup is necessary for preparing the build environment. This +section will need to be done when migrating to new versions of the SDK. This +guide assumes that the environment is linux based, and recommends Ubuntu 20.04. + +- Download and install [SysConfig][sysconfig]. This can be done simply with + the following commands. + + ``` + $ cd ~ + $ `wget https://dr-download.ti.com/software-development/ide-configuration-compiler-or-debugger/MD-nsUM6f7Vvb/1.15.0.2826/sysconfig-1.15.0_2826-setup.run` + $ chmod +x sysconfig-1.15.0_2826-setup.run + $ ./sysconfig-1.15.0_2826-setup.run + ``` + +- Run the bootstrap script to setup the build environment. + + ``` + $ cd ~/connectedhomeip + $ source ./scripts/bootstrap.sh + + ``` + +### Compilation + +It is necessary to activate the environment in every new shell. Then run GN and +Ninja to build the executable. + +- Activate the build environment with the repository activate script. + + ``` + $ cd ~/connectedhomeip + $ source ./scripts/activate.sh + + ``` + +- Run the build to produce a default executable. By default on Linux both the + TI SimpleLink SDK and Sysconfig are located in a `ti` folder in the user's + home directory, and you must provide the absolute path to them. For example + `/home/username/ti/sysconfig_1.15.0`. On Windows the default directory is + `C:\ti`. Take note of this install path, as it will be used in the next + step. + + ``` + $ cd ~/connectedhomeip/examples/lock-app/cc13x2x7_26x2x7 + OR + $ cd ~/connectedhomeip/examples/lock-app/cc13x4_26x4 + $ gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\"" + $ ninja -C out/debug + + ``` + + If you would like to define arguments on the command line you may add them + to the GN call. + + + ``` + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + ``` + +## Programming + +Loading the built image onto a LaunchPad is supported through two methods; +Uniflash and Code Composer Studio (CCS). UniFlash can be used to load the image. +Code Composer Studio can be used to load the image and debug the source code. + +### Code Composer Studio + +Programming with CCS will allow for a full debug environment within the IDE. +This is accomplished by creating a target connection to the XDS110 debugger and +starting a project-less debug session. The CCS IDE will attempt to find the +source files on the local machine based on the debug information embedded within +the ELF. CCS may prompt you to find the source code if the image was built on +another machine or the source code is located in a different location than is +recorded within the ELF. + +Download and install [Code Composer Studio][ccs]. + +First open CCS and create a new workspace. + +Create a target connection (sometimes called the CCXML) for your target SoC and +debugger as described in the [Manual Method][ccs_manual_method] section of the +CCS User's Guide. + +Next initiate a project-less debug session as described in the [Manual +Launch][ccs_manual_launch] section of the CCS User's Guide. + +CCS should switch to the debug view described in the [After +Launch][ccs_after_launch] section of the User's Guide. The SoC core will likely +be disconnected and symbols will not be loaded. Connect to the core as described +in the [Debug View][ccs_debug_view] section of the User's Guide. Once the core +is connected, use the `Load` button on the toolbar to load the ELF image. + +Note that the default configuration of the CCXML uses 2-wire cJTAG instead of +the full 4-wire JTAG connection to match the default jumper configuration of the +LaunchPad. + +### UniFlash + +Uniflash is Texas Instrument's uniform programming tool for embedded processors. +This will allow you to erase, flash, and inspect the SoC without setting up a +debugging environment. + +Download and install [UniFlash][uniflash]. + +First open UniFlash. Debug probes connected to the computer will usually be +displayed under the Detected Devices due to the automatic device detection +feature. If your device does not show up in this view it my be disconnected, or +you may have to create a New Configuration. If you already have a CCXML for your +SoC and debug connection you can use that in the section at the bottom. Once +your device is selected, click the `Start` button within the section to launch +the session. + +Select the ELF image to load on the device with the `Browse` button. This file +is placed in the `out/debug` folder by this guide and ends with the `*.out` file +extension. For OTA enabled applications, the standalone image will instead end +with the `*-bim.hex` file extension. This this is a combined image with +application and and `BIM` included. The flag to enable or disable the OTA +feature is determined by "chip_enable_ota_requestor" in the application's +args.gni file. + +Finally click the `Load Image` button to load the executable image onto the +device. You should be able to see the log output over the XDS110 User UART. + +Note that programming the device through JTAG sets the Halt-in-Boot flag and may +cause issues when performing a software reset. This flag can be reset by +power-cycling the LaunchPad. + +## Running the Example + +By default the log output will be sent to the Application/User UART. Open a +terminal emulator to that port to see the output with the following options: + +| Parameter | Value | +| ------------ | -------- | +| Speed (baud) | `115200` | +| Data bits | `8` | +| Stop bits | `1` | +| Parity | `None` | +| Flow control | `None` | + +## Running the Example + +Once a device has been flashed with this example, it can now join and operate in +an existing Matter network. The following sections assume that a Matter network +is already active, and has at least one [OpenThread Border +Router][ot_border_router_setup]. + +For insight into what other components are needed to run this example, please +refer to our [Matter Getting Started Guide][matter-e2e-faq]. + +The steps below should be followed to commission the device onto the network and +control it once it has been commissioned. + +**Step 0** + +Set up the CHIP tool by following the instructions outlined in our [Matter +Getting Started Guide][matter-e2e-faq]. + +**Step 1** + +Commission the device onto the Matter network. Run the following command on the +CHIP tool: + +``` + +./chip-tool pairing ble-thread hex: 20202021 3840 + +``` + +Interacting with the application begins by enabling BLE advertisements and then +pairing the device into a Thread network. To provision this example onto a +Matter network, the device must be discoverable over Bluetooth LE. + +On the LaunchPad, press and hold the right button, labeled `BTN-2`, for more +than 1 second. Upon release, the Bluetooth LE advertising will begin. Once the +device is fully provisioned, BLE advertising will stop. + +Once the device has been successfully commissioned, you will see the following +message on the CHIP tool output: + +``` + +[1677648218.370754][39785:39790] CHIP:CTL: Received CommissioningComplete response, errorCode=0 +[1677648218.370821][39785:39790] CHIP:CTL: Successfully finished commissioning step 'SendComplete' + +``` + +An accompanying message will be seen from the device: + +``` + +Commissioning complete, notify platform driver to persist network credentials. + +``` + +**Step 2** The example Doorlock cluster operations have the following format: + +``` +./chip-tool doorlock +./chip-tool doorlock set-user +./chip-tool +``` + +Send commands to the lock-app. Here are some example commands: + +Set a new user "`TST`" with user index of 1 with a default pin of 123456 + +``` +./chip-tool doorlock set-user 0 1 `TST` 6452 1 0 0 1 1 --timedInteractionTimeoutMs 1000 +./chip-tool doorlock set-credential 0 '{ "credentialType" : 1 , "credentialIndex" : 1 }' 123456 1 null null 1 1 --timedInteractionTimeoutMs 1000 +``` + +Require a pin mode for lock operations: + +``` +./chip-tool doorlock write require-pinfor-remote-operation 1 1 1 +``` + +Lock the Door + +``` +./chip-tool doorlock lock-door 1 1 --timedInteractionTimeoutMs 1000 --PinCode 123456 +``` + +Unlock the door + +``` +./chip-tool doorlock unlock-door 1 1 --timedInteractionTimeoutMs 1000 --PinCode 123456 +``` + +### Provisioning + +Interacting with the application begins by enabling BLE advertisements and then +pairing the device into a Thread network. + +#### Bluetooth LE Advertising + +To provision this example onto a Thread network, the device must be discoverable +over Bluetooth LE. BLE advertising is started by long pressing the right button +(greater than 1000ms), labeled `BTN-2` on the silkscreen. Once the device is +fully provisioned, BLE advertising will stop. + +#### Bluetooth LE Rendezvous + +Pairing this application with `ble-thread` can be done with any of the enabled +[CHIP Controller](../../../src/controller/README.md) applications. Use the +information printed on the console to aide in pairing the device. The controller +application can also be used to control the example app with the cluster +commands. + +## TI Support + +For technical support, please consider creating a post on TI's [E2E forum][e2e]. +Additionally, we welcome any feedback. + +[matter]: https://csa-iot.org/all-solutions/matter/ +[ccs]: https://www.ti.com/tool/CCSTUDIO +[ccs_after_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#after-launch +[ccs_debug_view]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#debug-view +[ccs_manual_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-launch +[ccs_manual_method]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-method +[e2e]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum +[matter-e2e-faq]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/1082428/faq-cc2652r7-matter----getting-started-guide +[sysconfig]: https://www.ti.com/tool/SYSCONFIG +[ti_thread_dnd]: + https://www.ti.com/wireless-connectivity/thread/design-development.html +[ot_border_router_setup]: https://openthread.io/guides/border-router/build +[uniflash]: https://www.ti.com/tool/download/UNIFLASH diff --git a/examples/lock-app/cc13x4_26x4/args.gni b/examples/lock-app/cc13x4_26x4/args.gni new file mode 100644 index 00000000000000..bea77489ce4158 --- /dev/null +++ b/examples/lock-app/cc13x4_26x4/args.gni @@ -0,0 +1,49 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/chip.gni") +import("${chip_root}/examples/platform/cc13x4_26x4/args.gni") + +ti_simplelink_sdk_target = get_label_info(":sdk", "label_no_toolchain") +ti_simplelink_sysconfig_target = + get_label_info(":sysconfig", "label_no_toolchain") + +ti_simplelink_board = "LP_EM_CC1354P10_6" + +# Size Optimizations +# use -Os instead of -Og, LWIP release build +optimize_debug_level = "s" +lwip_debug = false + +chip_enable_ota_requestor = false + +chip_openthread_ftd = false +openthread_external_platform = "${chip_root}/third_party/openthread/platforms/cc13x4_26x4:libopenthread-cc13x4_cc26x4" + +# Disable CHIP Logging +#chip_progress_logging = false +#chip_detail_logging = false +#chip_automation_logging = false + +# BLE options +chip_config_network_layer_ble = true + +# Disable lock tracking, since our FreeRTOS configuration does not set +# INCLUDE_xSemaphoreGetMutexHolder +chip_stack_lock_tracking = "none" + +matter_device_vid = "0xFFF1" +matter_device_pid = "0x8006" +matter_software_ver = "0x0001" +matter_software_ver_str = "1.0d1" diff --git a/examples/lock-app/cc13x4_26x4/build_overrides b/examples/lock-app/cc13x4_26x4/build_overrides new file mode 120000 index 00000000000000..e578e73312ebd1 --- /dev/null +++ b/examples/lock-app/cc13x4_26x4/build_overrides @@ -0,0 +1 @@ +../../build_overrides \ No newline at end of file diff --git a/examples/lock-app/cc13x4_26x4/chip.syscfg b/examples/lock-app/cc13x4_26x4/chip.syscfg new file mode 100644 index 00000000000000..e9cb55c3e22f07 --- /dev/null +++ b/examples/lock-app/cc13x4_26x4/chip.syscfg @@ -0,0 +1,242 @@ +/* + * + * Copyright (c) 2020 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. + */ + + +/* Modules */ +var AESCCM = scripting.addModule("/ti/drivers/AESCCM"); +var AESECB = scripting.addModule("/ti/drivers/AESECB"); +var Button = scripting.addModule("/ti/drivers/apps/Button"); +var LED = scripting.addModule("/ti/drivers/apps/LED"); +var NVS = scripting.addModule("/ti/drivers/NVS"); +var RF = scripting.addModule("/ti/drivers/RF"); +var RFDesign = scripting.addModule("ti/devices/radioconfig/rfdesign"); +var RFCustom = scripting.addModule("/ti/devices/radioconfig/custom"); +var TRNG = scripting.addModule("/ti/drivers/TRNG"); +var SHA2 = scripting.addModule("/ti/drivers/SHA2"); +var UART2 = scripting.addModule("/ti/drivers/UART2"); +var ble = scripting.addModule("/ti/ble5stack/ble"); +var dmm = scripting.addModule("/ti/dmm/dmm"); +var AESCTRDRBG = scripting.addModule("/ti/drivers/AESCTRDRBG"); +var ECDH = scripting.addModule("/ti/drivers/ECDH"); + +/* Instances */ +var AESCCM1 = AESCCM.addInstance(); +var AESECB1 = AESECB.addInstance(); +var AESECB2 = AESECB.addInstance(); +var Button1 = Button.addInstance(); +var Button2 = Button.addInstance(); +var NVS1 = NVS.addInstance(); +var NVS2 = NVS.addInstance(); +var SHA21 = SHA2.addInstance(); +var LED1 = LED.addInstance(); +var LED2 = LED.addInstance(); +var TRNG1 = TRNG.addInstance(); +var TRNG2 = TRNG.addInstance(); +var TRNG3 = TRNG.addInstance(); +var UART2 = UART2.addInstance(); +var AESCTRDRBG1 = AESCTRDRBG.addInstance(); +var ECDH1 = ECDH.addInstance(); + +AESCTRDRBG1.$name = "CONFIG_AESCTRDRBG_0"; + +AESCCM1.$name = "CONFIG_AESCCM0"; + +AESECB1.$name = "CONFIG_AESECB0"; +AESECB2.$name = "CONFIG_AESECB_1"; + +ECDH1.$name = "CONFIG_ECDH0"; + +/* Left Button */ +Button1.$name = "CONFIG_BTN_LEFT"; +Button1.$hardware = system.deviceData.board.components["BTN-1"]; +Button1.gpioPin.$name = "CONFIG_GPIO_BTN1"; +Button1.gpioPin.pull = "Pull Up"; +Button1.gpioPin.interruptTrigger = "Falling Edge"; + +/* Left Button */ +Button2.$name = "CONFIG_BTN_RIGHT"; +Button2.$hardware = system.deviceData.board.components["BTN-2"]; +Button2.gpioPin.$name = "CONFIG_GPIO_BTN2"; +Button2.gpioPin.pull = "Pull Up"; +Button2.gpioPin.interruptTrigger = "Falling Edge"; + +/* ======== CCFG ======== */ +var CCFG = scripting.addModule("/ti/devices/CCFG"); +const ccfgSettings = system.getScript("/ti/common/lprf_ccfg_settings.js").ccfgSettings; +for(var setting in ccfgSettings) +{ + CCFG[setting] = ccfgSettings[setting]; +} + +CCFG.enableCodeGeneration = true; + + +/* NVS */ +NVS1.$name = "CONFIG_NVSINTERNAL"; +NVS1.internalFlash.regionBase = 0xFB800; +NVS1.internalFlash.regionSize = 0x2800; + + +NVS2.$name = "CONFIG_NVSEXTERNAL"; +NVS2.nvsType = "External"; // NVS Region Type +NVS2.$hardware = system.deviceData.board.components.MX25R8035F; + +/* RF */ +/* if an antenna component exists, assign it to the rf instance */ +if (system.deviceData.board && system.deviceData.board.components.RF) { + RF.$hardware = system.deviceData.board.components.RF; +} + +const rfDesignSettings = system.getScript("/ti/common/lprf_rf_design_settings.js").rfDesignSettings; +for(var setting in rfDesignSettings) +{ + RFDesign[setting] = rfDesignSettings[setting]; +} + + + +/* Handling for RF frontend characterization */ +if(RFDesign.rfDesign.match(/LP_CC2652PSIP/)) +{ + RFCustom.ieee = ["ieee154p10"]; + var rfCodeExportConfig = RFCustom.radioConfigieee154p10.codeExportConfig +} +else +{ + RFCustom.ieee = ["ieee154"]; + var rfCodeExportConfig = RFCustom.radioConfigieee154.codeExportConfig +} + +var cmdList = [ + "cmdIeeeTx", + "cmdIeeeRx", + "cmdIeeeCsma", + "cmdIeeeEdScan", + "cmdIeeeRxAck", + "cmdTxTest" +]; + +rfCodeExportConfig.useConst = true; +rfCodeExportConfig.useMulti = true; +rfCodeExportConfig.symGenMethod = "Custom"; + +const deviceId = system.deviceData.deviceId; + +// Add high PA options if present +if(deviceId.match(/CC(265[12]R|2674R|1352R1|1354R)/)) +{ + cmdList.push("cmdRadioSetup"); + rfCodeExportConfig.cmdRadioSetup = "RF_cmdIeeeRadioSetup"; +} +else if(deviceId.match(/CC(265[12]P|2674P|1352P)/)) +{ + cmdList.push("cmdRadioSetupPa"); + rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; + rfCodeExportConfig.paExport = "combined"; +} +else if(deviceId.match(/CC(265[34]|1354)P/)) +{ + cmdList.push("cmdRadioSetupPa"); + rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; + // currently not characterized for high PA +} +else +{ + throw new Error("Could not match platform to any known platform types"); +} + +rfCodeExportConfig.cmdList_ieee_15_4 = cmdList; + +/* Red LED */ +LED1.$name = "CONFIG_LED_RED"; +LED1.$hardware = system.deviceData.board.components.LED_RED; +LED1.gpioPin.$name = "CONFIG_GPIO_RLED"; +LED1.gpioPin.mode = "Output"; +LED1.gpioPin.callbackFunction = ""; + +/* Green LED */ +LED2.$name = "CONFIG_LED_GREEN"; +LED2.$hardware = system.deviceData.board.components.LED_GREEN; +LED2.gpioPin.$name = "CONFIG_GPIO_GLED"; +LED2.gpioPin.mode = "Output"; +LED2.gpioPin.callbackFunction = ""; + +/* Debug UART */ +UART2.$hardware = system.deviceData.board.components.XDS110UART; +UART2.$name = "CONFIG_UART2_DEBUG"; + +/* TRNG */ +TRNG1.$name = "CONFIG_TRNG_0"; +TRNG2.$name = "CONFIG_TRNG_THREAD"; +TRNG3.$name = "CONFIG_TRNG_APP"; + +/* BLE */ +ble.addressMode = "ADDRMODE_RP_WITH_PUBLIC_ID"; +ble.maxConnNum = 1; +ble.numOfAdvSets = 1; +ble.lockProject = true; +ble.oneLibSizeOpt = true; +ble.maxPDUSize = 255; +ble.radioConfig.codeExportConfig.$name = "ti_devices_radioconfig_code_export_param1"; +ble.connUpdateParamsPeripheral.$name = "ti_ble5stack_general_ble_conn_update_params0"; +ble.connUpdateParamsPeripheral.reqMinConnInt = 30; +ble.connUpdateParamsPeripheral.reqMaxConnInt = 50; + +ble.advSet1.$name = "ti_ble5stack_broadcaster_advertisement_set0"; +ble.advSet1.advParam1.$name = "ti_ble5stack_broadcaster_advertisement_params0"; + +ble.rfDesign = "LP_EM_CC1354P10_6"; + +ble.thorPg = 2; +/* DMM */ +dmm.project = "ti_thread_thermostat_remote_display"; +dmm.stackRoles = ["blePeripheral","threadFTD"]; +dmm.lockStackRoles = true; +dmm.numApplicationStates = 10; +dmm.applicationState0 = "ANY"; +dmm.applicationState1 = "DMMPOLICY_BLE_IDLE"; +dmm.applicationState2 = "DMMPOLICY_BLE_ADV"; +dmm.applicationState3 = "DMMPOLICY_BLE_CONNECTING"; +dmm.applicationState4 = "DMMPOLICY_BLE_HIGH_BANDWIDTH"; +dmm.applicationState5 = "DMMPOLICY_BLE_CONNECTED"; +dmm.applicationState6 = "DMMPOLICY_BLE_OAD"; +dmm.applicationState7 = "DMMPOLICY_THREAD_IDLE"; +dmm.applicationState8 = "DMMPOLICY_THREAD_LINK_EST"; +dmm.applicationState9 = "DMMPOLICY_THREAD_DATA"; +dmm.policyArray.create(4); +dmm.policyArray[0].$name = "ti_dmm_policy_dmm_policy0"; +dmm.policyArray[0].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble0"; +dmm.policyArray[0].blePeripheral.applicationStates = ["applicationState6"]; +dmm.policyArray[0].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread0"; +dmm.policyArray[0].threadFTD.pause = "DMMPOLICY_PAUSED"; +dmm.policyArray[1].$name = "ti_dmm_policy_dmm_policy1"; +dmm.policyArray[1].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble1"; +dmm.policyArray[1].blePeripheral.applicationStates = ["applicationState3","applicationState4"]; +dmm.policyArray[1].blePeripheral.weight = 25; +dmm.policyArray[1].blePeripheral.appliedActivity = ["DMMPOLICY_APPLIED_ACTIVITY_BLE_CONNECTION"]; +dmm.policyArray[1].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread1"; +dmm.policyArray[2].$name = "ti_dmm_policy_dmm_policy2"; +dmm.policyArray[2].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble2"; +dmm.policyArray[2].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread2"; +dmm.policyArray[2].threadFTD.weight = 30; +dmm.policyArray[2].threadFTD.applicationStates = ["applicationState8"]; +dmm.policyArray[2].threadFTD.appliedActivity = ["DMMPOLICY_APPLIED_ACTIVITY_ALL"]; +dmm.policyArray[3].$name = "ti_dmm_policy_dmm_policy3"; +dmm.policyArray[3].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble3"; +dmm.policyArray[3].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread3"; +dmm.policyArray[3].threadFTD.weight = 1; diff --git a/examples/lock-app/cc13x4_26x4/include/CHIPProjectConfig.h b/examples/lock-app/cc13x4_26x4/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..a808f37a72d7b5 --- /dev/null +++ b/examples/lock-app/cc13x4_26x4/include/CHIPProjectConfig.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * 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. + * + */ + +#ifndef CHIP_PROJECT_CONFIG_H +#define CHIP_PROJECT_CONFIG_H + +#if BUILD_RELEASE // release build +// Note: Default Pairing/PIN/Serial Numbers being used. These should not be enabled for production builds +#endif // BUILD_RELEASE + +// 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 + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" + +/** + * CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER + * + * Enables the use of a hard-coded default serial number if none + * is found in CHIP NV storage. + */ +#define CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER "TEST_SN" + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 1 +#endif + +/** + * Values set by args.gni: + * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION + */ + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + * + * Enable support for CHIP-over-BLE (CHIPOBLE). + */ +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote CHIP Time service + * using the CHIP Time Sync protocol. + */ +// #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 + +/** + * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE + * + * A size, in bytes, of the individual debug event logging buffer. + */ +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) + +#define MATTER_CC13XX_26XX_PLATFORM_LOG_ENABLED 1 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + * + * Enable the OpenThread SRP client to allow for CHIP device discovery. + */ +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT 1 + +/** + * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE + * + * For a development build, set the default importance of events to be logged as Debug. + * Since debug is the lowest importance level, this means all standard, critical, info and + * debug importance level vi events get logged. + */ +#if BUILD_RELEASE +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production +#else +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug +#endif // BUILD_RELEASE + +#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 + +/** + * @def CHIP_IM_MAX_NUM_COMMAND_HANDLER + * + * @brief Defines the maximum number of CommandHandler, limits the number of active commands transactions on server. + */ +#define CHIP_IM_MAX_NUM_COMMAND_HANDLER 2 + +/** + * @def CHIP_IM_MAX_NUM_WRITE_HANDLER + * + * @brief Defines the maximum number of WriteHandler, limits the number of active write transactions on server. + */ +#define CHIP_IM_MAX_NUM_WRITE_HANDLER 2 + +#endif // CHIP_PROJECT_CONFIG_H diff --git a/examples/lock-app/cc13x4_26x4/src/AppConfig.h b/examples/lock-app/cc13x4_26x4/src/AppConfig.h new file mode 100644 index 00000000000000..a818b21d641875 --- /dev/null +++ b/examples/lock-app/cc13x4_26x4/src/AppConfig.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef APP_CONFIG_H +#define APP_CONFIG_H + +// Logging +#ifdef __cplusplus +extern "C" { +#endif + +int cc13xx_26xxLogInit(void); +void cc13xx_26xxLog(const char * aFormat, ...); +#define PLAT_LOG(...) cc13xx_26xxLog(__VA_ARGS__); + +#define ACTUATOR_MOVEMENT_PERIOD_MS 1000 + +#ifdef __cplusplus +} +#endif +#endif // APP_CONFIG_H diff --git a/examples/lock-app/cc13x4_26x4/src/AppEvent.h b/examples/lock-app/cc13x4_26x4/src/AppEvent.h new file mode 100644 index 00000000000000..dc4ce143338e1e --- /dev/null +++ b/examples/lock-app/cc13x4_26x4/src/AppEvent.h @@ -0,0 +1,68 @@ +/* + * + * Copyright (c) 2021 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. + */ + +#ifndef APP_EVENT_H +#define APP_EVENT_H + +struct AppEvent; +typedef void (*EventHandler)(AppEvent *); + +struct AppEvent +{ + enum AppEventType + { + kEventType_None = 0, + kEventType_ButtonLeft, + kEventType_ButtonRight, + kEventType_AppEvent, + kEventType_IdentifyStart, + kEventType_IdentifyStop, + }; + + enum AppEventButtonType + { + kAppEventButtonType_None = 0, + kAppEventButtonType_Clicked, + kAppEventButtonType_LongClicked, + }; + + enum AppEventType Type; + + union + { + struct + { + enum AppEventButtonType Type; + } ButtonEvent; + + struct + { + void * Context; + } BoltLockEvent; + + struct + { + uint8_t Action; + int32_t Actor; + } LockEvent; + }; + + EventHandler Handler; +}; + +#endif // APP_EVENT_H diff --git a/examples/lock-app/cc13x4_26x4/src/AppTask.cpp b/examples/lock-app/cc13x4_26x4/src/AppTask.cpp new file mode 100644 index 00000000000000..5880c270030efa --- /dev/null +++ b/examples/lock-app/cc13x4_26x4/src/AppTask.cpp @@ -0,0 +1,560 @@ +/* + * + * Copyright (c) 2020 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 "FreeRTOS.h" + +#include +#include + +#include +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +#include +#include +#include +#include +#include +#endif + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +/* syscfg */ +#include + +#define APP_TASK_STACK_SIZE (4096) +#define APP_TASK_PRIORITY 4 +#define APP_EVENT_QUEUE_SIZE 10 + +using namespace ::chip; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; +using namespace ::chip::app::Clusters::DoorLock; + +static TaskHandle_t sAppTaskHandle; +static QueueHandle_t sAppEventQueue; + +static LED_Handle sAppRedHandle; +static LED_Handle sAppGreenHandle; +static Button_Handle sAppLeftHandle; +static Button_Handle sAppRightHandle; +static DeviceInfoProviderImpl sExampleDeviceInfoProvider; + +AppTask AppTask::sAppTask; + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +static DefaultOTARequestor sRequestorCore; +static DefaultOTARequestorStorage sRequestorStorage; +static DefaultOTARequestorDriver sRequestorUser; +static BDXDownloader sDownloader; +static OTAImageProcessorImpl sImageProcessor; + +void InitializeOTARequestor(void) +{ + // Initialize and interconnect the Requestor and Image Processor objects + SetRequestorInstance(&sRequestorCore); + + sRequestorStorage.Init(Server::GetInstance().GetPersistentStorage()); + sRequestorCore.Init(Server::GetInstance(), sRequestorStorage, sRequestorUser, sDownloader); + sImageProcessor.SetOTADownloader(&sDownloader); + sDownloader.SetImageProcessorDelegate(&sImageProcessor); + sRequestorUser.Init(&sRequestorCore, &sImageProcessor); +} +#endif + +::Identify stIdentify = { 0, AppTask::IdentifyStartHandler, AppTask::IdentifyStopHandler, + EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, AppTask::TriggerIdentifyEffectHandler }; + +int AppTask::StartAppTask() +{ + int ret = 0; + + sAppEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent)); + if (sAppEventQueue == NULL) + { + PLAT_LOG("Failed to allocate app event queue"); + while (1) + ; + } + + // Start App task. + if (xTaskCreate(AppTaskMain, "APP", APP_TASK_STACK_SIZE / sizeof(StackType_t), NULL, APP_TASK_PRIORITY, &sAppTaskHandle) != + pdPASS) + { + PLAT_LOG("Failed to create app task"); + while (1) + ; + } + return ret; +} + +void uiLocking(void) +{ + PLAT_LOG("Lock initiated"); + LED_setOn(sAppGreenHandle, LED_BRIGHTNESS_MAX); + LED_startBlinking(sAppGreenHandle, 50 /* ms */, LED_BLINK_FOREVER); + LED_setOn(sAppRedHandle, LED_BRIGHTNESS_MAX); + LED_startBlinking(sAppRedHandle, 110 /* ms */, LED_BLINK_FOREVER); +} + +void uiLocked(void) +{ + PLAT_LOG("Lock completed"); + LED_stopBlinking(sAppGreenHandle); + LED_setOff(sAppGreenHandle); + LED_stopBlinking(sAppRedHandle); + LED_setOn(sAppRedHandle, LED_BRIGHTNESS_MAX); +} + +void uiUnlocking(void) +{ + PLAT_LOG("Unlock initiated"); + LED_setOn(sAppGreenHandle, LED_BRIGHTNESS_MAX); + LED_startBlinking(sAppGreenHandle, 50 /* ms */, LED_BLINK_FOREVER); + LED_setOn(sAppRedHandle, LED_BRIGHTNESS_MAX); + LED_startBlinking(sAppRedHandle, 110 /* ms */, LED_BLINK_FOREVER); +} + +void uiUnlocked(void) +{ + PLAT_LOG("Unlock completed"); + LED_stopBlinking(sAppGreenHandle); + LED_setOff(sAppGreenHandle); + LED_stopBlinking(sAppRedHandle); + LED_setOff(sAppRedHandle); +} + +int AppTask::Init() +{ + LED_Params ledParams; + Button_Params buttonParams; + + cc13xx_26xxLogInit(); + + // Init Chip memory management before the stack + Platform::MemoryInit(); + + CHIP_ERROR ret = PlatformMgr().InitChipStack(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("PlatformMgr().InitChipStack() failed"); + while (1) + ; + } + + ret = ThreadStackMgr().InitThreadStack(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("ThreadStackMgr().InitThreadStack() failed"); + while (1) + ; + } +#if CHIP_DEVICE_CONFIG_THREAD_FTD + ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); +#else + ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); +#endif + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("ConnectivityMgr().SetThreadDeviceType() failed"); + while (1) + ; + } + + ret = PlatformMgr().StartEventLoopTask(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("PlatformMgr().StartEventLoopTask() failed"); + while (1) + ; + } + + ret = ThreadStackMgrImpl().StartThreadTask(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("ThreadStackMgr().StartThreadTask() failed"); + while (1) + ; + } + + // Init ZCL Data Model and start server + PLAT_LOG("Initialize Server"); + static CommonCaseDeviceServerInitParams initParams; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + + // Initialize info provider + sExampleDeviceInfoProvider.SetStorageDelegate(initParams.persistentStorageDelegate); + SetDeviceInfoProvider(&sExampleDeviceInfoProvider); + + Server::GetInstance().Init(initParams); + + // Initialize device attestation config +#ifdef CC13X4_26X4_ATTESTATION_CREDENTIALS + SetDeviceAttestationCredentialsProvider(CC13X4_26X4::GetCC13X4_26X4DacProvider()); +#else + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif + + // Initialize LEDs + PLAT_LOG("Initialize LEDs"); + LED_init(); + + LED_Params_init(&ledParams); // default PWM LED + sAppRedHandle = LED_open(CONFIG_LED_RED, &ledParams); + LED_setOff(sAppRedHandle); + + LED_Params_init(&ledParams); // default PWM LED + sAppGreenHandle = LED_open(CONFIG_LED_GREEN, &ledParams); + LED_setOff(sAppGreenHandle); + + // Initialize buttons + PLAT_LOG("Initialize buttons"); + Button_init(); + + Button_Params_init(&buttonParams); + buttonParams.buttonEventMask = Button_EV_CLICKED | Button_EV_LONGCLICKED; + buttonParams.longPressDuration = 1000U; // ms + sAppLeftHandle = Button_open(CONFIG_BTN_LEFT, &buttonParams); + Button_setCallback(sAppLeftHandle, ButtonLeftEventHandler); + + Button_Params_init(&buttonParams); + buttonParams.buttonEventMask = Button_EV_CLICKED | Button_EV_LONGCLICKED; + buttonParams.longPressDuration = 1000U; // ms + sAppRightHandle = Button_open(CONFIG_BTN_RIGHT, &buttonParams); + Button_setCallback(sAppRightHandle, ButtonRightEventHandler); + + PlatformMgr().LockChipStack(); + { + uint8_t numberOfCredentialsPerUser = 0; + uint16_t numberOfUsers = 0; + uint8_t numberOfWeekdaySchedulesPerUser = 0; + uint8_t numberOfYeardaySchedulesPerUser = 0; + uint8_t numberOfHolidaySchedules = 0; + chip::app::DataModel::Nullable state; + EndpointId endpointId{ 1 }; + + if (!DoorLockServer::Instance().GetNumberOfCredentialsSupportedPerUser(endpointId, numberOfCredentialsPerUser)) + { + numberOfCredentialsPerUser = 5; + } + + if (!DoorLockServer::Instance().GetNumberOfUserSupported(endpointId, numberOfUsers)) + { + numberOfUsers = 10; + } + + if (!DoorLockServer::Instance().GetNumberOfWeekDaySchedulesPerUserSupported(endpointId, numberOfWeekdaySchedulesPerUser)) + { + numberOfWeekdaySchedulesPerUser = 10; + } + + if (!DoorLockServer::Instance().GetNumberOfYearDaySchedulesPerUserSupported(endpointId, numberOfYeardaySchedulesPerUser)) + { + numberOfYeardaySchedulesPerUser = 10; + } + + if (!DoorLockServer::Instance().GetNumberOfHolidaySchedulesSupported(endpointId, numberOfHolidaySchedules)) + { + numberOfHolidaySchedules = 10; + } + + Attributes::LockState::Get(endpointId, state); + ret = LockMgr().Init(state, + CC13X2_26X2DoorLock::LockInitParams::ParamBuilder() + .SetNumberOfUsers(numberOfUsers) + .SetNumberOfCredentialsPerUser(numberOfCredentialsPerUser) + .SetNumberOfWeekdaySchedulesPerUser(numberOfWeekdaySchedulesPerUser) + .SetNumberOfYeardaySchedulesPerUser(numberOfYeardaySchedulesPerUser) + .SetNumberOfHolidaySchedules(numberOfHolidaySchedules) + .GetLockParam()); + + if (state.Value() == DlLockState::kLocked) + { + uiLocked(); + } + else + { + uiUnlocked(); + } + } + + PlatformMgr().UnlockChipStack(); + + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("LockMgr().Init() failed"); + while (1) + ; + } + + LockMgr().SetCallbacks(ActionInitiated, ActionCompleted); + + ConfigurationMgr().LogDeviceConfig(); + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + InitializeOTARequestor(); +#endif + // QR code will be used with CHIP Tool + PrintOnboardingCodes(RendezvousInformationFlags(RendezvousInformationFlag::kBLE)); + + return 0; +} + +void AppTask::AppTaskMain(void * pvParameter) +{ + AppEvent event; + + sAppTask.Init(); + + LockMgr().ReadConfigValues(); + + while (1) + { + /* Task pend until we have stuff to do */ + if (xQueueReceive(sAppEventQueue, &event, portMAX_DELAY) == pdTRUE) + { + sAppTask.DispatchEvent(&event); + } + } +} + +void AppTask::ButtonLeftEventHandler(Button_Handle handle, Button_EventMask events) +{ + AppEvent event; + event.Type = AppEvent::kEventType_ButtonLeft; + + if (events & Button_EV_CLICKED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_Clicked; + } + else if (events & Button_EV_LONGCLICKED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_LongClicked; + } + // button callbacks are in ISR context + if (xQueueSendFromISR(sAppEventQueue, &event, NULL) != pdPASS) + { + /* Failed to post the message */ + } +} + +void AppTask::ButtonRightEventHandler(Button_Handle handle, Button_EventMask events) +{ + AppEvent event; + event.Type = AppEvent::kEventType_ButtonRight; + + if (events & Button_EV_CLICKED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_Clicked; + } + else if (events & Button_EV_LONGCLICKED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_LongClicked; + } + // button callbacks are in ISR context + if (xQueueSendFromISR(sAppEventQueue, &event, NULL) != pdPASS) + { + /* Failed to post the message */ + } +} + +void AppTask::ActionInitiated(LockManager::Action_t aAction) +{ + if (aAction == LockManager::LOCK_ACTION) + { + uiLocking(); + } + else if (aAction == LockManager::UNLOCK_ACTION) + { + uiUnlocking(); + } +} + +void AppTask::ActionCompleted(LockManager::Action_t aAction) +{ + if (aAction == LockManager::LOCK_ACTION) + { + uiLocked(); + } + else if (aAction == LockManager::UNLOCK_ACTION) + { + uiUnlocked(); + } +} + +void AppTask::PostEvent(const AppEvent * aEvent) +{ + if (sAppEventQueue != NULL) + { + BaseType_t status; + if (xPortIsInsideInterrupt()) + { + BaseType_t higherPrioTaskWoken = pdFALSE; + status = xQueueSendFromISR(sAppEventQueue, aEvent, &higherPrioTaskWoken); + +#ifdef portYIELD_FROM_ISR + portYIELD_FROM_ISR(higherPrioTaskWoken); +#elif portEND_SWITCHING_ISR // portYIELD_FROM_ISR or portEND_SWITCHING_ISR + portEND_SWITCHING_ISR(higherPrioTaskWoken); +#else // portYIELD_FROM_ISR or portEND_SWITCHING_ISR +#error "Must have portYIELD_FROM_ISR or portEND_SWITCHING_ISR" +#endif // portYIELD_FROM_ISR or portEND_SWITCHING_ISR + } + else + { + status = xQueueSend(sAppEventQueue, aEvent, 1); + } + + if (status != pdTRUE) + { + PLAT_LOG("Failed to post event to app task event queue"); + } + } + else + { + PLAT_LOG("Event Queue is NULL should never happen"); + } +} + +void AppTask::DispatchEvent(AppEvent * aEvent) +{ + switch (aEvent->Type) + { + case AppEvent::kEventType_ButtonLeft: + if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) + { + LockMgr().InitiateAction(LockManager::UNLOCK_ACTION); + } + else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) + { + chip::Server::GetInstance().ScheduleFactoryReset(); + } + break; + + case AppEvent::kEventType_ButtonRight: + if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) + { + LockMgr().InitiateAction(LockManager::LOCK_ACTION); + } + else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) + { + // Enable BLE advertisements + if (!ConnectivityMgr().IsBLEAdvertisingEnabled()) + { + if (Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() == CHIP_NO_ERROR) + { + PLAT_LOG("Enabled BLE Advertisements"); + } + else + { + PLAT_LOG("OpenBasicCommissioningWindow() failed"); + } + } + else + { + // Disable BLE advertisements + ConnectivityMgr().SetBLEAdvertisingEnabled(false); + PLAT_LOG("Disabled BLE Advertisements"); + } + } + break; + + case AppEvent::kEventType_IdentifyStart: + LED_setOn(sAppGreenHandle, LED_BRIGHTNESS_MAX); + LED_startBlinking(sAppGreenHandle, 500, LED_BLINK_FOREVER); + PLAT_LOG("Identify started"); + break; + + case AppEvent::kEventType_IdentifyStop: + LED_stopBlinking(sAppGreenHandle); + + LED_setOff(sAppGreenHandle); + PLAT_LOG("Identify stopped"); + break; + + case AppEvent::kEventType_AppEvent: + if (NULL != aEvent->Handler) + { + aEvent->Handler(aEvent); + } + break; + + case AppEvent::kEventType_None: + default: + break; + } +} + +void AppTask::IdentifyStartHandler(::Identify *) +{ + AppEvent event; + event.Type = AppEvent::kEventType_IdentifyStart; + sAppTask.PostEvent(&event); +} + +void AppTask::IdentifyStopHandler(::Identify *) +{ + AppEvent event; + event.Type = AppEvent::kEventType_IdentifyStop; + sAppTask.PostEvent(&event); +} + +void AppTask::TriggerIdentifyEffectHandler(::Identify * identify) +{ + switch (identify->mCurrentEffectIdentifier) + { + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: + PLAT_LOG("Starting blink identifier effect"); + IdentifyStartHandler(identify); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: + PLAT_LOG("Breathe identifier effect not implemented"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: + PLAT_LOG("Okay identifier effect not implemented"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: + PLAT_LOG("Channel Change identifier effect not implemented"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: + PLAT_LOG("Finish identifier effect not implemented"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: + PLAT_LOG("Stop identifier effect"); + IdentifyStopHandler(identify); + break; + default: + PLAT_LOG("No identifier effect"); + } +} diff --git a/examples/lock-app/cc13x4_26x4/src/AppTask.h b/examples/lock-app/cc13x4_26x4/src/AppTask.h new file mode 100644 index 00000000000000..15939e6581737b --- /dev/null +++ b/examples/lock-app/cc13x4_26x4/src/AppTask.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * 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 +#include + +#include "FreeRTOS.h" +#include "semphr.h" +#include "task.h" + +#include "AppEvent.h" +#include "LockManager.h" + +#include + +// Application-defined error codes in the CHIP_ERROR space. +#define APP_ERROR_EVENT_QUEUE_FAILED CHIP_APPLICATION_ERROR(0x01) +#define APP_ERROR_CREATE_TASK_FAILED CHIP_APPLICATION_ERROR(0x02) +#define APP_ERROR_UNHANDLED_EVENT CHIP_APPLICATION_ERROR(0x03) +#define APP_ERROR_CREATE_TIMER_FAILED CHIP_APPLICATION_ERROR(0x04) +#define APP_ERROR_START_TIMER_FAILED CHIP_APPLICATION_ERROR(0x05) +#define APP_ERROR_STOP_TIMER_FAILED CHIP_APPLICATION_ERROR(0x06) +#define APP_ERROR_ALLOCATION_FAILED CHIP_APPLICATION_ERROR(0x07) + +struct Identify; + +class AppTask +{ + +public: + int StartAppTask(); + static void AppTaskMain(void * pvParameter); + + void PostLockActionRequest(int32_t aActor, LockManager::Action_t aAction); + void PostEvent(const AppEvent * event); + + static void IdentifyStartHandler(::Identify *); + static void IdentifyStopHandler(::Identify *); + static void TriggerIdentifyEffectHandler(::Identify * identify); + +private: + friend AppTask & GetAppTask(void); + + int Init(); + + // should this be done by BoltLock Manager? I don't want to unravel this spaghetti quite yet + static void ActionInitiated(LockManager::Action_t aAction); + static void ActionCompleted(LockManager::Action_t aAction); + + void DispatchEvent(AppEvent * event); + + static void ButtonLeftEventHandler(Button_Handle handle, Button_EventMask events); + static void ButtonRightEventHandler(Button_Handle handle, Button_EventMask events); + static void TimerEventHandler(void * p_context); + + enum Function_t + { + kFunction_NoneSelected = 0, + kFunction_SoftwareUpdate = 0, + kFunction_FactoryReset, + + kFunction_Invalid + } Function; + + Function_t mFunction; + bool mFunctionTimerActive; + bool mSyncClusterToButtonAction; + + static AppTask sAppTask; +}; + +inline AppTask & GetAppTask(void) +{ + return AppTask::sAppTask; +} diff --git a/examples/lock-app/cc13x4_26x4/src/LockManager.cpp b/examples/lock-app/cc13x4_26x4/src/LockManager.cpp new file mode 100644 index 00000000000000..acd9c00b41c4d5 --- /dev/null +++ b/examples/lock-app/cc13x4_26x4/src/LockManager.cpp @@ -0,0 +1,703 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * 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 "LockManager.h" + +#include "AppConfig.h" +#include "AppTask.h" +#include "platform/KeyValueStoreManager.h" +#include +#include +#include +#include + +LockManager LockManager::sLock; + +TimerHandle_t sLockTimer; + +using namespace CC13X2_26X2DoorLock::LockInitParams; +using namespace chip::DeviceLayer::PersistedStorage; + +// persisted storage keys +const char LockUser[] = "a/lu"; +const char Credential[] = "a/c"; +const char LockUserName[] = "a/lun"; +const char CredentialData[] = "a/cd"; +const char UserCredentials[] = "a/uc"; +const char WeekDaySchedules[] = "a/wds"; +const char YearDaySchedules[] = "a/yds"; +const char HolidaySchedules[] = "a/hs"; + +CHIP_ERROR LockManager::Init(chip::app::DataModel::Nullable state, LockParam lockParam) +{ + + LockParams = lockParam; + + if (LockParams.numberOfUsers > kMaxUsers) + { + PLAT_LOG("Max number of users is greater than %d, the maximum amount of users currently supported on this platform", + kMaxUsers); + return APP_ERROR_ALLOCATION_FAILED; + } + + if (LockParams.numberOfCredentialsPerUser > kMaxCredentialsPerUser) + { + PLAT_LOG("Max number of credentials per user is greater than %d, the maximum amount of users currently supported on this " + "platform", + kMaxCredentialsPerUser); + return APP_ERROR_ALLOCATION_FAILED; + } + + if (LockParams.numberOfWeekdaySchedulesPerUser > kMaxWeekdaySchedulesPerUser) + { + PLAT_LOG("Max number of schedules is greater than %d, the maximum amount of schedules currently supported on this platform", + kMaxWeekdaySchedulesPerUser); + return APP_ERROR_ALLOCATION_FAILED; + } + + if (LockParams.numberOfYeardaySchedulesPerUser > kMaxYeardaySchedulesPerUser) + { + PLAT_LOG("Max number of schedules is greater than %d, the maximum amount of schedules currently supported on this platform", + kMaxYeardaySchedulesPerUser); + return APP_ERROR_ALLOCATION_FAILED; + } + + if (LockParams.numberOfHolidaySchedules > kMaxHolidaySchedules) + { + PLAT_LOG("Max number of schedules is greater than %d, the maximum amount of schedules currently supported on this platform", + kMaxHolidaySchedules); + return APP_ERROR_ALLOCATION_FAILED; + } + + // Create FreeRTOS sw timer for lock timer. + sLockTimer = xTimerCreate("lockTmr", // Just a text name, not used by the RTOS kernel + 1, // == default timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = lock obj context + TimerEventHandler // timer callback handler + ); + + if (sLockTimer == NULL) + { + PLAT_LOG("sLockTimer timer create failed"); + return APP_ERROR_CREATE_TIMER_FAILED; + } + + if (state.Value() == DlLockState::kUnlocked) + { + mState = kState_UnlockCompleted; + } + else + { + mState = kState_LockCompleted; + } + + return CHIP_NO_ERROR; +} + +bool LockManager::IsValidUserIndex(uint16_t userIndex) +{ + return (userIndex < kMaxUsers); +} + +bool LockManager::IsValidCredentialIndex(uint16_t credentialIndex, CredentialTypeEnum type) +{ + if (CredentialTypeEnum::kProgrammingPIN == type) + { + return (0 == credentialIndex); // 0 is required index for Programming PIN + } + return (credentialIndex < kMaxCredentialsPerUser); +} + +bool LockManager::IsValidWeekdayScheduleIndex(uint8_t scheduleIndex) +{ + return (scheduleIndex < kMaxWeekdaySchedulesPerUser); +} + +bool LockManager::IsValidYeardayScheduleIndex(uint8_t scheduleIndex) +{ + return (scheduleIndex < kMaxYeardaySchedulesPerUser); +} + +bool LockManager::IsValidHolidayScheduleIndex(uint8_t scheduleIndex) +{ + return (scheduleIndex < kMaxHolidaySchedules); +} + +bool LockManager::ReadConfigValues() +{ + size_t outLen; + KeyValueStoreMgr().Get(LockUser, reinterpret_cast(&mLockUsers), + sizeof(EmberAfPluginDoorLockUserInfo) * ArraySize(mLockUsers), &outLen); + + KeyValueStoreMgr().Get(Credential, reinterpret_cast(&mLockCredentials), + sizeof(EmberAfPluginDoorLockCredentialInfo) * ArraySize(mLockCredentials), &outLen); + + KeyValueStoreMgr().Get(LockUserName, reinterpret_cast(mUserNames), sizeof(mUserNames), &outLen); + + KeyValueStoreMgr().Get(CredentialData, reinterpret_cast(mCredentialData), sizeof(mCredentialData), &outLen); + + KeyValueStoreMgr().Get(UserCredentials, reinterpret_cast(mCredentials), + sizeof(CredentialStruct) * LockParams.numberOfUsers * LockParams.numberOfCredentialsPerUser, &outLen); + + KeyValueStoreMgr().Get(WeekDaySchedules, reinterpret_cast(mWeekdaySchedule), + sizeof(EmberAfPluginDoorLockWeekDaySchedule) * LockParams.numberOfWeekdaySchedulesPerUser * + LockParams.numberOfUsers, + &outLen); + + KeyValueStoreMgr().Get(YearDaySchedules, reinterpret_cast(mYeardaySchedule), + sizeof(EmberAfPluginDoorLockYearDaySchedule) * LockParams.numberOfYeardaySchedulesPerUser * + LockParams.numberOfUsers, + &outLen); + + KeyValueStoreMgr().Get(HolidaySchedules, reinterpret_cast(&(mHolidaySchedule)), + sizeof(EmberAfPluginDoorLockHolidaySchedule) * LockParams.numberOfHolidaySchedules, &outLen); + + return true; +} + +void LockManager::SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB) +{ + mActionInitiated_CB = aActionInitiated_CB; + mActionCompleted_CB = aActionCompleted_CB; +} + +bool LockManager::InitiateAction(Action_t aAction) +{ + bool action_initiated = false; + State_t new_state; + + // Initiate Turn Lock/Unlock Action only when the previous one is complete. + if (mState == kState_LockCompleted && aAction == UNLOCK_ACTION) + { + action_initiated = true; + + new_state = kState_UnlockInitiated; + } + else if (mState == kState_UnlockCompleted && aAction == LOCK_ACTION) + { + action_initiated = true; + + new_state = kState_LockInitiated; + } + + if (action_initiated) + { + + StartTimer(ACTUATOR_MOVEMENT_PERIOD_MS); + + // Since the timer started successfully, update the state and trigger callback + mState = new_state; + + if (mActionInitiated_CB) + { + mActionInitiated_CB(aAction); + } + } + + return action_initiated; +} + +void LockManager::StartTimer(uint32_t aTimeoutMs) +{ + if (xTimerIsTimerActive(sLockTimer)) + { + PLAT_LOG("app timer already started!"); + CancelTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sLockTimer, pdMS_TO_TICKS(aTimeoutMs), 100) != pdPASS) + { + PLAT_LOG("sLockTimer timer start() failed"); + } +} + +void LockManager::CancelTimer(void) +{ + if (xTimerStop(sLockTimer, 0) == pdFAIL) + { + PLAT_LOG("sLockTimer stop() failed"); + } +} + +void LockManager::TimerEventHandler(TimerHandle_t xTimer) +{ + // Get lock obj context from timer id. + LockManager * lock = static_cast(pvTimerGetTimerID(xTimer)); + + // The timer event handler will be called in the context of the timer task + // once sLockTimer expires. Post an event to apptask queue with the actual handler + // so that the event can be handled in the context of the apptask. + AppEvent event; + event.Type = AppEvent::kEventType_AppEvent; + event.BoltLockEvent.Context = lock; + event.Handler = ActuatorMovementTimerEventHandler; + GetAppTask().PostEvent(&event); +} + +void LockManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent) +{ + Action_t actionCompleted = INVALID_ACTION; + + LockManager * lock = static_cast(aEvent->BoltLockEvent.Context); + + if (lock->mState == kState_LockInitiated) + { + lock->mState = kState_LockCompleted; + actionCompleted = LOCK_ACTION; + DoorLockServer::Instance().SetLockState(1, DlLockState::kLocked); + } + else if (lock->mState == kState_UnlockInitiated) + { + lock->mState = kState_UnlockCompleted; + actionCompleted = UNLOCK_ACTION; + DoorLockServer::Instance().SetLockState(1, DlLockState::kUnlocked); + } + + if (actionCompleted != INVALID_ACTION) + { + if (lock->mActionCompleted_CB) + { + lock->mActionCompleted_CB(actionCompleted); + } + } +} + +bool LockManager::Lock(chip::EndpointId endpointId, const Optional & pin, OperationErrorEnum & err) +{ + return checkPin(endpointId, DlLockState::kLocked, pin, err); +} + +bool LockManager::Unlock(chip::EndpointId endpointId, const Optional & pin, OperationErrorEnum & err) +{ + return checkPin(endpointId, DlLockState::kUnlocked, pin, err); +} + +bool LockManager::GetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user) +{ + VerifyOrReturnValue(userIndex > 0, false); // indices are one-indexed + + userIndex--; + + VerifyOrReturnValue(IsValidUserIndex(userIndex), false); + + ChipLogProgress(Zcl, "Door Lock App: LockManager::GetUser [endpoint=%d,userIndex=%hu]", endpointId, userIndex); + + const auto & userInDb = mLockUsers[userIndex]; + + user.userStatus = userInDb.userStatus; + if (UserStatusEnum::kAvailable == user.userStatus) + { + ChipLogDetail(Zcl, "Found unoccupied user [endpoint=%d]", endpointId); + return true; + } + + user.userName = chip::CharSpan(userInDb.userName.data(), userInDb.userName.size()); + user.credentials = chip::Span(mCredentials[userIndex], userInDb.credentials.size()); + user.userUniqueId = userInDb.userUniqueId; + user.userType = userInDb.userType; + user.credentialRule = userInDb.credentialRule; + // So far there's no way to actually create the credential outside Matter, so here we always set the creation/modification + // source to Matter + user.creationSource = DlAssetSource::kMatterIM; + user.createdBy = userInDb.createdBy; + user.modificationSource = DlAssetSource::kMatterIM; + user.lastModifiedBy = userInDb.lastModifiedBy; + + ChipLogDetail(Zcl, + "Found occupied user " + "[endpoint=%d,name=\"%.*s\",credentialsCount=%u,uniqueId=%lx,type=%u,credentialRule=%u," + "createdBy=%d,lastModifiedBy=%d]", + endpointId, static_cast(user.userName.size()), user.userName.data(), user.credentials.size(), + user.userUniqueId, to_underlying(user.userType), to_underlying(user.credentialRule), user.createdBy, + user.lastModifiedBy); + + return true; +} + +bool LockManager::SetUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator, chip::FabricIndex modifier, + const chip::CharSpan & userName, uint32_t uniqueId, UserStatusEnum userStatus, UserTypeEnum usertype, + CredentialRuleEnum credentialRule, const CredentialStruct * credentials, size_t totalCredentials) +{ + ChipLogProgress(Zcl, + "Door Lock App: LockManager::SetUser " + "[endpoint=%d,userIndex=%d,creator=%d,modifier=%d,userName=%s,uniqueId=%ld " + "userStatus=%u,userType=%u,credentialRule=%u,credentials=%p,totalCredentials=%u]", + endpointId, userIndex, creator, modifier, userName.data(), uniqueId, to_underlying(userStatus), + to_underlying(usertype), to_underlying(credentialRule), credentials, totalCredentials); + + VerifyOrReturnValue(userIndex > 0, false); // indices are one-indexed + + userIndex--; + + VerifyOrReturnValue(IsValidUserIndex(userIndex), false); + + auto & userInStorage = mLockUsers[userIndex]; + + if (userName.size() > DOOR_LOCK_MAX_USER_NAME_SIZE) + { + ChipLogError(Zcl, "Cannot set user - user name is too long [endpoint=%d,index=%d]", endpointId, userIndex); + return false; + } + + if (totalCredentials > LockParams.numberOfCredentialsPerUser) + { + ChipLogError(Zcl, "Cannot set user - total number of credentials is too big [endpoint=%d,index=%d,totalCredentials=%u]", + endpointId, userIndex, totalCredentials); + return false; + } + + chip::Platform::CopyString(mUserNames[userIndex], userName); + userInStorage.userName = chip::CharSpan(mUserNames[userIndex], userName.size()); + userInStorage.userUniqueId = uniqueId; + userInStorage.userStatus = userStatus; + userInStorage.userType = usertype; + userInStorage.credentialRule = credentialRule; + userInStorage.lastModifiedBy = modifier; + userInStorage.createdBy = creator; + + for (size_t i = 0; i < totalCredentials; ++i) + { + mCredentials[userIndex][i] = credentials[i]; + mCredentials[userIndex][i].credentialType = CredentialTypeEnum::kPin; + mCredentials[userIndex][i].credentialIndex = i + 1; + } + + userInStorage.credentials = chip::Span(mCredentials[userIndex], totalCredentials); + + // Save user information in NVM flash + KeyValueStoreMgr().Put(LockUser, reinterpret_cast(&mLockUsers), + sizeof(EmberAfPluginDoorLockUserInfo) * LockParams.numberOfUsers); + + KeyValueStoreMgr().Put(UserCredentials, reinterpret_cast(mCredentials), + sizeof(CredentialStruct) * LockParams.numberOfUsers * LockParams.numberOfCredentialsPerUser); + + KeyValueStoreMgr().Put(LockUserName, reinterpret_cast(mUserNames), sizeof(mUserNames)); + + ChipLogProgress(Zcl, "Successfully set the user [mEndpointId=%d,index=%d]", endpointId, userIndex); + + return true; +} + +bool LockManager::GetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, CredentialTypeEnum credentialType, + EmberAfPluginDoorLockCredentialInfo & credential) +{ + + if (CredentialTypeEnum::kProgrammingPIN == credentialType) + { + VerifyOrReturnValue(IsValidCredentialIndex(credentialIndex, credentialType), + false); // programming pin index is only index allowed to contain 0 + } + else + { + VerifyOrReturnValue(IsValidCredentialIndex(--credentialIndex, credentialType), false); // otherwise, indices are one-indexed + } + + ChipLogProgress(Zcl, "Lock App: LockManager::GetCredential [credentialType=%u], credentialIndex=%d", + to_underlying(credentialType), credentialIndex); + + const auto & credentialInStorage = mLockCredentials[credentialIndex]; + + credential.status = credentialInStorage.status; + ChipLogDetail(Zcl, "CredentialStatus: %d, CredentialIndex: %d ", (int) credential.status, credentialIndex); + + if (DlCredentialStatus::kAvailable == credential.status) + { + ChipLogDetail(Zcl, "Found unoccupied credential "); + return true; + } + credential.credentialType = credentialInStorage.credentialType; + credential.credentialData = credentialInStorage.credentialData; + credential.createdBy = credentialInStorage.createdBy; + credential.lastModifiedBy = credentialInStorage.lastModifiedBy; + // So far there's no way to actually create the credential outside Matter, so here we always set the creation/modification + // source to Matter + credential.creationSource = DlAssetSource::kMatterIM; + credential.modificationSource = DlAssetSource::kMatterIM; + + ChipLogDetail(Zcl, "Found occupied credential [type=%u,dataSize=%u]", to_underlying(credential.credentialType), + credential.credentialData.size()); + + return true; +} + +bool LockManager::SetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator, + chip::FabricIndex modifier, DlCredentialStatus credentialStatus, CredentialTypeEnum credentialType, + const chip::ByteSpan & credentialData) +{ + + if (CredentialTypeEnum::kProgrammingPIN == credentialType) + { + VerifyOrReturnValue(IsValidCredentialIndex(credentialIndex, credentialType), + false); // programming pin index is only index allowed to contain 0 + } + else + { + VerifyOrReturnValue(IsValidCredentialIndex(--credentialIndex, credentialType), false); // otherwise, indices are one-indexed + } + + ChipLogProgress(Zcl, + "Door Lock App: LockManager::SetCredential " + "[credentialStatus=%u,credentialType=%u,credentialDataSize=%u,creator=%d,modifier=%d]", + to_underlying(credentialStatus), to_underlying(credentialType), credentialData.size(), creator, modifier); + + auto & credentialInStorage = mLockCredentials[credentialIndex]; + + credentialInStorage.status = credentialStatus; + credentialInStorage.credentialType = credentialType; + credentialInStorage.createdBy = creator; + credentialInStorage.lastModifiedBy = modifier; + + memcpy(mCredentialData[credentialIndex], credentialData.data(), credentialData.size()); + credentialInStorage.credentialData = chip::ByteSpan{ mCredentialData[credentialIndex], credentialData.size() }; + + // Save credential information in NVM flash + KeyValueStoreMgr().Put(Credential, reinterpret_cast(&mLockCredentials), + sizeof(EmberAfPluginDoorLockCredentialInfo) * LockParams.numberOfCredentialsPerUser); + + KeyValueStoreMgr().Put(CredentialData, reinterpret_cast(&mCredentialData), sizeof(mCredentialData)); + + ChipLogProgress(Zcl, "Successfully set the credential [credentialType=%u]", to_underlying(credentialType)); + + return true; +} + +DlStatus LockManager::GetWeekdaySchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex, + EmberAfPluginDoorLockWeekDaySchedule & schedule) +{ + + VerifyOrReturnValue(weekdayIndex > 0, DlStatus::kFailure); // indices are one-indexed + VerifyOrReturnValue(userIndex > 0, DlStatus::kFailure); // indices are one-indexed + + weekdayIndex--; + userIndex--; + + VerifyOrReturnValue(IsValidWeekdayScheduleIndex(weekdayIndex), DlStatus::kFailure); + VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure); + + const auto & scheduleInStorage = mWeekdaySchedule[userIndex][weekdayIndex]; + if (DlScheduleStatus::kAvailable == scheduleInStorage.status) + { + return DlStatus::kNotFound; + } + + schedule = scheduleInStorage.schedule; + + return DlStatus::kSuccess; +} + +DlStatus LockManager::SetWeekdaySchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex, + DlScheduleStatus status, DaysMaskMap daysMask, uint8_t startHour, uint8_t startMinute, + uint8_t endHour, uint8_t endMinute) +{ + + VerifyOrReturnValue(weekdayIndex > 0, DlStatus::kFailure); // indices are one-indexed + VerifyOrReturnValue(userIndex > 0, DlStatus::kFailure); // indices are one-indexed + + weekdayIndex--; + userIndex--; + + VerifyOrReturnValue(IsValidWeekdayScheduleIndex(weekdayIndex), DlStatus::kFailure); + VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure); + + auto & scheduleInStorage = mWeekdaySchedule[userIndex][weekdayIndex]; + + scheduleInStorage.schedule.daysMask = daysMask; + scheduleInStorage.schedule.startHour = startHour; + scheduleInStorage.schedule.startMinute = startMinute; + scheduleInStorage.schedule.endHour = endHour; + scheduleInStorage.schedule.endMinute = endMinute; + scheduleInStorage.status = status; + + // Save schedule information in NVM flash + KeyValueStoreMgr().Put(WeekDaySchedules, reinterpret_cast(mWeekdaySchedule), + sizeof(EmberAfPluginDoorLockWeekDaySchedule) * LockParams.numberOfWeekdaySchedulesPerUser * + LockParams.numberOfUsers); + + return DlStatus::kSuccess; +} + +DlStatus LockManager::GetYeardaySchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, + EmberAfPluginDoorLockYearDaySchedule & schedule) +{ + VerifyOrReturnValue(yearDayIndex > 0, DlStatus::kFailure); // indices are one-indexed + VerifyOrReturnValue(userIndex > 0, DlStatus::kFailure); // indices are one-indexed + + yearDayIndex--; + userIndex--; + + VerifyOrReturnValue(IsValidYeardayScheduleIndex(yearDayIndex), DlStatus::kFailure); + VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure); + + const auto & scheduleInStorage = mYeardaySchedule[userIndex][yearDayIndex]; + if (DlScheduleStatus::kAvailable == scheduleInStorage.status) + { + return DlStatus::kNotFound; + } + + schedule = scheduleInStorage.schedule; + + return DlStatus::kSuccess; +} + +DlStatus LockManager::SetYeardaySchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, + DlScheduleStatus status, uint32_t localStartTime, uint32_t localEndTime) +{ + VerifyOrReturnValue(yearDayIndex > 0, DlStatus::kFailure); // indices are one-indexed + VerifyOrReturnValue(userIndex > 0, DlStatus::kFailure); // indices are one-indexed + + yearDayIndex--; + userIndex--; + + VerifyOrReturnValue(IsValidYeardayScheduleIndex(yearDayIndex), DlStatus::kFailure); + VerifyOrReturnValue(IsValidUserIndex(userIndex), DlStatus::kFailure); + + auto & scheduleInStorage = mYeardaySchedule[userIndex][yearDayIndex]; + + scheduleInStorage.schedule.localStartTime = localStartTime; + scheduleInStorage.schedule.localEndTime = localEndTime; + scheduleInStorage.status = status; + + // Save schedule information in NVM flash + KeyValueStoreMgr().Put(YearDaySchedules, reinterpret_cast(mYeardaySchedule), + sizeof(EmberAfPluginDoorLockYearDaySchedule) * LockParams.numberOfYeardaySchedulesPerUser * + LockParams.numberOfUsers); + + return DlStatus::kSuccess; +} + +DlStatus LockManager::GetHolidaySchedule(chip::EndpointId endpointId, uint8_t holidayIndex, + EmberAfPluginDoorLockHolidaySchedule & schedule) +{ + VerifyOrReturnValue(holidayIndex > 0, DlStatus::kFailure); // indices are one-indexed + + holidayIndex--; + + VerifyOrReturnValue(IsValidHolidayScheduleIndex(holidayIndex), DlStatus::kFailure); + + const auto & scheduleInStorage = mHolidaySchedule[holidayIndex]; + if (DlScheduleStatus::kAvailable == scheduleInStorage.status) + { + return DlStatus::kNotFound; + } + + schedule = scheduleInStorage.schedule; + + return DlStatus::kSuccess; +} + +DlStatus LockManager::SetHolidaySchedule(chip::EndpointId endpointId, uint8_t holidayIndex, DlScheduleStatus status, + uint32_t localStartTime, uint32_t localEndTime, OperatingModeEnum operatingMode) +{ + VerifyOrReturnValue(holidayIndex > 0, DlStatus::kFailure); // indices are one-indexed + + holidayIndex--; + + VerifyOrReturnValue(IsValidHolidayScheduleIndex(holidayIndex), DlStatus::kFailure); + + auto & scheduleInStorage = mHolidaySchedule[holidayIndex]; + + scheduleInStorage.schedule.localStartTime = localStartTime; + scheduleInStorage.schedule.localEndTime = localEndTime; + scheduleInStorage.schedule.operatingMode = operatingMode; + scheduleInStorage.status = status; + + // Save schedule information in NVM flash + KeyValueStoreMgr().Put(HolidaySchedules, reinterpret_cast(&(mHolidaySchedule)), + sizeof(EmberAfPluginDoorLockHolidaySchedule) * LockParams.numberOfHolidaySchedules); + + return DlStatus::kSuccess; +} + +const char * LockManager::lockStateToString(DlLockState lockState) const +{ + switch (lockState) + { + case DlLockState::kNotFullyLocked: + return "Not Fully Locked"; + case DlLockState::kLocked: + return "Locked"; + case DlLockState::kUnlocked: + return "Unlocked"; + case DlLockState::kUnknownEnumValue: + break; + } + + return "Unknown"; +} + +bool LockManager::checkPin(chip::EndpointId endpointId, DlLockState lockState, const Optional & pin, + OperationErrorEnum & err) +{ + // Assume pin is required until told otherwise + bool requirePin = true; + chip::app::Clusters::DoorLock::Attributes::RequirePINforRemoteOperation::Get(endpointId, &requirePin); + + // If a pin code is not given + if (!pin.HasValue()) + { + ChipLogDetail(Zcl, "Door Lock App: PIN code is not specified [endpointId=%d]", endpointId); + + // If a pin code is not required + if (!requirePin) + { + ChipLogDetail(Zcl, "Door Lock App: setting door lock state to \"%s\" [endpointId=%d]", lockStateToString(lockState), + endpointId); + + return true; + } + + ChipLogError(Zcl, "Door Lock App: PIN code is not specified, but it is required [endpointId=%d]", endpointId); + + err = OperationErrorEnum::kInvalidCredential; + DoorLockServer::Instance().HandleWrongCodeEntry(endpointId); + return false; + } + + // Check the PIN code + for (uint8_t i = 0; i < kMaxCredentials; i++) + { + if (mLockCredentials[i].credentialType != CredentialTypeEnum::kPin || + mLockCredentials[i].status == DlCredentialStatus::kAvailable) + { + continue; + } + + if (mLockCredentials[i].credentialData.data_equal(pin.Value())) + { + ChipLogDetail(Zcl, + "Lock App: specified PIN code was found in the database, setting lock state to \"%s\" [endpointId=%d]", + lockStateToString(lockState), endpointId); + + return true; + } + } + + ChipLogDetail(Zcl, + "Door Lock App: specified PIN code was not found in the database, ignoring command to set lock state to \"%s\" " + "[endpointId=%d]", + lockStateToString(lockState), endpointId); + + err = OperationErrorEnum::kInvalidCredential; + DoorLockServer::Instance().HandleWrongCodeEntry(endpointId); + return false; +} diff --git a/examples/lock-app/cc13x4_26x4/src/LockManager.h b/examples/lock-app/cc13x4_26x4/src/LockManager.h new file mode 100644 index 00000000000000..74129260bd9172 --- /dev/null +++ b/examples/lock-app/cc13x4_26x4/src/LockManager.h @@ -0,0 +1,221 @@ +/* + * + * Copyright (c) 2019 Google LLC. + * 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 + +#include +#include + +#include "AppEvent.h" + +#include "FreeRTOS.h" +#include "timers.h" // provides FreeRTOS timer support + +#include + +struct WeekDaysScheduleInfo +{ + DlScheduleStatus status; + EmberAfPluginDoorLockWeekDaySchedule schedule; +}; + +struct YearDayScheduleInfo +{ + DlScheduleStatus status; + EmberAfPluginDoorLockYearDaySchedule schedule; +}; + +struct HolidayScheduleInfo +{ + DlScheduleStatus status; + EmberAfPluginDoorLockHolidaySchedule schedule; +}; + +namespace CC13X2_26X2DoorLock { +namespace ResourceRanges { +// Used to size arrays +static constexpr uint16_t kMaxUsers = 10; +static constexpr uint8_t kMaxCredentialsPerUser = 10; +static constexpr uint8_t kMaxWeekdaySchedulesPerUser = 10; +static constexpr uint8_t kMaxYeardaySchedulesPerUser = 10; +static constexpr uint8_t kMaxHolidaySchedules = 10; +static constexpr uint8_t kMaxCredentialSize = 8; + +// Indices received for user/credential/schedules are 1-indexed +static constexpr uint8_t kStartIndexValue = 1; + +static constexpr uint8_t kMaxCredentials = kMaxUsers * kMaxCredentialsPerUser; +} // namespace ResourceRanges + +namespace LockInitParams { + +struct LockParam +{ + // Read from zap attributes + uint16_t numberOfUsers = 0; + uint8_t numberOfCredentialsPerUser = 0; + uint8_t numberOfWeekdaySchedulesPerUser = 0; + uint8_t numberOfYeardaySchedulesPerUser = 0; + uint8_t numberOfHolidaySchedules = 0; +}; + +class ParamBuilder +{ +public: + ParamBuilder & SetNumberOfUsers(uint16_t numberOfUsers) + { + lockParam_.numberOfUsers = numberOfUsers; + return *this; + } + ParamBuilder & SetNumberOfCredentialsPerUser(uint8_t numberOfCredentialsPerUser) + { + lockParam_.numberOfCredentialsPerUser = numberOfCredentialsPerUser; + return *this; + } + ParamBuilder & SetNumberOfWeekdaySchedulesPerUser(uint8_t numberOfWeekdaySchedulesPerUser) + { + lockParam_.numberOfWeekdaySchedulesPerUser = numberOfWeekdaySchedulesPerUser; + return *this; + } + ParamBuilder & SetNumberOfYeardaySchedulesPerUser(uint8_t numberOfYeardaySchedulesPerUser) + { + lockParam_.numberOfYeardaySchedulesPerUser = numberOfYeardaySchedulesPerUser; + return *this; + } + ParamBuilder & SetNumberOfHolidaySchedules(uint8_t numberOfHolidaySchedules) + { + lockParam_.numberOfHolidaySchedules = numberOfHolidaySchedules; + return *this; + } + LockParam GetLockParam() { return lockParam_; } + +private: + LockParam lockParam_; +}; + +} // namespace LockInitParams +} // namespace CC13X2_26X2DoorLock + +using namespace ::chip; +using namespace CC13X2_26X2DoorLock::ResourceRanges; + +class LockManager +{ +public: + enum Action_t + { + LOCK_ACTION = 0, + UNLOCK_ACTION, + + INVALID_ACTION + } Action; + + enum State_t + { + kState_LockInitiated = 0, + kState_LockCompleted, + kState_UnlockInitiated, + kState_UnlockCompleted, + } State; + + CHIP_ERROR Init(chip::app::DataModel::Nullable state, + CC13X2_26X2DoorLock::LockInitParams::LockParam lockParam); + bool InitiateAction(Action_t aAction); + + typedef void (*Callback_fn_initiated)(Action_t); + typedef void (*Callback_fn_completed)(Action_t); + void SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB); + + bool Lock(chip::EndpointId endpointId, const Optional & pin, OperationErrorEnum & err); + bool Unlock(chip::EndpointId endpointId, const Optional & pin, OperationErrorEnum & err); + + bool GetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user); + bool SetUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator, chip::FabricIndex modifier, + const chip::CharSpan & userName, uint32_t uniqueId, UserStatusEnum userStatus, UserTypeEnum usertype, + CredentialRuleEnum credentialRule, const CredentialStruct * credentials, size_t totalCredentials); + + bool GetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, CredentialTypeEnum credentialType, + EmberAfPluginDoorLockCredentialInfo & credential); + + bool SetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator, chip::FabricIndex modifier, + DlCredentialStatus credentialStatus, CredentialTypeEnum credentialType, + const chip::ByteSpan & credentialData); + + DlStatus GetWeekdaySchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex, + EmberAfPluginDoorLockWeekDaySchedule & schedule); + + DlStatus SetWeekdaySchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex, DlScheduleStatus status, + DaysMaskMap daysMask, uint8_t startHour, uint8_t startMinute, uint8_t endHour, uint8_t endMinute); + + DlStatus GetYeardaySchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, + EmberAfPluginDoorLockYearDaySchedule & schedule); + + DlStatus SetYeardaySchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, DlScheduleStatus status, + uint32_t localStartTime, uint32_t localEndTime); + + DlStatus GetHolidaySchedule(chip::EndpointId endpointId, uint8_t holidayIndex, EmberAfPluginDoorLockHolidaySchedule & schedule); + + DlStatus SetHolidaySchedule(chip::EndpointId endpointId, uint8_t holidayIndex, DlScheduleStatus status, uint32_t localStartTime, + uint32_t localEndTime, OperatingModeEnum operatingMode); + + bool IsValidUserIndex(uint16_t userIndex); + bool IsValidCredentialIndex(uint16_t credentialIndex, CredentialTypeEnum type); + bool IsValidWeekdayScheduleIndex(uint8_t scheduleIndex); + bool IsValidYeardayScheduleIndex(uint8_t scheduleIndex); + bool IsValidHolidayScheduleIndex(uint8_t scheduleIndex); + + bool checkPin(chip::EndpointId endpointId, DlLockState lockState, const Optional & pin, + OperationErrorEnum & err); + const char * lockStateToString(DlLockState lockState) const; + + bool ReadConfigValues(); + +private: + friend LockManager & LockMgr(); + State_t mState; + + Callback_fn_initiated mActionInitiated_CB; + Callback_fn_completed mActionCompleted_CB; + + void CancelTimer(void); + void StartTimer(uint32_t aTimeoutMs); + + static void TimerEventHandler(TimerHandle_t xTimer); + static void AutoLockTimerEventHandler(AppEvent * aEvent); + static void ActuatorMovementTimerEventHandler(AppEvent * aEvent); + + EmberAfPluginDoorLockUserInfo mLockUsers[kMaxUsers]; + EmberAfPluginDoorLockCredentialInfo mLockCredentials[kMaxCredentials]; + WeekDaysScheduleInfo mWeekdaySchedule[kMaxUsers][kMaxWeekdaySchedulesPerUser]; + YearDayScheduleInfo mYeardaySchedule[kMaxUsers][kMaxYeardaySchedulesPerUser]; + HolidayScheduleInfo mHolidaySchedule[kMaxHolidaySchedules]; + + char mUserNames[ArraySize(mLockUsers)][DOOR_LOCK_MAX_USER_NAME_SIZE]; + uint8_t mCredentialData[kMaxCredentials][kMaxCredentialSize]; + CredentialStruct mCredentials[kMaxUsers][kMaxCredentialsPerUser]; + + static LockManager sLock; + CC13X2_26X2DoorLock::LockInitParams::LockParam LockParams; +}; + +inline LockManager & LockMgr() +{ + return LockManager::sLock; +} diff --git a/examples/lock-app/cc13x4_26x4/src/ZclCallbacks.cpp b/examples/lock-app/cc13x4_26x4/src/ZclCallbacks.cpp new file mode 100644 index 00000000000000..0fb673f020c5c5 --- /dev/null +++ b/examples/lock-app/cc13x4_26x4/src/ZclCallbacks.cpp @@ -0,0 +1,149 @@ +/* + * + * Copyright (c) 2020 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. + */ + +/** + * @file + * This file implements the handler for data model messages. + */ + +#include "AppConfig.h" +#include "LockManager.h" +#include + +#include +#include +#include +#include + +using namespace ::chip::app::Clusters; +using namespace ::chip::DeviceLayer::Internal; + +void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size, + uint8_t * value) +{ + ClusterId clusterId = attributePath.mClusterId; + AttributeId attributeId = attributePath.mAttributeId; + ChipLogProgress(Zcl, "Cluster callback: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); + + if (clusterId == DoorLock::Id && attributeId == DoorLock::Attributes::LockState::Id) + { + ChipLogProgress(Zcl, "Door lock cluster: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); + } +} + +/** @brief DoorLock Cluster Init + * + * This function is called when a specific cluster is initialized. It gives the + * application an opportunity to take care of cluster initialization procedures. + * It is called exactly once for each endpoint where cluster is present. + * + * @param endpoint Ver.: always + * + */ +void emberAfDoorLockClusterInitCallback(EndpointId endpoint) {} + +bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const Optional & pinCode, + OperationErrorEnum & err) +{ + ChipLogProgress(Zcl, "Door Lock App: Lock Command endpoint=%d", endpointId); + bool status = LockMgr().Lock(endpointId, pinCode, err); + if (status == true) + { + LockMgr().InitiateAction(LockManager::LOCK_ACTION); + } + return status; +} + +bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const Optional & pinCode, + OperationErrorEnum & err) +{ + ChipLogProgress(Zcl, "Door Lock App: Unlock Command endpoint=%d", endpointId); + bool status = LockMgr().Unlock(endpointId, pinCode, err); + if (status == true) + { + LockMgr().InitiateAction(LockManager::UNLOCK_ACTION); + } + + return status; +} + +bool emberAfPluginDoorLockGetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, CredentialTypeEnum credentialType, + EmberAfPluginDoorLockCredentialInfo & credential) +{ + return LockMgr().GetCredential(endpointId, credentialIndex, credentialType, credential); +} + +bool emberAfPluginDoorLockSetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator, + chip::FabricIndex modifier, DlCredentialStatus credentialStatus, + CredentialTypeEnum credentialType, const chip::ByteSpan & credentialData) +{ + return LockMgr().SetCredential(endpointId, credentialIndex, creator, modifier, credentialStatus, credentialType, + credentialData); +} + +bool emberAfPluginDoorLockGetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user) +{ + return LockMgr().GetUser(endpointId, userIndex, user); +} + +bool emberAfPluginDoorLockSetUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator, + chip::FabricIndex modifier, const chip::CharSpan & userName, uint32_t uniqueId, + UserStatusEnum userStatus, UserTypeEnum usertype, CredentialRuleEnum credentialRule, + const CredentialStruct * credentials, size_t totalCredentials) +{ + + return LockMgr().SetUser(endpointId, userIndex, creator, modifier, userName, uniqueId, userStatus, usertype, credentialRule, + credentials, totalCredentials); +} + +DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex, + EmberAfPluginDoorLockWeekDaySchedule & schedule) +{ + return LockMgr().GetWeekdaySchedule(endpointId, weekdayIndex, userIndex, schedule); +} + +DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, + EmberAfPluginDoorLockYearDaySchedule & schedule) +{ + return LockMgr().GetYeardaySchedule(endpointId, yearDayIndex, userIndex, schedule); +} + +DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t holidayIndex, + EmberAfPluginDoorLockHolidaySchedule & holidaySchedule) +{ + return LockMgr().GetHolidaySchedule(endpointId, holidayIndex, holidaySchedule); +} + +DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex, + DlScheduleStatus status, DaysMaskMap daysMask, uint8_t startHour, uint8_t startMinute, + uint8_t endHour, uint8_t endMinute) +{ + return LockMgr().SetWeekdaySchedule(endpointId, weekdayIndex, userIndex, status, daysMask, startHour, startMinute, endHour, + endMinute); +} + +DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex, + DlScheduleStatus status, uint32_t localStartTime, uint32_t localEndTime) +{ + return LockMgr().SetYeardaySchedule(endpointId, yearDayIndex, userIndex, status, localStartTime, localEndTime); +} + +DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t holidayIndex, DlScheduleStatus status, + uint32_t localStartTime, uint32_t localEndTime, OperatingModeEnum operatingMode) +{ + return LockMgr().SetHolidaySchedule(endpointId, holidayIndex, status, localStartTime, localEndTime, operatingMode); +} diff --git a/examples/lock-app/cc13x4_26x4/src/main.cpp b/examples/lock-app/cc13x4_26x4/src/main.cpp new file mode 100644 index 00000000000000..6cf27cf79a35fb --- /dev/null +++ b/examples/lock-app/cc13x4_26x4/src/main.cpp @@ -0,0 +1,104 @@ +/* + * + * Copyright (c) 2020 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. + */ + +#include +#include + +#include + +#include "AppConfig.h" +#include "AppTask.h" + +#include + +/* Driver Header files */ +#include +#include +#include + +#include +#include +#include +#include + +#include +#define TOTAL_ICALL_HEAP_SIZE (0xc600) + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::DeviceLayer; + +__attribute__((section(".heap"))) uint8_t GlobalHeapZoneBuffer[TOTAL_ICALL_HEAP_SIZE]; +uint32_t heapSize = TOTAL_ICALL_HEAP_SIZE; + +// ================================================================================ +// FreeRTOS Callbacks +// ================================================================================ +extern "C" void vApplicationStackOverflowHook(void) +{ + while (1) + { + ; + } +} + +/* Wrapper functions for using the queue registry regardless of whether it is enabled or disabled */ +extern "C" void vQueueAddToRegistryWrapper(QueueHandle_t xQueue, const char * pcQueueName) +{ + /* This function is intentionally left empty as the Queue Registry is disabled */ +} + +extern "C" void vQueueUnregisterQueueWrapper(QueueHandle_t xQueue) +{ + /* This function is intentionally left empty as the Queue Registry is disabled */ +} + +// ================================================================================ +// Main Code +// ================================================================================ +int main(void) +{ + Board_init(); + bpool((void *) GlobalHeapZoneBuffer, TOTAL_ICALL_HEAP_SIZE); + + GPIO_init(); + + NVS_init(); + + ECDH_init(); + + ECDSA_init(); + + AESECB_init(); + + SHA2_init(); + + int ret = GetAppTask().StartAppTask(); + if (ret != 0) + { + // can't log until the kernel is started + // PLAT_LOG("GetAppTask().StartAppTask() failed"); + while (1) + ; + } + + vTaskStartScheduler(); + + // Should never get here. + while (1) + ; +} diff --git a/examples/lock-app/cc13x4_26x4/third_party/connectedhomeip b/examples/lock-app/cc13x4_26x4/third_party/connectedhomeip new file mode 120000 index 00000000000000..c866b86874994d --- /dev/null +++ b/examples/lock-app/cc13x4_26x4/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../.. \ No newline at end of file diff --git a/examples/lock-app/cc32xx/main/AppConfig.h b/examples/lock-app/cc32xx/main/AppConfig.h index 8eeee7fb61e3ed..c6977342e5405c 100755 --- a/examples/lock-app/cc32xx/main/AppConfig.h +++ b/examples/lock-app/cc32xx/main/AppConfig.h @@ -1,6 +1,5 @@ /* * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2019 Google LLC. * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/examples/lock-app/cc32xx/main/AppEvent.h b/examples/lock-app/cc32xx/main/AppEvent.h index ad9e93ee3ad1a5..1d1efd369495b6 100755 --- a/examples/lock-app/cc32xx/main/AppEvent.h +++ b/examples/lock-app/cc32xx/main/AppEvent.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018 Nest Labs, Inc. + * Copyright (c) 2021 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/examples/persistent-storage/cc13x2x7_26x2x7/README.md b/examples/persistent-storage/cc13x2x7_26x2x7/README.md index dc97d434c0deea..fc06023b7edb83 100644 --- a/examples/persistent-storage/cc13x2x7_26x2x7/README.md +++ b/examples/persistent-storage/cc13x2x7_26x2x7/README.md @@ -1,11 +1,11 @@ -# Matter CC1352 CC2652 Persistent Storage Example Application +# Matter Persistent Storage Example Application An example test application showing the persistent storage system for [Matter][matter] on the Texas Instruments CC13X2_26X2 family of Wireless MCUs. --- -- [Matter CC1352 CC2652 Persistent Storage Application](#matter-cc1352-cc2652-persistent-storage-example-application) +- [Matter Persistent Storage Application](#matter-persistent-storage-example-application) - [Introduction](#introduction) - [Device UI](#device-ui) - [Building](#building) @@ -64,8 +64,7 @@ guide assumes that the environment is linux based, and recommends Ubuntu 20.04. packaged with the TI SDK. Check the following section for a list of changes needed. -- Download and install [SysConfig][sysconfig] ([recommended - version][sysconfig_recommended]) +- Download and install [SysConfig][sysconfig]. - This may have already been installed with your SimpleLink SDK install. @@ -208,7 +207,11 @@ the session. Select the ELF image to load on the device with the `Browse` button. This file is placed in the `out/debug` folder by this guide and ends with the `*.out` file -extension. +extension. For OTA enabled applications, the standalone image will instead end +with the `*-bim.hex` file extension. This this is a combined image with +application and and `BIM` included. The flag to enable or disable the OTA +feature is determined by "chip_enable_ota_requestor" in the application's +args.gni file. Finally click the `Load Image` button to load the executable image onto the device. You should be able to see the log output over the XDS110 User UART. @@ -235,7 +238,7 @@ terminal emulator to that port to see the output with the following options: For technical support, please consider creating a post on TI's [E2E forum][e2e]. Additionally, we welcome any feedback. -[matter]: https://github.com/project-chip/connectedhomeip +[matter]: https://csa-iot.org/all-solutions/matter/ [ccs]: https://www.ti.com/tool/CCSTUDIO [ccs_after_launch]: https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#after-launch @@ -245,9 +248,8 @@ Additionally, we welcome any feedback. https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-launch [ccs_manual_method]: https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-method -[e2e]: https://e2e.ti.com/support/wireless-connectivity/zigbee-and-thread +[e2e]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum [sysconfig]: https://www.ti.com/tool/SYSCONFIG -[sysconfig_recommended]: - https://software-dl.ti.com/ccs/esd/sysconfig/sysconfig-1.10.0_2163-setup.run [ti_cc13x2_26x2_r7_matter_request]: https://ti.com/chip_sdk [uniflash]: https://www.ti.com/tool/download/UNIFLASH diff --git a/examples/platform/cc13x2_26x2/project_include/OpenThreadConfig.h b/examples/platform/cc13x2_26x2/project_include/OpenThreadConfig.h index 7747508d80bfdb..02f900809aae9b 100644 --- a/examples/platform/cc13x2_26x2/project_include/OpenThreadConfig.h +++ b/examples/platform/cc13x2_26x2/project_include/OpenThreadConfig.h @@ -1,6 +1,7 @@ /* * * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/examples/platform/cc13x4_26x4/BUILD.gn b/examples/platform/cc13x4_26x4/BUILD.gn new file mode 100644 index 00000000000000..42df17a42d0166 --- /dev/null +++ b/examples/platform/cc13x4_26x4/BUILD.gn @@ -0,0 +1,44 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/chip.gni") + +config("chip_examples_project_config") { + include_dirs = [ "project_include" ] +} + +source_set("openthread_core_config_cc13x4_26x4_chip_examples") { + sources = [ "project_include/OpenThreadConfig.h" ] + public_configs = [ ":chip_examples_project_config" ] +} + +config("attestation-credentials-config") { + include_dirs = [ "${chip_root}" ] + + defines = [ "CC13X4_26X4_ATTESTATION_CREDENTIALS" ] +} + +source_set("cc13x4_26x4-attestation-credentials") { + sources = [ + "CC13X4_26X4DeviceAttestationCreds.cpp", + "CC13X4_26X4DeviceAttestationCreds.h", + ] + + public_deps = [ + "${chip_root}/src/credentials", + "${chip_root}/src/platform:platform_base", + ] + + public_configs = [ ":attestation-credentials-config" ] +} diff --git a/examples/platform/cc13x4_26x4/CC13X4_26X4DeviceAttestationCreds.cpp b/examples/platform/cc13x4_26x4/CC13X4_26X4DeviceAttestationCreds.cpp new file mode 100644 index 00000000000000..e07e8c01c88c96 --- /dev/null +++ b/examples/platform/cc13x4_26x4/CC13X4_26X4DeviceAttestationCreds.cpp @@ -0,0 +1,263 @@ +/* + * + * 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. + */ +#include "CC13X4_26X4DeviceAttestationCreds.h" +#include +#include +#include +#include + +extern uint32_t __attestation_credentials_base; + +namespace chip { +namespace Credentials { +namespace CC13X4_26X4 { + +namespace { + +extern "C" { + +extern void cc13x4_26x4Log(const char * aFormat, ...); + +typedef struct +{ + const uint32_t len; + uint8_t const * data; +} data_ptr; + +typedef struct +{ + data_ptr dac_priv_key; + data_ptr dac_pub_key; + data_ptr dac_cert; + data_ptr pai_cert; +} factoryData; + +const uint8_t gDacPrivKey[] = { + 0x50, 0x5a, 0x21, 0x1d, 0xbd, 0xa8, 0x71, 0x33, 0x0d, 0x63, 0x5d, 0xa3, 0xb0, 0x7e, 0xb1, 0xc5, + 0x08, 0x8a, 0x8f, 0xc7, 0x01, 0x24, 0xfb, 0xb3, 0x3e, 0x93, 0xd5, 0x06, 0x05, 0x82, 0xc7, 0xc5, +}; +const uint8_t gDacPubKey[] = { + 0x04, 0xc5, 0x65, 0xfd, 0xad, 0xfd, 0x16, 0xdd, 0x62, 0xe4, 0x3f, 0x19, 0x60, 0xb9, 0x93, 0xbb, 0x57, + 0x2c, 0xfd, 0xd8, 0x1f, 0x6d, 0x71, 0x67, 0x67, 0x1b, 0x77, 0x45, 0xdc, 0xbe, 0x6f, 0x65, 0xaf, 0x66, + 0x5a, 0x1d, 0x93, 0x1c, 0x05, 0xb9, 0xf9, 0xa3, 0xe9, 0x45, 0x66, 0x85, 0x60, 0x2c, 0x05, 0xc6, 0x96, + 0x46, 0xb8, 0xf7, 0x59, 0x98, 0xdb, 0xaa, 0x68, 0x7a, 0x5c, 0x56, 0x49, 0x02, 0xda, +}; +const uint8_t gDacCert[] = { + 0x30, 0x82, 0x01, 0xf7, 0x30, 0x82, 0x01, 0x9d, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x46, 0x88, 0xeb, 0x94, 0xad, 0x32, + 0xb2, 0xe4, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x4d, 0x31, 0x1f, 0x30, 0x1d, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, + 0x65, 0x6e, 0x74, 0x20, 0x50, 0x41, 0x49, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, + 0x02, 0x01, 0x0c, 0x04, 0x46, 0x46, 0x46, 0x31, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, + 0x7c, 0x02, 0x02, 0x0c, 0x04, 0x38, 0x30, 0x30, 0x36, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x36, 0x32, 0x38, 0x31, 0x34, + 0x32, 0x33, 0x34, 0x33, 0x5a, 0x18, 0x0f, 0x39, 0x39, 0x39, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, + 0x5a, 0x30, 0x52, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1b, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, + 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x44, 0x41, 0x43, 0x20, 0x30, 0x30, 0x30, 0x30, 0x31, + 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x01, 0x0c, 0x04, 0x46, 0x46, 0x46, 0x31, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x02, 0x0c, 0x04, 0x38, 0x30, 0x30, + 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, + 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xc5, 0x65, 0xfd, 0xad, 0xfd, 0x16, 0xdd, 0x62, 0xe4, 0x3f, 0x19, 0x60, 0xb9, 0x93, + 0xbb, 0x57, 0x2c, 0xfd, 0xd8, 0x1f, 0x6d, 0x71, 0x67, 0x67, 0x1b, 0x77, 0x45, 0xdc, 0xbe, 0x6f, 0x65, 0xaf, 0x66, 0x5a, 0x1d, + 0x93, 0x1c, 0x05, 0xb9, 0xf9, 0xa3, 0xe9, 0x45, 0x66, 0x85, 0x60, 0x2c, 0x05, 0xc6, 0x96, 0x46, 0xb8, 0xf7, 0x59, 0x98, 0xdb, + 0xaa, 0x68, 0x7a, 0x5c, 0x56, 0x49, 0x02, 0xda, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, + 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, + 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9b, 0x40, 0x60, 0x6f, 0x9e, 0x04, 0x7f, 0xb8, 0x60, 0x78, + 0x8e, 0x3d, 0xc1, 0x12, 0xd7, 0x5e, 0x87, 0x95, 0x77, 0x68, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0x43, 0x34, 0x57, 0x12, 0xba, 0x2c, 0x87, 0xef, 0x25, 0x49, 0x7b, 0x11, 0xd7, 0x98, 0x58, 0x9b, 0x84, 0x35, 0x7f, + 0x88, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x21, 0x00, + 0xb9, 0x28, 0xf9, 0x3e, 0xe3, 0x87, 0xef, 0x3e, 0x00, 0x72, 0x88, 0x22, 0x84, 0xbd, 0x8a, 0xdd, 0x5c, 0xd6, 0xd0, 0x55, 0x81, + 0xbf, 0xcc, 0x55, 0x17, 0xcf, 0x9e, 0x9b, 0xcd, 0xd4, 0x37, 0xda, 0x02, 0x20, 0x10, 0x07, 0x9c, 0xcf, 0x7f, 0x1f, 0x2d, 0xda, + 0x46, 0xac, 0xe9, 0x67, 0xae, 0x5b, 0xe9, 0x66, 0xe7, 0xf2, 0x8a, 0xdf, 0xa0, 0x28, 0xb8, 0xf8, 0x7f, 0x93, 0x9e, 0xd4, 0x15, + 0x8d, 0xc0, 0xf8, +}; + +const uint8_t gPaiCert[] = { + 0x30, 0x82, 0x01, 0xdc, 0x30, 0x82, 0x01, 0x81, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x7f, 0x7e, 0xf3, 0xdb, 0x08, 0xa3, + 0x8f, 0x68, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x30, 0x31, 0x18, 0x30, 0x16, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x41, 0x41, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x01, 0x0c, 0x04, 0x46, 0x46, 0x46, + 0x31, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x36, 0x32, 0x38, 0x31, 0x34, 0x32, 0x33, 0x34, 0x33, 0x5a, 0x18, 0x0f, 0x39, + 0x39, 0x39, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x4d, 0x31, 0x1f, 0x30, 0x1d, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, + 0x65, 0x6e, 0x74, 0x20, 0x50, 0x41, 0x49, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, + 0x02, 0x01, 0x0c, 0x04, 0x46, 0x46, 0x46, 0x31, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, + 0x7c, 0x02, 0x02, 0x0c, 0x04, 0x38, 0x30, 0x30, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, + 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x42, 0x93, 0x55, 0x77, 0x35, 0x35, + 0x15, 0xce, 0xfa, 0x8f, 0x0e, 0x30, 0xe2, 0x34, 0x7e, 0x90, 0xee, 0xd6, 0xfd, 0x51, 0x5b, 0xe8, 0x82, 0xd1, 0xbc, 0xba, 0x74, + 0x83, 0xd7, 0xff, 0x6e, 0xf4, 0xde, 0xdf, 0x98, 0xf7, 0xf7, 0x4f, 0x17, 0x42, 0x1d, 0xe5, 0x45, 0x0c, 0xff, 0xfb, 0x3e, 0x7f, + 0x6d, 0x4f, 0x62, 0x28, 0x53, 0x41, 0x14, 0xfb, 0xb8, 0x5c, 0x2d, 0x52, 0xd1, 0x82, 0xb6, 0x6a, 0xa3, 0x66, 0x30, 0x64, 0x30, + 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0x43, 0x34, 0x57, 0x12, 0xba, 0x2c, 0x87, 0xef, 0x25, 0x49, 0x7b, 0x11, 0xd7, 0x98, 0x58, 0x9b, 0x84, + 0x35, 0x7f, 0x88, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x6a, 0xfd, 0x22, 0x77, 0x1f, + 0x51, 0x1f, 0xec, 0xbf, 0x16, 0x41, 0x97, 0x67, 0x10, 0xdc, 0xdc, 0x31, 0xa1, 0x71, 0x7e, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0xff, 0x25, 0xf1, 0xd1, 0x54, 0xc3, 0x13, + 0x7e, 0x0e, 0x08, 0x6d, 0x82, 0xab, 0x0b, 0x11, 0xb5, 0x66, 0x18, 0x39, 0xb7, 0x12, 0xb1, 0x34, 0x2c, 0x6c, 0xde, 0x94, 0xfb, + 0xe3, 0x18, 0xa9, 0x2b, 0x02, 0x21, 0x00, 0x92, 0xe2, 0x81, 0xf9, 0x8a, 0x2f, 0xcc, 0x14, 0xcd, 0xf4, 0x07, 0x50, 0xd2, 0x80, + 0xd7, 0xdf, 0xea, 0x3f, 0x4d, 0xa4, 0x6f, 0x35, 0x7a, 0xfe, 0xac, 0xb8, 0x9b, 0x26, 0x77, 0x06, 0xd2, 0x8a, +}; + +const factoryData gFactoryData = { + .dac_priv_key = { + .len = sizeof(gDacPrivKey), + .data = gDacPrivKey, + }, + .dac_pub_key = { + .len = sizeof(gDacPubKey), + .data = gDacPubKey, + }, + .dac_cert = { + .len = sizeof(gDacCert), + .data = gDacCert, + }, + .pai_cert = { + .len = sizeof(gPaiCert), + .data = gPaiCert, + }, +}; + +} // extern "C" + +CHIP_ERROR LoadKeypairFromRaw(ByteSpan private_key, ByteSpan public_key, Crypto::P256Keypair & keypair) +{ + Crypto::P256SerializedKeypair serialized_keypair; + ReturnErrorOnFailure(serialized_keypair.SetLength(private_key.size() + public_key.size())); + memcpy(serialized_keypair.Bytes(), public_key.data(), public_key.size()); + memcpy(serialized_keypair.Bytes() + public_key.size(), private_key.data(), private_key.size()); + return keypair.Deserialize(serialized_keypair); +} + +class DeviceAttestationCredsCC13X4_26X4 : public DeviceAttestationCredentialsProvider +{ + +public: + CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & out_buffer) override; + CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override; + CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & out_buffer) override; + CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & out_buffer) override; + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, MutableByteSpan & out_buffer) override; + +private: + factoryData const * mFactoryData = &gFactoryData; +}; + +CHIP_ERROR DeviceAttestationCredsCC13X4_26X4::GetCertificationDeclaration(MutableByteSpan & out_buffer) +{ + //-> format_version = 1 + //-> vendor_id = 0xFFF1 + //-> product_id_array = [ 0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, 0x8008, 0x8009, 0x800A, 0x800B, + // 0x800C, 0x800D, 0x800E, 0x800F, 0x8010, 0x8011, 0x8012, 0x8013, 0x8014, 0x8015, 0x8016, 0x8017, 0x8018, 0x8019, 0x801A, + // 0x801B, 0x801C, 0x801D, 0x801E, 0x801F, 0x8020, 0x8021, 0x8022, 0x8023, 0x8024, 0x8025, 0x8026, 0x8027, 0x8028, 0x8029, + // 0x802A, 0x802B, 0x802C, 0x802D, 0x802E, 0x802F, 0x8030, 0x8031, 0x8032, 0x8033, 0x8034, 0x8035, 0x8036, 0x8037, 0x8038, + // 0x8039, 0x803A, 0x803B, 0x803C, 0x803D, 0x803E, 0x803F, 0x8040, 0x8041, 0x8042, 0x8043, 0x8044, 0x8045, 0x8046, 0x8047, + // 0x8048, 0x8049, 0x804A, 0x804B, 0x804C, 0x804D, 0x804E, 0x804F, 0x8050, 0x8051, 0x8052, 0x8053, 0x8054, 0x8055, 0x8056, + // 0x8057, 0x8058, 0x8059, 0x805A, 0x805B, 0x805C, 0x805D, 0x805E, 0x805F, 0x8060, 0x8061, 0x8062, 0x8063 ] + //-> device_type_id = 0x0016 + //-> certificate_id = "ZIG20142ZB330003-24" + //-> security_level = 0 + //-> security_information = 0 + //-> version_number = 0x2694 + //-> certification_type = 0 + //-> dac_origin_vendor_id is not present + //-> dac_origin_product_id is not present + const uint8_t kCdForAllExamples[] = { + 0x30, 0x82, 0x02, 0x19, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x0a, 0x30, + 0x82, 0x02, 0x06, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, + 0x01, 0x30, 0x82, 0x01, 0x71, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x01, 0x62, + 0x04, 0x82, 0x01, 0x5e, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, 0x05, 0x01, 0x80, + 0x05, 0x02, 0x80, 0x05, 0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, 0x07, 0x80, 0x05, 0x08, + 0x80, 0x05, 0x09, 0x80, 0x05, 0x0a, 0x80, 0x05, 0x0b, 0x80, 0x05, 0x0c, 0x80, 0x05, 0x0d, 0x80, 0x05, 0x0e, 0x80, 0x05, + 0x0f, 0x80, 0x05, 0x10, 0x80, 0x05, 0x11, 0x80, 0x05, 0x12, 0x80, 0x05, 0x13, 0x80, 0x05, 0x14, 0x80, 0x05, 0x15, 0x80, + 0x05, 0x16, 0x80, 0x05, 0x17, 0x80, 0x05, 0x18, 0x80, 0x05, 0x19, 0x80, 0x05, 0x1a, 0x80, 0x05, 0x1b, 0x80, 0x05, 0x1c, + 0x80, 0x05, 0x1d, 0x80, 0x05, 0x1e, 0x80, 0x05, 0x1f, 0x80, 0x05, 0x20, 0x80, 0x05, 0x21, 0x80, 0x05, 0x22, 0x80, 0x05, + 0x23, 0x80, 0x05, 0x24, 0x80, 0x05, 0x25, 0x80, 0x05, 0x26, 0x80, 0x05, 0x27, 0x80, 0x05, 0x28, 0x80, 0x05, 0x29, 0x80, + 0x05, 0x2a, 0x80, 0x05, 0x2b, 0x80, 0x05, 0x2c, 0x80, 0x05, 0x2d, 0x80, 0x05, 0x2e, 0x80, 0x05, 0x2f, 0x80, 0x05, 0x30, + 0x80, 0x05, 0x31, 0x80, 0x05, 0x32, 0x80, 0x05, 0x33, 0x80, 0x05, 0x34, 0x80, 0x05, 0x35, 0x80, 0x05, 0x36, 0x80, 0x05, + 0x37, 0x80, 0x05, 0x38, 0x80, 0x05, 0x39, 0x80, 0x05, 0x3a, 0x80, 0x05, 0x3b, 0x80, 0x05, 0x3c, 0x80, 0x05, 0x3d, 0x80, + 0x05, 0x3e, 0x80, 0x05, 0x3f, 0x80, 0x05, 0x40, 0x80, 0x05, 0x41, 0x80, 0x05, 0x42, 0x80, 0x05, 0x43, 0x80, 0x05, 0x44, + 0x80, 0x05, 0x45, 0x80, 0x05, 0x46, 0x80, 0x05, 0x47, 0x80, 0x05, 0x48, 0x80, 0x05, 0x49, 0x80, 0x05, 0x4a, 0x80, 0x05, + 0x4b, 0x80, 0x05, 0x4c, 0x80, 0x05, 0x4d, 0x80, 0x05, 0x4e, 0x80, 0x05, 0x4f, 0x80, 0x05, 0x50, 0x80, 0x05, 0x51, 0x80, + 0x05, 0x52, 0x80, 0x05, 0x53, 0x80, 0x05, 0x54, 0x80, 0x05, 0x55, 0x80, 0x05, 0x56, 0x80, 0x05, 0x57, 0x80, 0x05, 0x58, + 0x80, 0x05, 0x59, 0x80, 0x05, 0x5a, 0x80, 0x05, 0x5b, 0x80, 0x05, 0x5c, 0x80, 0x05, 0x5d, 0x80, 0x05, 0x5e, 0x80, 0x05, + 0x5f, 0x80, 0x05, 0x60, 0x80, 0x05, 0x61, 0x80, 0x05, 0x62, 0x80, 0x05, 0x63, 0x80, 0x18, 0x24, 0x03, 0x16, 0x2c, 0x04, + 0x13, 0x5a, 0x49, 0x47, 0x32, 0x30, 0x31, 0x34, 0x32, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x34, + 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x94, 0x26, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, 0x01, + 0x03, 0x80, 0x14, 0x62, 0xfa, 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, 0xf5, 0x04, + 0xf3, 0x71, 0x60, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x24, 0xe5, 0xd1, 0xf4, 0x7a, 0x7d, + 0x7b, 0x0d, 0x20, 0x6a, 0x26, 0xef, 0x69, 0x9b, 0x7c, 0x97, 0x57, 0xb7, 0x2d, 0x46, 0x90, 0x89, 0xde, 0x31, 0x92, 0xe6, + 0x78, 0xc7, 0x45, 0xe7, 0xf6, 0x0c, 0x02, 0x21, 0x00, 0xf8, 0xaa, 0x2f, 0xa7, 0x11, 0xfc, 0xb7, 0x9b, 0x97, 0xe3, 0x97, + 0xce, 0xda, 0x66, 0x7b, 0xae, 0x46, 0x4e, 0x2b, 0xd3, 0xff, 0xdf, 0xc3, 0xcc, 0xed, 0x7a, 0xa8, 0xca, 0x5f, 0x4c, 0x1a, + 0x7c, + }; + + return CopySpanToMutableSpan(ByteSpan{ kCdForAllExamples }, out_buffer); +} + +CHIP_ERROR DeviceAttestationCredsCC13X4_26X4::GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) +{ + out_firmware_info_buffer.reduce_size(0); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR DeviceAttestationCredsCC13X4_26X4::GetDeviceAttestationCert(MutableByteSpan & out_buffer) +{ + ReturnErrorCodeIf(out_buffer.size() < mFactoryData->dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); + ReturnErrorCodeIf(!mFactoryData->dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + + return CopySpanToMutableSpan(ByteSpan{ mFactoryData->dac_cert.data, mFactoryData->dac_cert.len }, out_buffer); + return CHIP_NO_ERROR; +} + +CHIP_ERROR DeviceAttestationCredsCC13X4_26X4::GetProductAttestationIntermediateCert(MutableByteSpan & out_buffer) +{ + ReturnErrorCodeIf(out_buffer.size() < mFactoryData->pai_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); + ReturnErrorCodeIf(!mFactoryData->pai_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + + return CopySpanToMutableSpan(ByteSpan{ mFactoryData->pai_cert.data, mFactoryData->pai_cert.len }, out_buffer); +} + +CHIP_ERROR DeviceAttestationCredsCC13X4_26X4::SignWithDeviceAttestationKey(const ByteSpan & message_to_sign, + MutableByteSpan & out_buffer) +{ + Crypto::P256ECDSASignature signature; + Crypto::P256Keypair keypair; + + VerifyOrReturnError(IsSpanUsable(out_buffer), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsSpanUsable(message_to_sign), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(out_buffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL); + + // In a non-exemplary implementation, the public key is not needed here. It is used here merely because + // Crypto::P256Keypair is only (currently) constructable from raw keys if both private/public keys are present. + ReturnErrorOnFailure(LoadKeypairFromRaw(ByteSpan(mFactoryData->dac_priv_key.data, mFactoryData->dac_priv_key.len), + ByteSpan(mFactoryData->dac_pub_key.data, mFactoryData->dac_pub_key.len), keypair)); + ReturnErrorOnFailure(keypair.ECDSA_sign_msg(message_to_sign.data(), message_to_sign.size(), signature)); + + return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, out_buffer); +} + +} // namespace + +DeviceAttestationCredentialsProvider * GetCC13X4_26X4DacProvider() +{ + static DeviceAttestationCredsCC13X4_26X4 dac_provider; + return &dac_provider; +} + +} // namespace CC13X4_26X4 +} // namespace Credentials +} // namespace chip diff --git a/examples/platform/cc13x4_26x4/CC13X4_26X4DeviceAttestationCreds.h b/examples/platform/cc13x4_26x4/CC13X4_26X4DeviceAttestationCreds.h new file mode 100644 index 00000000000000..9a99099ab09037 --- /dev/null +++ b/examples/platform/cc13x4_26x4/CC13X4_26X4DeviceAttestationCreds.h @@ -0,0 +1,36 @@ +/* + * + * 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. + */ +#pragma once + +#include + +namespace chip { +namespace Credentials { +namespace CC13X4_26X4 { + +/** + * @brief Get implementation of a sample DAC provider to validate device + * attestation procedure. + * + * @returns a singleton DeviceAttestationCredentialsProvider that relies on no + * storage abstractions. + */ +DeviceAttestationCredentialsProvider * GetCC13X4_26X4DacProvider(); + +} // namespace CC13X4_26X4 +} // namespace Credentials +} // namespace chip diff --git a/examples/platform/cc13x4_26x4/args.gni b/examples/platform/cc13x4_26x4/args.gni new file mode 100644 index 00000000000000..8ce3d8cfe73a61 --- /dev/null +++ b/examples/platform/cc13x4_26x4/args.gni @@ -0,0 +1,27 @@ +# 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. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +import("${chip_root}/src/platform/cc13xx_26xx/cc13x4_26x4/args.gni") + +openthread_config_file = "" +openthread_core_config_deps = [ "${chip_root}/examples/platform/cc13x4_26x4:openthread_core_config_cc13x4_26x4_chip_examples" ] + +chip_ble_project_config_include = "" +chip_device_project_config_include = "" +chip_project_config_include = "" +chip_inet_project_config_include = "" +chip_system_project_config_include = "" diff --git a/examples/platform/cc13x4_26x4/project_include/OpenThreadConfig.h b/examples/platform/cc13x4_26x4/project_include/OpenThreadConfig.h new file mode 100644 index 00000000000000..e61b5a3a5ac7a9 --- /dev/null +++ b/examples/platform/cc13x4_26x4/project_include/OpenThreadConfig.h @@ -0,0 +1,99 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * 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 + * Overrides to default OpenThread configuration. + * + */ + +#pragma once + +#ifdef DeviceFamily_CC13X4_CC26X4 + +/* Number of message buffers reduced to fit into CC26x2x3 RAM */ +#define OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS 22 + +#endif // DeviceFamily_CC13X4_CC26X4 + +#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_APP + +// When operating in a less than ideal RF environment, having a more forgiving configuration +// of OpenThread makes thread a great deal more reliable. +#define OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_MAX_RETRY_DELAY 120 // default is 28800 +#define OPENTHREAD_CONFIG_MAC_DEFAULT_MAX_FRAME_RETRIES_DIRECT 15 // default is 3 +#define OPENTHREAD_CONFIG_MAC_DEFAULT_MAX_FRAME_RETRIES_INDIRECT 1 // default is 0 +#define OPENTHREAD_CONFIG_MAC_MAX_TX_ATTEMPTS_INDIRECT_POLLS 16 // default is 4 + +// Enable periodic parent search to speed up finding a better parent. +#define OPENTHREAD_CONFIG_PARENT_SEARCH_ENABLE 1 // default is 0 +#define OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_THRESHOLD -45 // default is -65 +#define OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH 1 // default is 0 + +// Use smaller maximum interval to speed up reattaching. +#define OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_MAXIMUM_INTERVAL (60 * 10 * 1000) // default 1200000 ms + +#define OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE 1 +//#define OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE 0 +#define UART_AS_SERIAL_TRANSPORT 1 +#define OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE 1 + +#define OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE 1 +#define OPENTHREAD_CONFIG_ECDSA_ENABLE 1 +#define OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE 1 +#define OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE 1 +#define OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE 1 + +#define OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE 0 +#define OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE 0 +#define OPENTHREAD_CONFIG_COMMISSIONER_ENABLE 0 +#define OPENTHREAD_CONFIG_JOINER_ENABLE 0 + +#define OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS 0 +// TCP disabled until OpenThread has a GN/Ninja build for the tcplp library +#define OPENTHREAD_CONFIG_TCP_ENABLE 0 + +#define OPENTHREAD_CONFIG_THREAD_VERSION OT_THREAD_VERSION_1_3 + +//#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 1 +//#define OPENTHREAD_CONFIG_COAP_API_ENABLE 1 +#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 0 +#define OPENTHREAD_CONFIG_COAP_API_ENABLE 0 +#define OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE 0 +#define OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE 0 +#define OPENTHREAD_CONFIG_DIAG_ENABLE 0 +#define OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE 0 +#define OPENTHREAD_CONFIG_DUA_ENABLE 1 +#define OPENTHREAD_CONFIG_LINK_RAW_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_FILTER_ENABLE 0 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1 +#define OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE 1 +#define OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 1 +#define OPENTHREAD_CONFIG_MLR_ENABLE 1 +#define OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE 1 +#define OPENTHREAD_CONFIG_SRP_CLIENT_AUTO_START_DEFAULT_MODE 1 +#define OPENTHREAD_CONFIG_SRP_SERVER_ENABLE 0 +#define OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 1 + +// Use the TI-supplied default platform configuration for remainder +#include "openthread-core-cc13xx_cc26xx-config.h" diff --git a/examples/pump-app/cc13x2x7_26x2x7/README.md b/examples/pump-app/cc13x2x7_26x2x7/README.md index cb425e13f45dbc..d3d53d87e7634b 100644 --- a/examples/pump-app/cc13x2x7_26x2x7/README.md +++ b/examples/pump-app/cc13x2x7_26x2x7/README.md @@ -1,33 +1,29 @@ -# Matter CC1352 CC2652 Pump Example Application +# Matter Pump Example Application An example application showing the use of [Matter][matter] on the Texas Instruments CC13XX_26XX family of Wireless MCUs. --- -- [Matter CC1352 CC2652 Pump Example Application](#matter-cc1352-cc2652-pump-example-application) +- [Matter Pump Example Application](#matter-pump-example-application) - [Introduction](#introduction) - [Device UI](#device-ui) - [Building](#building) - [Preparation](#preparation) - [Compilation](#compilation) - [Programming](#programming) - - [UniFlash](#uniflash) - [Code Composer Studio](#code-composer-studio) - - [Viewing Logging Output](#viewing-logging-output) + - [UniFlash](#uniflash) - [Running the Example](#running-the-example) - [Provisioning](#provisioning) - [Bluetooth LE Advertising](#bluetooth-le-advertising) - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) - - [Matter Remote Commands](#matter-remote-commands) - [TI Support](#ti-support) --- ## Introduction -![CC1352R1_LAUNCHXL](doc/images/cc1352r1_launchxl.jpg) - The CC13XX_26XX pump example application provides a working demonstration of a connected pump device. This uses the open-source Matter implementation and the Texas Instruments SimpleLinkā„¢ CC13XX and CC26XX software development kit. @@ -40,20 +36,14 @@ Instruments devices. ## Device UI -This example application has a simple User Interface to depict the state of the -pump and to control the state. The user LEDs on the LaunchPad are set on when -the pump is started, and are set off when stopped. The LEDs will flash when in -the transition state between started and stopped. - -Short presses (less than 1000ms) of the right user button (`BTN-2`) are used for -toggling the pump state. - -Short presses (less than 1000ms) of the left user button (`BTN-1`) are used for -toggling Matter BLE advertisements. - -Long presses (greater than 5000ms) of the left user button (`BTN-1`) will -initiate a factory reset of the device clearing all stored provisioning -information to allow for a new network setup. +| Action | Functionality | +| ------------------------------------------------ | -------------------------------------- | +| Left Button (`BTN-1`) Press (less than 1000 ms) | BLE Advertisement (Enable/Disable) | +| Left Button (`BTN-1`) Press (more than 5000 ms) | Factory Reset | +| Right Button (`BTN-2`) Press (less than 1000 ms) | Toggle pump state | +| Red & Green LED Blinking State | Pump transition from either Start/Stop | +| Red & Green LED On State | Pump is started | +| Red & Green LED Off State | Pump stopped | ## Building @@ -63,15 +53,14 @@ Some initial setup is necessary for preparing the build environment. This section will need to be done when migrating to new versions of the SDK. This guide assumes that the environment is linux based, and recommends Ubuntu 20.04. -- Download and install [SysConfig][sysconfig] ([recommended - version][sysconfig_recommended]). This can be done simply with the following - commands. +- Download and install [SysConfig][sysconfig]. This can be done simply with + the following commands. ``` $ cd ~ - $ wget https://software-dl.ti.com/ccs/esd/sysconfig/sysconfig-1.11.0_2225-setup.run - $ chmod +x sysconfig-1.11.0_2225-setup.run - $ ./sysconfig-1.11.0_2225-setup.run + $ `wget https://dr-download.ti.com/software-development/ide-configuration-compiler-or-debugger/MD-nsUM6f7Vvb/1.15.0.2826/sysconfig-1.15.0_2826-setup.run` + $ chmod +x sysconfig-1.15.0_2826-setup.run + $ ./sysconfig-1.15.0_2826-setup.run ``` - Run the bootstrap script to setup the build environment. @@ -98,32 +87,95 @@ Ninja to build the executable. - Run the build to produce a default executable. By default on Linux both the TI SimpleLink SDK and Sysconfig are located in a `ti` folder in the user's home directory, and you must provide the absolute path to them. For example - `/home/username/ti/sysconfig_1.11.0`. On Windows the default directory is + `/home/username/ti/sysconfig_1.15.0`. On Windows the default directory is `C:\ti`. Take note of this install path, as it will be used in the next step. ``` $ cd ~/connectedhomeip/examples/pump-app/cc13x2x7_26x2x7 - $ gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.11.0\"" + OR + $ cd ~/connectedhomeip/examples/pump-app/cc13x4_26x4 + $ gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\"" $ ninja -C out/debug ``` + If you would like to define arguments on the command line you may add them + to the GN call. + + ``` + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\" target_defines=[\"CC13X2_26X2_ATTESTATION_CREDENTIALS=1\"]" + ``` + ## Programming Loading the built image onto a LaunchPad is supported through two methods; Uniflash and Code Composer Studio (CCS). UniFlash can be used to load the image. Code Composer Studio can be used to load the image and debug the source code. +### Code Composer Studio + +Programming with CCS will allow for a full debug environment within the IDE. +This is accomplished by creating a target connection to the XDS110 debugger and +starting a project-less debug session. The CCS IDE will attempt to find the +source files on the local machine based on the debug information embedded within +the ELF. CCS may prompt you to find the source code if the image was built on +another machine or the source code is located in a different location than is +recorded within the ELF. + +Download and install [Code Composer Studio][ccs]. + +First open CCS and create a new workspace. + +Create a target connection (sometimes called the CCXML) for your target SoC and +debugger as described in the [Manual Method][ccs_manual_method] section of the +CCS User's Guide. + +Next initiate a project-less debug session as described in the [Manual +Launch][ccs_manual_launch] section of the CCS User's Guide. + +CCS should switch to the debug view described in the [After +Launch][ccs_after_launch] section of the User's Guide. The SoC core will likely +be disconnected and symbols will not be loaded. Connect to the core as described +in the [Debug View][ccs_debug_view] section of the User's Guide. Once the core +is connected, use the `Load` button on the toolbar to load the ELF image. + +Note that the default configuration of the CCXML uses 2-wire cJTAG instead of +the full 4-wire JTAG connection to match the default jumper configuration of the +LaunchPad. + ### UniFlash -[Programming UniFlash](doc/programming-uniflash.md) +Uniflash is Texas Instrument's uniform programming tool for embedded processors. +This will allow you to erase, flash, and inspect the SoC without setting up a +debugging environment. -### Code Composer Studio +Download and install [UniFlash][uniflash]. -[Programming and Debugging with CCS](doc/programming-ccs.md) +First open UniFlash. Debug probes connected to the computer will usually be +displayed under the Detected Devices due to the automatic device detection +feature. If your device does not show up in this view it my be disconnected, or +you may have to create a New Configuration. If you already have a CCXML for your +SoC and debug connection you can use that in the section at the bottom. Once +your device is selected, click the `Start` button within the section to launch +the session. -## Viewing Logging Output +Select the ELF image to load on the device with the `Browse` button. This file +is placed in the `out/debug` folder by this guide and ends with the `*.out` file +extension. For OTA enabled applications, the standalone image will instead end +with the `*-bim.hex` file extension. This this is a combined image with +application and and `BIM` included. The flag to enable or disable the OTA +feature is determined by "chip_enable_ota_requestor" in the application's +args.gni file. + +Finally click the `Load Image` button to load the executable image onto the +device. You should be able to see the log output over the XDS110 User UART. + +Note that programming the device through JTAG sets the Halt-in-Boot flag and may +cause issues when performing a software reset. This flag can be reset by +power-cycling the LaunchPad. + +## Running the Example By default the log output will be sent to the Application/User UART. Open a terminal emulator to that port to see the output with the following options: @@ -139,68 +191,120 @@ terminal emulator to that port to see the output with the following options: ## Running the Example Once a device has been flashed with this example, it can now join and operate in -an existing Thread network. The following sections assume that a Thread network +an existing Matter network. The following sections assume that a Matter network is already active, and has at least one [OpenThread Border Router][ot_border_router_setup]. -### Provisioning +For insight into what other components are needed to run this example, please +refer to our [Matter Getting Started Guide][matter-e2e-faq]. -The first step to bring the Matter device onto the network is to provision it. -Our example accomplishes this with Bluetooth Low Energy (BLE) and the -[CHIPTool](../../../examples/android/CHIPTool/README.md) mobile app. +The steps below should be followed to commission the device onto the network and +control it once it has been commissioned. -#### Bluetooth LE Advertising +**Step 0** -To provision this example onto a Thread network, the device must be discoverable -over Bluetooth LE. BLE advertising is started by pressing the right button (less -than 1000ms), labeled `BTN-2` on the silkscreen. Once the device is fully -provisioned, BLE advertising will stop. +Set up the CHIP tool by following the instructions outlined in our [Matter +Getting Started Guide][matter-e2e-faq]. -#### Bluetooth LE Rendezvous +**Step 1** -In this example, the provisioning procedure (called Rendezvous) is done over -Bluetooth LE between a Matter device (pump-app) and the Matter controller -(CHIPTool), where the controller has the commissioner role. +Commission the device onto the Matter network. Run the following command on the +CHIP tool: -To start the rendezvous, the controller must get the commissioning information -from the Matter device. +``` -This is done by scanning a QR code. A URL will be displayed on the pump-app's -log ([UART terminal](#viewing-logging-output)). It will look like the following: +./chip-tool pairing ble-thread hex: 20202021 3840 ``` -SetupQRCode: [MT:.81TM -00 0C9SS0] -Copy/paste the below URL in a browser to see the QR Code: -https://project-chip.github.io/connectedhomeip/qrcode.html?data=CH%3A.81TM%20-00%200C9SS0 + +Interacting with the application begins by enabling BLE advertisements and then +pairing the device into a Thread network. To provision this example onto a +Matter network, the device must be discoverable over Bluetooth LE. + +On the LaunchPad, press and hold the right button, labeled `BTN-1`, for more +than 1 second. Upon release, the Bluetooth LE advertising will begin. Once the +device is fully provisioned, BLE advertising will stop. + +Once the device has been successfully commissioned, you will see the following +message on the CHIP tool output: + +``` + +[1677648218.370754][39785:39790] CHIP:CTL: Received CommissioningComplete response, errorCode=0 +[1677648218.370821][39785:39790] CHIP:CTL: Successfully finished commissioning step 'SendComplete' + +``` + +An accompanying message will be seen from the device: + +``` + +Commissioning complete, notify platform driver to persist network credentials. + +``` + +**Step 2** The pump configuration & control cluster commands have the following +formats: + +``` +./chip-tool pumpconfigurationandcontrol ``` -You can directly navigate to the webpage URL displayed (which has QR payload -pre-loaded). Alternatively, you can navigate to [the QR code -generator][qr_code_generator] and enter in the payload shown in `SetupQRCode` -(in this case `MT:.81TM -00 0C9SS0`). +Send commands to the pump-app. Here are some example commands: -### Matter Remote Commands +Write normal operation mode (0) to device -Once the Matter device is provisioned and operating on the network, CHIPTool can -be used to control the device. During the provisioning process, the Matter -device would have sent one of its newly assigned IPv6 addresses to the CHIPTool. +``` +./chip-tool pumpconfigurationandcontrol write operation-mode 0 1 1 +``` + +Get current operation mode + +``` +./chip-tool pumpconfigurationandcontrol read effective-operation-mode 1 1 +``` + +### Provisioning + +Interacting with the application begins by enabling BLE advertisements and then +pairing the device into a Thread network. + +#### Bluetooth LE Advertising + +To provision this example onto a Thread network, the device must be discoverable +over Bluetooth LE. BLE advertising is started by long pressing the right button +(greater than 1000ms), labeled `BTN-1` on the silkscreen. Once the device is +fully provisioned, BLE advertising will stop. + +#### Bluetooth LE Rendezvous -In the app, you should see an On/Off cluster; this corresponds to the pump-app. -You can now control the pump-app Matter device from the smartphone! +Pairing this application with `ble-thread` can be done with any of the enabled +[CHIP Controller](../../../src/controller/README.md) applications. Use the +information printed on the console to aide in pairing the device. The controller +application can also be used to control the example app with the cluster +commands. ## TI Support For technical support, please consider creating a post on TI's [E2E forum][e2e]. Additionally, we welcome any feedback. -[matter]: https://github.com/project-chip/connectedhomeip -[cc1352r1_launchxl]: https://www.ti.com/tool/LAUNCHXL-CC1352R1 -[e2e]: https://e2e.ti.com/support/wireless-connectivity/zigbee-and-thread +[matter]: https://csa-iot.org/all-solutions/matter/ +[ccs]: https://www.ti.com/tool/CCSTUDIO +[ccs_after_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#after-launch +[ccs_debug_view]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#debug-view +[ccs_manual_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-launch +[ccs_manual_method]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-method +[e2e]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum +[matter-e2e-faq]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/1082428/faq-cc2652r7-matter----getting-started-guide [sysconfig]: https://www.ti.com/tool/SYSCONFIG -[sysconfig_recommended]: - https://software-dl.ti.com/ccs/esd/sysconfig/sysconfig-1.11.0_2225-setup.run [ti_thread_dnd]: https://www.ti.com/wireless-connectivity/thread/design-development.html -[ot_border_router_setup]: - https://openthread.io/guides/border-router/beaglebone-black -[qr_code_generator]: https://project-chip.github.io/connectedhomeip/qrcode.html +[ot_border_router_setup]: https://openthread.io/guides/border-router/build +[uniflash]: https://www.ti.com/tool/download/UNIFLASH diff --git a/examples/pump-app/cc13x4_26x4/.gn b/examples/pump-app/cc13x4_26x4/.gn new file mode 100644 index 00000000000000..3d48789e30ab3d --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/.gn @@ -0,0 +1,28 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/build.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "freertos" + + import("//args.gni") +} diff --git a/examples/pump-app/cc13x4_26x4/BUILD.gn b/examples/pump-app/cc13x4_26x4/BUILD.gn new file mode 100644 index 00000000000000..18865640fb3259 --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/BUILD.gn @@ -0,0 +1,119 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/openthread.gni") +import("//build_overrides/ti_simplelink_sdk.gni") + +import("${build_root}/config/defaults.gni") +import("${chip_root}/src/platform/device.gni") + +import("${ti_simplelink_sdk_build_root}/ti_simplelink_executable.gni") +import("${ti_simplelink_sdk_build_root}/ti_simplelink_sdk.gni") + +assert(current_os == "freertos") + +project_dir = "${chip_root}/examples/pump-app/cc13x4_26x4" + +ti_simplelink_sdk("sdk") { + include_dirs = [ "${project_dir}/main/include" ] + public_configs = [ ":pump_app_config" ] +} + +ti_sysconfig("sysconfig") { + sources = [ "${project_dir}/chip.syscfg" ] + + outputs = [ + "ti_devices_config.c", + "ti_radio_config.c", + "ti_radio_config.h", + "ti_drivers_config.c", + "ti_drivers_config.h", + "ti_ble_config.c", + "ti_ble_config.h", + "ti_dmm_application_policy.c", + "ti_dmm_application_policy.h", + + # disabled until upstream generation is aligned + #"tiop_config.h", + #"tiop_config.c", + + # not traditional source files + #"ti_utils_build_linker.cmd.genlibs", + #"syscfg_c.rov.xs", + #"ti_utils_runtime_model.gv", + #"ti_utils_runtime_Makefile", + #"ti_ble_app_config.opt", + #"ti_build_config.opt", + ] + + public_configs = [ ":sdk_dmm_config" ] + + cflags = [ + "-Wno-comment", + "@" + rebase_path("${target_gen_dir}/sysconfig/ti_ble_app_config.opt", + root_build_dir), + "@" + rebase_path("${target_gen_dir}/sysconfig/ti_build_config.opt", + root_build_dir), + ] +} + +ti_simplelink_executable("pump_app") { + output_name = "chip-${ti_simplelink_board}-pump-example.out" + + sources = [ + "${project_dir}/main/AppTask.cpp", + "${project_dir}/main/CHIPDeviceManager.cpp", + "${project_dir}/main/DeviceCallbacks.cpp", + "${project_dir}/main/PumpManager.cpp", + "${project_dir}/main/ZclCallbacks.cpp", + "${project_dir}/main/main.cpp", + ] + + deps = [ + ":sdk", + ":sysconfig", + "${chip_root}/examples/platform/cc13x4_26x4:cc13x4_26x4-attestation-credentials", + "${chip_root}/examples/pump-app/pump-common", + "${chip_root}/src/lib", + ] + + if (chip_openthread_ftd) { + deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-ftd" ] + } else { + deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-mtd" ] + } + + include_dirs = [ + "${project_dir}", + "${project_dir}/main", + ] + + cflags = [ + "-Wno-implicit-fallthrough", + "-Wno-sign-compare", + "-Wconversion", + ] + + output_dir = root_out_dir +} + +group("cc13x4_26x4") { + deps = [ ":pump_app" ] +} + +group("default") { + deps = [ ":cc13x4_26x4" ] +} diff --git a/examples/pump-app/cc13x4_26x4/README.md b/examples/pump-app/cc13x4_26x4/README.md new file mode 100644 index 00000000000000..08385526ae14d9 --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/README.md @@ -0,0 +1,310 @@ +# Matter Pump Example Application + +An example application showing the use of [Matter][matter] on the Texas +Instruments CC13XX_26XX family of Wireless MCUs. + +--- + +- [Matter Pump Example Application](#matter-pump-example-application) + - [Introduction](#introduction) + - [Device UI](#device-ui) + - [Building](#building) + - [Preparation](#preparation) + - [Compilation](#compilation) + - [Programming](#programming) + - [Code Composer Studio](#code-composer-studio) + - [UniFlash](#uniflash) + - [Running the Example](#running-the-example) + - [Provisioning](#provisioning) + - [Bluetooth LE Advertising](#bluetooth-le-advertising) + - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) + - [TI Support](#ti-support) + +--- + +## Introduction + +The CC13XX_26XX pump example application provides a working demonstration of a +connected pump device. This uses the open-source Matter implementation and the +Texas Instruments SimpleLinkā„¢ CC13XX and CC26XX software development kit. + +This example is enabled to build for CC1354P10 devices. + +The pump example is intended to serve both as a means to explore the workings of +Matter, as well as a template for creating real products based on the Texas +Instruments devices. + +## Device UI + +| Action | Functionality | +| ------------------------------------------------ | -------------------------------------- | +| Left Button (`BTN-1`) Press (less than 1000 ms) | BLE Advertisement (Enable/Disable) | +| Left Button (`BTN-1`) Press (more than 5000 ms) | Factory Reset | +| Right Button (`BTN-2`) Press (less than 1000 ms) | Toggle pump state | +| Red & Green LED Blinking State | Pump transition from either Start/Stop | +| Red & Green LED On State | Pump is started | +| Red & Green LED Off State | Pump stopped | + +## Building + +### Preparation + +Some initial setup is necessary for preparing the build environment. This +section will need to be done when migrating to new versions of the SDK. This +guide assumes that the environment is linux based, and recommends Ubuntu 20.04. + +- Download and install [SysConfig][sysconfig]. This can be done simply with + the following commands. + + ``` + $ cd ~ + $ `wget https://dr-download.ti.com/software-development/ide-configuration-compiler-or-debugger/MD-nsUM6f7Vvb/1.15.0.2826/sysconfig-1.15.0_2826-setup.run` + $ chmod +x sysconfig-1.15.0_2826-setup.run + $ ./sysconfig-1.15.0_2826-setup.run + ``` + +- Run the bootstrap script to setup the build environment. + + ``` + $ cd ~/connectedhomeip + $ source ./scripts/bootstrap.sh + + ``` + +### Compilation + +It is necessary to activate the environment in every new shell. Then run GN and +Ninja to build the executable. + +- Activate the build environment with the repository activate script. + + ``` + $ cd ~/connectedhomeip + $ source ./scripts/activate.sh + + ``` + +- Run the build to produce a default executable. By default on Linux both the + TI SimpleLink SDK and Sysconfig are located in a `ti` folder in the user's + home directory, and you must provide the absolute path to them. For example + `/home/username/ti/sysconfig_1.15.0`. On Windows the default directory is + `C:\ti`. Take note of this install path, as it will be used in the next + step. + + ``` + $ cd ~/connectedhomeip/examples/pump-app/cc13x2x7_26x2x7 + OR + $ cd ~/connectedhomeip/examples/pump-app/cc13x4_26x4 + $ gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\"" + $ ninja -C out/debug + + ``` + + If you would like to define arguments on the command line you may add them + to the GN call. + + ``` + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + ``` + +## Programming + +Loading the built image onto a LaunchPad is supported through two methods; +Uniflash and Code Composer Studio (CCS). UniFlash can be used to load the image. +Code Composer Studio can be used to load the image and debug the source code. + +### Code Composer Studio + +Programming with CCS will allow for a full debug environment within the IDE. +This is accomplished by creating a target connection to the XDS110 debugger and +starting a project-less debug session. The CCS IDE will attempt to find the +source files on the local machine based on the debug information embedded within +the ELF. CCS may prompt you to find the source code if the image was built on +another machine or the source code is located in a different location than is +recorded within the ELF. + +Download and install [Code Composer Studio][ccs]. + +First open CCS and create a new workspace. + +Create a target connection (sometimes called the CCXML) for your target SoC and +debugger as described in the [Manual Method][ccs_manual_method] section of the +CCS User's Guide. + +Next initiate a project-less debug session as described in the [Manual +Launch][ccs_manual_launch] section of the CCS User's Guide. + +CCS should switch to the debug view described in the [After +Launch][ccs_after_launch] section of the User's Guide. The SoC core will likely +be disconnected and symbols will not be loaded. Connect to the core as described +in the [Debug View][ccs_debug_view] section of the User's Guide. Once the core +is connected, use the `Load` button on the toolbar to load the ELF image. + +Note that the default configuration of the CCXML uses 2-wire cJTAG instead of +the full 4-wire JTAG connection to match the default jumper configuration of the +LaunchPad. + +### UniFlash + +Uniflash is Texas Instrument's uniform programming tool for embedded processors. +This will allow you to erase, flash, and inspect the SoC without setting up a +debugging environment. + +Download and install [UniFlash][uniflash]. + +First open UniFlash. Debug probes connected to the computer will usually be +displayed under the Detected Devices due to the automatic device detection +feature. If your device does not show up in this view it my be disconnected, or +you may have to create a New Configuration. If you already have a CCXML for your +SoC and debug connection you can use that in the section at the bottom. Once +your device is selected, click the `Start` button within the section to launch +the session. + +Select the ELF image to load on the device with the `Browse` button. This file +is placed in the `out/debug` folder by this guide and ends with the `*.out` file +extension. For OTA enabled applications, the standalone image will instead end +with the `*-bim.hex` file extension. This this is a combined image with +application and and `BIM` included. The flag to enable or disable the OTA +feature is determined by "chip_enable_ota_requestor" in the application's +args.gni file. + +Finally click the `Load Image` button to load the executable image onto the +device. You should be able to see the log output over the XDS110 User UART. + +Note that programming the device through JTAG sets the Halt-in-Boot flag and may +cause issues when performing a software reset. This flag can be reset by +power-cycling the LaunchPad. + +## Running the Example + +By default the log output will be sent to the Application/User UART. Open a +terminal emulator to that port to see the output with the following options: + +| Parameter | Value | +| ------------ | -------- | +| Speed (baud) | `115200` | +| Data bits | `8` | +| Stop bits | `1` | +| Parity | `None` | +| Flow control | `None` | + +## Running the Example + +Once a device has been flashed with this example, it can now join and operate in +an existing Matter network. The following sections assume that a Matter network +is already active, and has at least one [OpenThread Border +Router][ot_border_router_setup]. + +For insight into what other components are needed to run this example, please +refer to our [Matter Getting Started Guide][matter-e2e-faq]. + +The steps below should be followed to commission the device onto the network and +control it once it has been commissioned. + +**Step 0** + +Set up the CHIP tool by following the instructions outlined in our [Matter +Getting Started Guide][matter-e2e-faq]. + +**Step 1** + +Commission the device onto the Matter network. Run the following command on the +CHIP tool: + +``` + +./chip-tool pairing ble-thread hex: 20202021 3840 + +``` + +Interacting with the application begins by enabling BLE advertisements and then +pairing the device into a Thread network. To provision this example onto a +Matter network, the device must be discoverable over Bluetooth LE. + +On the LaunchPad, press and hold the right button, labeled `BTN-1`, for more +than 1 second. Upon release, the Bluetooth LE advertising will begin. Once the +device is fully provisioned, BLE advertising will stop. + +Once the device has been successfully commissioned, you will see the following +message on the CHIP tool output: + +``` + +[1677648218.370754][39785:39790] CHIP:CTL: Received CommissioningComplete response, errorCode=0 +[1677648218.370821][39785:39790] CHIP:CTL: Successfully finished commissioning step 'SendComplete' + +``` + +An accompanying message will be seen from the device: + +``` + +Commissioning complete, notify platform driver to persist network credentials. + +``` + +**Step 2** The pump configuration & control cluster commands have the following +formats: + +``` +./chip-tool pumpconfigurationandcontrol +``` + +Send commands to the pump-app. Here are some example commands: + +Write normal operation mode (0) to device + +``` +./chip-tool pumpconfigurationandcontrol write operation-mode 0 1 1 +``` + +Get current operation mode + +``` +./chip-tool pumpconfigurationandcontrol read effective-operation-mode 1 1 +``` + +### Provisioning + +Interacting with the application begins by enabling BLE advertisements and then +pairing the device into a Thread network. + +#### Bluetooth LE Advertising + +To provision this example onto a Thread network, the device must be discoverable +over Bluetooth LE. BLE advertising is started by long pressing the right button +(greater than 1000ms), labeled `BTN-1` on the silkscreen. Once the device is +fully provisioned, BLE advertising will stop. + +#### Bluetooth LE Rendezvous + +Pairing this application with `ble-thread` can be done with any of the enabled +[CHIP Controller](../../../src/controller/README.md) applications. Use the +information printed on the console to aide in pairing the device. The controller +application can also be used to control the example app with the cluster +commands. + +## TI Support + +For technical support, please consider creating a post on TI's [E2E forum][e2e]. +Additionally, we welcome any feedback. + +[matter]: https://csa-iot.org/all-solutions/matter/ +[ccs]: https://www.ti.com/tool/CCSTUDIO +[ccs_after_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#after-launch +[ccs_debug_view]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#debug-view +[ccs_manual_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-launch +[ccs_manual_method]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-method +[e2e]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum +[matter-e2e-faq]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/1082428/faq-cc2652r7-matter----getting-started-guide +[sysconfig]: https://www.ti.com/tool/SYSCONFIG +[ti_thread_dnd]: + https://www.ti.com/wireless-connectivity/thread/design-development.html +[ot_border_router_setup]: https://openthread.io/guides/border-router/build +[uniflash]: https://www.ti.com/tool/download/UNIFLASH diff --git a/examples/pump-app/cc13x4_26x4/args.gni b/examples/pump-app/cc13x4_26x4/args.gni new file mode 100644 index 00000000000000..a0299575e8bc49 --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/args.gni @@ -0,0 +1,48 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/chip.gni") +import("${chip_root}/examples/platform/cc13x4_26x4/args.gni") + +ti_simplelink_sdk_target = get_label_info(":sdk", "label_no_toolchain") +ti_simplelink_sysconfig_target = + get_label_info(":sysconfig", "label_no_toolchain") + +ti_simplelink_board = "LP_EM_CC1354P10_6" + +# Size Optimizations +# use -Os instead of -Og, LWIP release build +optimize_debug_level = "s" +lwip_debug = false + +chip_enable_ota_requestor = false + +openthread_external_platform = "${chip_root}/third_party/openthread/platforms/cc13x4_26x4:libopenthread-cc13x4_cc26x4" + +# Disable CHIP Logging +#chip_progress_logging = false +#chip_detail_logging = false +#chip_automation_logging = false + +# BLE options +chip_config_network_layer_ble = true + +# Disable lock tracking, since our FreeRTOS configuration does not set +# INCLUDE_xSemaphoreGetMutexHolder +chip_stack_lock_tracking = "none" + +matter_device_vid = "0xFFF1" +matter_device_pid = "0x800A" +matter_software_ver = "0x0001" +matter_software_ver_str = "1.0d1" diff --git a/examples/pump-app/cc13x4_26x4/build_overrides b/examples/pump-app/cc13x4_26x4/build_overrides new file mode 120000 index 00000000000000..e578e73312ebd1 --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/build_overrides @@ -0,0 +1 @@ +../../build_overrides \ No newline at end of file diff --git a/examples/pump-app/cc13x4_26x4/chip.syscfg b/examples/pump-app/cc13x4_26x4/chip.syscfg new file mode 100644 index 00000000000000..e9cb55c3e22f07 --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/chip.syscfg @@ -0,0 +1,242 @@ +/* + * + * Copyright (c) 2020 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. + */ + + +/* Modules */ +var AESCCM = scripting.addModule("/ti/drivers/AESCCM"); +var AESECB = scripting.addModule("/ti/drivers/AESECB"); +var Button = scripting.addModule("/ti/drivers/apps/Button"); +var LED = scripting.addModule("/ti/drivers/apps/LED"); +var NVS = scripting.addModule("/ti/drivers/NVS"); +var RF = scripting.addModule("/ti/drivers/RF"); +var RFDesign = scripting.addModule("ti/devices/radioconfig/rfdesign"); +var RFCustom = scripting.addModule("/ti/devices/radioconfig/custom"); +var TRNG = scripting.addModule("/ti/drivers/TRNG"); +var SHA2 = scripting.addModule("/ti/drivers/SHA2"); +var UART2 = scripting.addModule("/ti/drivers/UART2"); +var ble = scripting.addModule("/ti/ble5stack/ble"); +var dmm = scripting.addModule("/ti/dmm/dmm"); +var AESCTRDRBG = scripting.addModule("/ti/drivers/AESCTRDRBG"); +var ECDH = scripting.addModule("/ti/drivers/ECDH"); + +/* Instances */ +var AESCCM1 = AESCCM.addInstance(); +var AESECB1 = AESECB.addInstance(); +var AESECB2 = AESECB.addInstance(); +var Button1 = Button.addInstance(); +var Button2 = Button.addInstance(); +var NVS1 = NVS.addInstance(); +var NVS2 = NVS.addInstance(); +var SHA21 = SHA2.addInstance(); +var LED1 = LED.addInstance(); +var LED2 = LED.addInstance(); +var TRNG1 = TRNG.addInstance(); +var TRNG2 = TRNG.addInstance(); +var TRNG3 = TRNG.addInstance(); +var UART2 = UART2.addInstance(); +var AESCTRDRBG1 = AESCTRDRBG.addInstance(); +var ECDH1 = ECDH.addInstance(); + +AESCTRDRBG1.$name = "CONFIG_AESCTRDRBG_0"; + +AESCCM1.$name = "CONFIG_AESCCM0"; + +AESECB1.$name = "CONFIG_AESECB0"; +AESECB2.$name = "CONFIG_AESECB_1"; + +ECDH1.$name = "CONFIG_ECDH0"; + +/* Left Button */ +Button1.$name = "CONFIG_BTN_LEFT"; +Button1.$hardware = system.deviceData.board.components["BTN-1"]; +Button1.gpioPin.$name = "CONFIG_GPIO_BTN1"; +Button1.gpioPin.pull = "Pull Up"; +Button1.gpioPin.interruptTrigger = "Falling Edge"; + +/* Left Button */ +Button2.$name = "CONFIG_BTN_RIGHT"; +Button2.$hardware = system.deviceData.board.components["BTN-2"]; +Button2.gpioPin.$name = "CONFIG_GPIO_BTN2"; +Button2.gpioPin.pull = "Pull Up"; +Button2.gpioPin.interruptTrigger = "Falling Edge"; + +/* ======== CCFG ======== */ +var CCFG = scripting.addModule("/ti/devices/CCFG"); +const ccfgSettings = system.getScript("/ti/common/lprf_ccfg_settings.js").ccfgSettings; +for(var setting in ccfgSettings) +{ + CCFG[setting] = ccfgSettings[setting]; +} + +CCFG.enableCodeGeneration = true; + + +/* NVS */ +NVS1.$name = "CONFIG_NVSINTERNAL"; +NVS1.internalFlash.regionBase = 0xFB800; +NVS1.internalFlash.regionSize = 0x2800; + + +NVS2.$name = "CONFIG_NVSEXTERNAL"; +NVS2.nvsType = "External"; // NVS Region Type +NVS2.$hardware = system.deviceData.board.components.MX25R8035F; + +/* RF */ +/* if an antenna component exists, assign it to the rf instance */ +if (system.deviceData.board && system.deviceData.board.components.RF) { + RF.$hardware = system.deviceData.board.components.RF; +} + +const rfDesignSettings = system.getScript("/ti/common/lprf_rf_design_settings.js").rfDesignSettings; +for(var setting in rfDesignSettings) +{ + RFDesign[setting] = rfDesignSettings[setting]; +} + + + +/* Handling for RF frontend characterization */ +if(RFDesign.rfDesign.match(/LP_CC2652PSIP/)) +{ + RFCustom.ieee = ["ieee154p10"]; + var rfCodeExportConfig = RFCustom.radioConfigieee154p10.codeExportConfig +} +else +{ + RFCustom.ieee = ["ieee154"]; + var rfCodeExportConfig = RFCustom.radioConfigieee154.codeExportConfig +} + +var cmdList = [ + "cmdIeeeTx", + "cmdIeeeRx", + "cmdIeeeCsma", + "cmdIeeeEdScan", + "cmdIeeeRxAck", + "cmdTxTest" +]; + +rfCodeExportConfig.useConst = true; +rfCodeExportConfig.useMulti = true; +rfCodeExportConfig.symGenMethod = "Custom"; + +const deviceId = system.deviceData.deviceId; + +// Add high PA options if present +if(deviceId.match(/CC(265[12]R|2674R|1352R1|1354R)/)) +{ + cmdList.push("cmdRadioSetup"); + rfCodeExportConfig.cmdRadioSetup = "RF_cmdIeeeRadioSetup"; +} +else if(deviceId.match(/CC(265[12]P|2674P|1352P)/)) +{ + cmdList.push("cmdRadioSetupPa"); + rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; + rfCodeExportConfig.paExport = "combined"; +} +else if(deviceId.match(/CC(265[34]|1354)P/)) +{ + cmdList.push("cmdRadioSetupPa"); + rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; + // currently not characterized for high PA +} +else +{ + throw new Error("Could not match platform to any known platform types"); +} + +rfCodeExportConfig.cmdList_ieee_15_4 = cmdList; + +/* Red LED */ +LED1.$name = "CONFIG_LED_RED"; +LED1.$hardware = system.deviceData.board.components.LED_RED; +LED1.gpioPin.$name = "CONFIG_GPIO_RLED"; +LED1.gpioPin.mode = "Output"; +LED1.gpioPin.callbackFunction = ""; + +/* Green LED */ +LED2.$name = "CONFIG_LED_GREEN"; +LED2.$hardware = system.deviceData.board.components.LED_GREEN; +LED2.gpioPin.$name = "CONFIG_GPIO_GLED"; +LED2.gpioPin.mode = "Output"; +LED2.gpioPin.callbackFunction = ""; + +/* Debug UART */ +UART2.$hardware = system.deviceData.board.components.XDS110UART; +UART2.$name = "CONFIG_UART2_DEBUG"; + +/* TRNG */ +TRNG1.$name = "CONFIG_TRNG_0"; +TRNG2.$name = "CONFIG_TRNG_THREAD"; +TRNG3.$name = "CONFIG_TRNG_APP"; + +/* BLE */ +ble.addressMode = "ADDRMODE_RP_WITH_PUBLIC_ID"; +ble.maxConnNum = 1; +ble.numOfAdvSets = 1; +ble.lockProject = true; +ble.oneLibSizeOpt = true; +ble.maxPDUSize = 255; +ble.radioConfig.codeExportConfig.$name = "ti_devices_radioconfig_code_export_param1"; +ble.connUpdateParamsPeripheral.$name = "ti_ble5stack_general_ble_conn_update_params0"; +ble.connUpdateParamsPeripheral.reqMinConnInt = 30; +ble.connUpdateParamsPeripheral.reqMaxConnInt = 50; + +ble.advSet1.$name = "ti_ble5stack_broadcaster_advertisement_set0"; +ble.advSet1.advParam1.$name = "ti_ble5stack_broadcaster_advertisement_params0"; + +ble.rfDesign = "LP_EM_CC1354P10_6"; + +ble.thorPg = 2; +/* DMM */ +dmm.project = "ti_thread_thermostat_remote_display"; +dmm.stackRoles = ["blePeripheral","threadFTD"]; +dmm.lockStackRoles = true; +dmm.numApplicationStates = 10; +dmm.applicationState0 = "ANY"; +dmm.applicationState1 = "DMMPOLICY_BLE_IDLE"; +dmm.applicationState2 = "DMMPOLICY_BLE_ADV"; +dmm.applicationState3 = "DMMPOLICY_BLE_CONNECTING"; +dmm.applicationState4 = "DMMPOLICY_BLE_HIGH_BANDWIDTH"; +dmm.applicationState5 = "DMMPOLICY_BLE_CONNECTED"; +dmm.applicationState6 = "DMMPOLICY_BLE_OAD"; +dmm.applicationState7 = "DMMPOLICY_THREAD_IDLE"; +dmm.applicationState8 = "DMMPOLICY_THREAD_LINK_EST"; +dmm.applicationState9 = "DMMPOLICY_THREAD_DATA"; +dmm.policyArray.create(4); +dmm.policyArray[0].$name = "ti_dmm_policy_dmm_policy0"; +dmm.policyArray[0].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble0"; +dmm.policyArray[0].blePeripheral.applicationStates = ["applicationState6"]; +dmm.policyArray[0].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread0"; +dmm.policyArray[0].threadFTD.pause = "DMMPOLICY_PAUSED"; +dmm.policyArray[1].$name = "ti_dmm_policy_dmm_policy1"; +dmm.policyArray[1].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble1"; +dmm.policyArray[1].blePeripheral.applicationStates = ["applicationState3","applicationState4"]; +dmm.policyArray[1].blePeripheral.weight = 25; +dmm.policyArray[1].blePeripheral.appliedActivity = ["DMMPOLICY_APPLIED_ACTIVITY_BLE_CONNECTION"]; +dmm.policyArray[1].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread1"; +dmm.policyArray[2].$name = "ti_dmm_policy_dmm_policy2"; +dmm.policyArray[2].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble2"; +dmm.policyArray[2].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread2"; +dmm.policyArray[2].threadFTD.weight = 30; +dmm.policyArray[2].threadFTD.applicationStates = ["applicationState8"]; +dmm.policyArray[2].threadFTD.appliedActivity = ["DMMPOLICY_APPLIED_ACTIVITY_ALL"]; +dmm.policyArray[3].$name = "ti_dmm_policy_dmm_policy3"; +dmm.policyArray[3].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble3"; +dmm.policyArray[3].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread3"; +dmm.policyArray[3].threadFTD.weight = 1; diff --git a/examples/pump-app/cc13x4_26x4/main/AppTask.cpp b/examples/pump-app/cc13x4_26x4/main/AppTask.cpp new file mode 100644 index 00000000000000..8b03138ae7513c --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/main/AppTask.cpp @@ -0,0 +1,676 @@ +/* + * + * Copyright (c) 2020 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 "CHIPDeviceManager.h" +#include "DeviceCallbacks.h" +#include +#include + +#include "FreeRTOS.h" +#include +#include + +#include + +#include +#include +#include + +#if defined(CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR) +#include +#include +#include +#include +#include +#endif +#include +#include +#include +#include +#include + +#include + +#include +#include + +/* syscfg */ +#include + +#define APP_TASK_STACK_SIZE (4096) +#define APP_TASK_PRIORITY 4 +#define APP_EVENT_QUEUE_SIZE 10 + +#define PCC_CLUSTER_ENDPOINT 1 +#define ONOFF_CLUSTER_ENDPOINT 1 +#define EXTENDED_DISCOVERY_TIMEOUT_SEC 20 + +using namespace chip; +using namespace chip::app; +using namespace chip::Credentials; +using namespace chip::DeviceLayer; +using namespace chip::DeviceManager; +using namespace chip::app::Clusters; + +static TaskHandle_t sAppTaskHandle; +static QueueHandle_t sAppEventQueue; + +static LED_Handle sAppRedHandle; +static LED_Handle sAppGreenHandle; +static Button_Handle sAppLeftHandle; +static Button_Handle sAppRightHandle; + +AppTask AppTask::sAppTask; + +static DeviceCallbacks sDeviceCallbacks; + +#if defined(CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR) +static DefaultOTARequestor sRequestorCore; +static DefaultOTARequestorStorage sRequestorStorage; +static DefaultOTARequestorDriver sRequestorUser; +static BDXDownloader sDownloader; +static OTAImageProcessorImpl sImageProcessor; + +void InitializeOTARequestor(void) +{ + // Initialize and interconnect the Requestor and Image Processor objects + SetRequestorInstance(&sRequestorCore); + + sRequestorStorage.Init(chip::Server::GetInstance().GetPersistentStorage()); + sRequestorCore.Init(chip::Server::GetInstance(), sRequestorStorage, sRequestorUser, sDownloader); + sImageProcessor.SetOTADownloader(&sDownloader); + sDownloader.SetImageProcessorDelegate(&sImageProcessor); + sRequestorUser.Init(&sRequestorCore, &sImageProcessor); +} +#endif + +static const chip::EndpointId sIdentifyEndpointId = 0; +static const uint32_t sIdentifyBlinkRateMs = 500; + +::Identify stIdentify = { sIdentifyEndpointId, AppTask::IdentifyStartHandler, AppTask::IdentifyStopHandler, + EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, AppTask::TriggerIdentifyEffectHandler }; + +int AppTask::StartAppTask() +{ + int ret = 0; + + sAppEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent)); + if (sAppEventQueue == NULL) + { + PLAT_LOG("Failed to allocate app event queue"); + while (true) + ; + } + + // Start App task. + if (xTaskCreate(AppTaskMain, "APP", APP_TASK_STACK_SIZE / sizeof(StackType_t), NULL, APP_TASK_PRIORITY, &sAppTaskHandle) != + pdPASS) + { + PLAT_LOG("Failed to create app task"); + while (true) + ; + } + return ret; +} + +int AppTask::Init() +{ + LED_Params ledParams; + Button_Params buttonParams; + + cc13xx_26xxLogInit(); + + // Init Chip memory management before the stack + Platform::MemoryInit(); + + CHIP_ERROR ret = PlatformMgr().InitChipStack(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("PlatformMgr().InitChipStack() failed"); + while (true) + ; + } + + ret = ThreadStackMgr().InitThreadStack(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("ThreadStackMgr().InitThreadStack() failed"); + while (true) + ; + } + +#ifdef CONFIG_OPENTHREAD_MTD_SED + ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); +#elif CONFIG_OPENTHREAD_MTD + ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); +#else + ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); +#endif + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("ConnectivityMgr().SetThreadDeviceType() failed"); + while (true) + ; + } + + ret = ThreadStackMgrImpl().StartThreadTask(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("ThreadStackMgr().StartThreadTask() failed"); + while (true) + ; + } + + // Initialize LEDs + PLAT_LOG("Initialize LEDs"); + LED_init(); + + LED_Params_init(&ledParams); // default PWM LED + sAppRedHandle = LED_open(CONFIG_LED_RED, &ledParams); + LED_setOff(sAppRedHandle); + + LED_Params_init(&ledParams); // default PWM LED + sAppGreenHandle = LED_open(CONFIG_LED_GREEN, &ledParams); + LED_setOff(sAppGreenHandle); + + // Initialize buttons + PLAT_LOG("Initialize buttons"); + Button_init(); + + Button_Params_init(&buttonParams); + buttonParams.buttonEventMask = Button_EV_CLICKED | Button_EV_LONGPRESSED; + buttonParams.longPressDuration = 5000U; // ms + sAppLeftHandle = Button_open(CONFIG_BTN_LEFT, &buttonParams); + Button_setCallback(sAppLeftHandle, ButtonLeftEventHandler); + + Button_Params_init(&buttonParams); + buttonParams.buttonEventMask = Button_EV_CLICKED; + buttonParams.longPressDuration = 1000U; // ms + sAppRightHandle = Button_open(CONFIG_BTN_RIGHT, &buttonParams); + Button_setCallback(sAppRightHandle, ButtonRightEventHandler); + + // Initialize Pump module + PLAT_LOG("Initialize Pump"); + PumpMgr().Init(); + + PumpMgr().SetCallbacks(ActionInitiated, ActionCompleted); + +#if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY + DnssdServer::Instance().SetExtendedDiscoveryTimeoutSecs(EXTENDED_DISCOVERY_TIMEOUT_SEC); +#endif + + // Init ZCL Data Model + static chip::CommonCaseDeviceServerInitParams initParams; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + chip::Server::GetInstance().Init(initParams); + + // Initialize device attestation config +#ifdef CC13X4_26X4_ATTESTATION_CREDENTIALS + SetDeviceAttestationCredentialsProvider(CC13X4_26X4::GetCC13X4_26X4DacProvider()); +#else + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif + + ConfigurationMgr().LogDeviceConfig(); + +#if defined(CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR) + InitializeOTARequestor(); +#endif + + // QR code will be used with CHIP Tool + PrintOnboardingCodes(RendezvousInformationFlags(RendezvousInformationFlag::kBLE)); + + CHIPDeviceManager & deviceMgr = CHIPDeviceManager::GetInstance(); + ret = deviceMgr.Init(&sDeviceCallbacks); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("CHIPDeviceManager::Init() failed: %s", ErrorStr(ret)); + while (true) + ; + } + + return 0; +} + +void AppTask::AppTaskMain(void * pvParameter) +{ + AppEvent event; + + sAppTask.Init(); + + while (true) + { + /* Task pend until we have stuff to do */ + if (xQueueReceive(sAppEventQueue, &event, portMAX_DELAY) == pdTRUE) + { + sAppTask.DispatchEvent(&event); + } + } +} + +void AppTask::PostEvent(const AppEvent * aEvent) +{ + if (xQueueSend(sAppEventQueue, aEvent, 0) != pdPASS) + { + /* Failed to post the message */ + } +} + +void AppTask::ButtonLeftEventHandler(Button_Handle handle, Button_EventMask events) +{ + AppEvent event; + event.Type = AppEvent::kEventType_ButtonLeft; + + if (events & Button_EV_CLICKED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_Clicked; + } + else if (events & Button_EV_LONGPRESSED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_LongPressed; + } + // button callbacks are in ISR context + if (xQueueSendFromISR(sAppEventQueue, &event, NULL) != pdPASS) + { + /* Failed to post the message */ + } +} + +void AppTask::ButtonRightEventHandler(Button_Handle handle, Button_EventMask events) +{ + AppEvent event; + event.Type = AppEvent::kEventType_ButtonRight; + + if (events & Button_EV_CLICKED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_Clicked; + } + // button callbacks are in ISR context + if (xQueueSendFromISR(sAppEventQueue, &event, NULL) != pdPASS) + { + /* Failed to post the message */ + } +} + +void AppTask::ActionInitiated(PumpManager::Action_t aAction, int32_t aActor) +{ + // If the action has been initiated by the pump, update the pump trait + // and start flashing the LEDs rapidly to indicate action initiation. + if (aAction == PumpManager::START_ACTION) + { + PLAT_LOG("Pump start initiated"); + ; // TODO + } + else if (aAction == PumpManager::STOP_ACTION) + { + PLAT_LOG("Stop initiated"); + ; // TODO + } + + LED_setOn(sAppGreenHandle, LED_BRIGHTNESS_MAX); + LED_startBlinking(sAppGreenHandle, 50 /* ms */, LED_BLINK_FOREVER); + LED_setOn(sAppRedHandle, LED_BRIGHTNESS_MAX); + LED_startBlinking(sAppRedHandle, 110 /* ms */, LED_BLINK_FOREVER); +} + +void AppTask::ActionCompleted(PumpManager::Action_t aAction, int32_t aActor) +{ + // if the action has been completed by the pump, update the pump trait. + // Turn on the pump state LED if in a STARTED state OR + // Turn off the pump state LED if in an STOPPED state. + if (aAction == PumpManager::START_ACTION) + { + PLAT_LOG("Pump start completed"); + LED_stopBlinking(sAppGreenHandle); + LED_setOn(sAppGreenHandle, LED_BRIGHTNESS_MAX); + LED_stopBlinking(sAppRedHandle); + LED_setOn(sAppRedHandle, LED_BRIGHTNESS_MAX); + // Signal to the PCC cluster, that the pump is running + sAppTask.UpdateClusterState(); + } + else if (aAction == PumpManager::STOP_ACTION) + { + PLAT_LOG("Pump stop completed"); + LED_stopBlinking(sAppGreenHandle); + LED_setOff(sAppGreenHandle); + LED_stopBlinking(sAppRedHandle); + LED_setOff(sAppRedHandle); + // Signal to the PCC cluster, that the pump is NOT running + sAppTask.UpdateClusterState(); + } + if (aActor == AppEvent::kEventType_ButtonLeft) + { + sAppTask.UpdateClusterState(); + } +} + +void AppTask::DispatchEvent(AppEvent * aEvent) +{ + switch (aEvent->Type) + { + case AppEvent::kEventType_ButtonRight: + if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) + { + // Toggle Pump state + if (!PumpMgr().IsStopped()) + { + PumpMgr().InitiateAction(0, PumpManager::STOP_ACTION); + } + else + { + PumpMgr().InitiateAction(0, PumpManager::START_ACTION); + } + } + break; + + case AppEvent::kEventType_ButtonLeft: + if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) + { + // Post event for demonstration purposes, we must ensure that the + // LogEvent is called in the right context which is the Matter mainloop + // thru ScheduleWork() + chip::DeviceLayer::PlatformMgr().ScheduleWork(sAppTask.PostEvents, reinterpret_cast(nullptr)); + + // Toggle BLE advertisements + if (!ConnectivityMgr().IsBLEAdvertisingEnabled()) + { + if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() == CHIP_NO_ERROR) + { + PLAT_LOG("Enabled BLE Advertisements"); + } + else + { + PLAT_LOG("OpenBasicCommissioningWindow() failed"); + } + } + else + { + // Disable BLE advertisements + ConnectivityMgr().SetBLEAdvertisingEnabled(false); + PLAT_LOG("Disabled BLE Advertisements"); + } + } + else if (AppEvent::kAppEventButtonType_LongPressed == aEvent->ButtonEvent.Type) + { + chip::Server::GetInstance().ScheduleFactoryReset(); + } + break; + + case AppEvent::kEventType_IdentifyStart: + LED_setOn(sAppGreenHandle, LED_BRIGHTNESS_MAX); + LED_startBlinking(sAppGreenHandle, sIdentifyBlinkRateMs, LED_BLINK_FOREVER); + PLAT_LOG("Identify started"); + break; + + case AppEvent::kEventType_IdentifyStop: + LED_stopBlinking(sAppGreenHandle); + + if (!PumpMgr().IsStopped()) + { + LED_setOn(sAppGreenHandle, LED_BRIGHTNESS_MAX); + } + else + { + LED_setOff(sAppGreenHandle); + } + PLAT_LOG("Identify stopped"); + break; + + case AppEvent::kEventType_AppEvent: + if (NULL != aEvent->Handler) + { + aEvent->Handler(aEvent); + } + break; + + case AppEvent::kEventType_None: + default: + break; + } +} + +void AppTask::InitOnOffClusterState() +{ + + EmberStatus status; + + ChipLogProgress(NotSpecified, "Init On/Off clusterstate"); + + // Write false as pump always boots in stopped mode + status = OnOff::Attributes::OnOff::Set(ONOFF_CLUSTER_ENDPOINT, false); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Init On/Off state %x", status); + } +} + +void AppTask::InitPCCClusterState() {} + +void AppTask::UpdateClusterState(void) +{ + // We must ensure that the Cluster accessors gets called in the right context + // which is the Matter mainloop thru ScheduleWork() + chip::DeviceLayer::PlatformMgr().ScheduleWork(UpdateCluster, reinterpret_cast(nullptr)); +} + +void AppTask::UpdateCluster(intptr_t context) +{ + EmberStatus status; + BitMask pumpStatus; + + ChipLogProgress(NotSpecified, "Update Cluster State"); + + // Update the PumpStatus + PumpConfigurationAndControl::Attributes::PumpStatus::Get(PCC_CLUSTER_ENDPOINT, &pumpStatus); + if (PumpMgr().IsStopped()) + { + pumpStatus.Clear(PumpConfigurationAndControl::PumpStatusBitmap::kRunning); + } + else + { + pumpStatus.Set(PumpConfigurationAndControl::PumpStatusBitmap::kRunning); + } + PumpConfigurationAndControl::Attributes::PumpStatus::Set(PCC_CLUSTER_ENDPOINT, pumpStatus); + + status = PumpConfigurationAndControl::Attributes::ControlMode::Set(PCC_CLUSTER_ENDPOINT, + PumpConfigurationAndControl::ControlModeEnum::kConstantFlow); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Constant Flow error %x", status); + } + status = PumpConfigurationAndControl::Attributes::ControlMode::Set( + PCC_CLUSTER_ENDPOINT, PumpConfigurationAndControl::ControlModeEnum::kConstantPressure); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Constant Pressure error %x", status); + } + status = PumpConfigurationAndControl::Attributes::ControlMode::Set( + PCC_CLUSTER_ENDPOINT, PumpConfigurationAndControl::ControlModeEnum::kConstantSpeed); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Constant Speed error %x", status); + } + status = PumpConfigurationAndControl::Attributes::ControlMode::Set( + PCC_CLUSTER_ENDPOINT, PumpConfigurationAndControl::ControlModeEnum::kConstantTemperature); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Constant Temperature error %x", status); + } + + // Write the new values + bool onOffState = !PumpMgr().IsStopped(); + status = OnOff::Attributes::OnOff::Set(ONOFF_CLUSTER_ENDPOINT, onOffState); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Updating On/Off state %x", status); + } + + int16_t maxPressure = PumpMgr().GetMaxPressure(); + status = PumpConfigurationAndControl::Attributes::MaxPressure::Set(PCC_CLUSTER_ENDPOINT, maxPressure); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Updating MaxPressure %x", status); + } + + uint16_t maxSpeed = PumpMgr().GetMaxSpeed(); + status = PumpConfigurationAndControl::Attributes::MaxSpeed::Set(PCC_CLUSTER_ENDPOINT, maxSpeed); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Updating MaxSpeed %x", status); + } + + uint16_t maxFlow = PumpMgr().GetMaxFlow(); + status = PumpConfigurationAndControl::Attributes::MaxFlow::Set(PCC_CLUSTER_ENDPOINT, maxFlow); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Updating MaxFlow %x", status); + } + + int16_t minConstPress = PumpMgr().GetMinConstPressure(); + status = PumpConfigurationAndControl::Attributes::MinConstPressure::Set(PCC_CLUSTER_ENDPOINT, minConstPress); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Updating MinConstPressure %x", status); + } + + int16_t maxConstPress = PumpMgr().GetMaxConstPressure(); + status = PumpConfigurationAndControl::Attributes::MaxConstPressure::Set(PCC_CLUSTER_ENDPOINT, maxConstPress); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Updating MaxConstPressure %x", status); + } + + int16_t minCompPress = PumpMgr().GetMinCompPressure(); + status = PumpConfigurationAndControl::Attributes::MinCompPressure::Set(PCC_CLUSTER_ENDPOINT, minCompPress); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Updating MinCompPressure %x", status); + } + + int16_t maxCompPress = PumpMgr().GetMaxCompPressure(); + status = PumpConfigurationAndControl::Attributes::MaxCompPressure::Set(PCC_CLUSTER_ENDPOINT, maxCompPress); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Updating MaxCompPressure %x", status); + } + + uint16_t minConstSpeed = PumpMgr().GetMinConstSpeed(); + status = PumpConfigurationAndControl::Attributes::MinConstSpeed::Set(PCC_CLUSTER_ENDPOINT, minConstSpeed); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Updating MinConstSpeed %x", status); + } + + uint16_t maxConstSpeed = PumpMgr().GetMaxConstSpeed(); + status = PumpConfigurationAndControl::Attributes::MaxConstSpeed::Set(PCC_CLUSTER_ENDPOINT, maxConstSpeed); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Updating MaxConstSpeed %x", status); + } + + uint16_t minConstFlow = PumpMgr().GetMinConstFlow(); + status = PumpConfigurationAndControl::Attributes::MinConstFlow::Set(PCC_CLUSTER_ENDPOINT, minConstFlow); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Updating MinConstFlow %x", status); + } + + uint16_t maxConstFlow = PumpMgr().GetMaxConstFlow(); + status = PumpConfigurationAndControl::Attributes::MaxConstFlow::Set(PCC_CLUSTER_ENDPOINT, maxConstFlow); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Updating MaxConstFlow %x", status); + } + + int16_t minConstTemp = PumpMgr().GetMinConstTemp(); + status = PumpConfigurationAndControl::Attributes::MinConstTemp::Set(PCC_CLUSTER_ENDPOINT, minConstTemp); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Updating MinConstTemp %x", status); + } + + int16_t maxConstTemp = PumpMgr().GetMaxConstTemp(); + status = PumpConfigurationAndControl::Attributes::MaxConstTemp::Set(PCC_CLUSTER_ENDPOINT, maxConstTemp); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: Updating MaxConstTemp %x", status); + } +} + +void AppTask::PostEvents(intptr_t context) +{ + // Example on posting events - here we post the general fault event on endpoints with PCC Server enabled + for (auto endpoint : EnabledEndpointsWithServerCluster(PumpConfigurationAndControl::Id)) + { + PumpConfigurationAndControl::Events::GeneralFault::Type event; + EventNumber eventNumber; + + ChipLogProgress(Zcl, "AppTask: Post PCC GeneralFault event"); + // Using default priority for the event + if (CHIP_NO_ERROR != LogEvent(event, endpoint, eventNumber)) + { + ChipLogError(Zcl, "AppTask: Failed to record GeneralFault event"); + } + } +} + +void AppTask::IdentifyStartHandler(::Identify *) +{ + AppEvent event; + event.Type = AppEvent::kEventType_IdentifyStart; + sAppTask.PostEvent(&event); +} + +void AppTask::IdentifyStopHandler(::Identify *) +{ + AppEvent event; + event.Type = AppEvent::kEventType_IdentifyStop; + sAppTask.PostEvent(&event); +} + +void AppTask::TriggerIdentifyEffectHandler(::Identify * identify) +{ + switch (identify->mCurrentEffectIdentifier) + { + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: + PLAT_LOG("Starting blink identifier effect"); + IdentifyStartHandler(identify); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: + PLAT_LOG("Breathe identifier effect not implemented"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: + PLAT_LOG("Okay identifier effect not implemented"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: + PLAT_LOG("Channel Change identifier effect not implemented"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: + PLAT_LOG("Finish identifier effect not implemented"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: + PLAT_LOG("Stop identifier effect"); + IdentifyStopHandler(identify); + break; + default: + PLAT_LOG("No identifier effect"); + } +} diff --git a/examples/pump-app/cc13x4_26x4/main/CHIPDeviceManager.cpp b/examples/pump-app/cc13x4_26x4/main/CHIPDeviceManager.cpp new file mode 100644 index 00000000000000..9c1894abc0bd80 --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/main/CHIPDeviceManager.cpp @@ -0,0 +1,91 @@ +/* + * + * 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. + */ + +/** + * @file + * This file implements the CHIP Device Interface that is used by + * applications to interact with the CHIP stack + * + */ + +#include + +#include "AppConfig.h" +#include "CHIPDeviceManager.h" + +#include +#include +#include +#include +#include +#include + +using namespace ::chip; + +namespace chip { +namespace DeviceManager { + +using namespace ::chip::DeviceLayer; + +void CHIPDeviceManager::CommonDeviceEventHandler(const ChipDeviceEvent * event, intptr_t arg) +{ + CHIPDeviceManagerCallbacks * cb = reinterpret_cast(arg); + if (cb != nullptr) + { + cb->DeviceEventCallback(event, reinterpret_cast(cb)); + } +} + +CHIP_ERROR CHIPDeviceManager::Init(CHIPDeviceManagerCallbacks * cb) +{ + mCB = cb; + + // Register a function to receive events from the CHIP device layer. Note that calls to + // this function will happen on the CHIP event loop thread, not the app_main thread. + PlatformMgr().AddEventHandler(CHIPDeviceManager::CommonDeviceEventHandler, reinterpret_cast(cb)); + + // Start a task to run the CHIP Device event loop. + return PlatformMgr().StartEventLoopTask(); +} +} // namespace DeviceManager +} // namespace chip + +void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size, + uint8_t * value) +{ + chip::DeviceManager::CHIPDeviceManagerCallbacks * cb = + chip::DeviceManager::CHIPDeviceManager::GetInstance().GetCHIPDeviceManagerCallbacks(); + if (cb != nullptr) + { + cb->PostAttributeChangeCallback(attributePath.mEndpointId, attributePath.mClusterId, attributePath.mAttributeId, type, size, + value); + } +} + +chip::Protocols::InteractionModel::Status MatterPreAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, + uint8_t type, uint16_t size, uint8_t * value) +{ + chip::DeviceManager::CHIPDeviceManagerCallbacks * cb = + chip::DeviceManager::CHIPDeviceManager::GetInstance().GetCHIPDeviceManagerCallbacks(); + if (cb != nullptr) + { + return cb->PreAttributeChangeCallback(attributePath.mEndpointId, attributePath.mClusterId, attributePath.mAttributeId, type, + size, value); + } + + return chip::Protocols::InteractionModel::Status::Success; +} diff --git a/examples/pump-app/cc13x4_26x4/main/DeviceCallbacks.cpp b/examples/pump-app/cc13x4_26x4/main/DeviceCallbacks.cpp new file mode 100644 index 00000000000000..8cda813016e45e --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/main/DeviceCallbacks.cpp @@ -0,0 +1,211 @@ +/* + * + * Copyright (c) 2021 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 DeviceCallbacks.cpp + * + * Implements all the callbacks to the application from the CHIP Stack + * + **/ + +#include "DeviceCallbacks.h" +#include "AppConfig.h" +#include "PumpManager.h" + +#include +#include +#include + +using namespace chip; +using namespace chip::Inet; +using namespace chip::System; +using namespace chip::DeviceLayer; +using namespace chip::app::Clusters; + +void DeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) +{ + switch (event->Type) + { + case DeviceEventType::kThreadConnectivityChange: + OnThreadConnectivityChange(event); + break; + + case DeviceEventType::kInternetConnectivityChange: + OnInternetConnectivityChange(event); + break; + + case DeviceEventType::kServiceProvisioningChange: + PLAT_LOG("## Service provisioning state change (%d,%d)", event->ServiceProvisioningChange.IsServiceProvisioned, + event->ServiceProvisioningChange.ServiceConfigUpdated); + break; + + case DeviceEventType::kCHIPoBLEConnectionEstablished: + PLAT_LOG("CHIPoBLE connection established"); + break; + + case DeviceEventType::kCHIPoBLEConnectionClosed: + PLAT_LOG("CHIPoBLE disconnected"); + break; + + case DeviceEventType::kThreadStateChange: + PLAT_LOG("## Thread stack state change (%x)", event->ThreadStateChange.OpenThread.Flags); + break; + + case DeviceEventType::kCommissioningComplete: + PLAT_LOG("Commissioning complete for fabric 0x%x", event->CommissioningComplete.fabricIndex); + break; + + case DeviceEventType::kOperationalNetworkEnabled: + PLAT_LOG("## Operational network enabled"); + break; + + case DeviceEventType::kDnssdInitialized: + PLAT_LOG("## Dnssd platform initialized"); + break; + + case DeviceEventType::kFailSafeTimerExpired: + PLAT_LOG("## Failsafe timer expired..."); + break; + + case DeviceEventType::kInterfaceIpAddressChanged: + PLAT_LOG("*** Interface IP address changed ***"); + if ((event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV4_Assigned) || + (event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV6_Assigned)) + { + // MDNS server restart on any ip assignment: if link local ipv6 is configured, that + // will not trigger a 'internet connectivity change' as there is no internet + // connectivity. MDNS still wants to refresh its listening interfaces to include the + // newly selected address. + chip::app::DnssdServer::Instance().StartServer(); + } + break; + } +} + +chip::Protocols::InteractionModel::Status DeviceCallbacks::PreAttributeChangeCallback(chip::EndpointId endpointId, + chip::ClusterId clusterId, + chip::AttributeId attributeId, uint8_t type, + uint16_t size, uint8_t * value) +{ + PLAT_LOG("PreAttributeChangeCallback - Cluster ID: '0x%04x', EndPoint ID: '0x%02x', Attribute ID: '0x%04x'", clusterId, + endpointId, attributeId); + + switch (clusterId) + { + case PumpConfigurationAndControl::Id: + break; + + case OnOff::Id: + break; + + case LevelControl::Id: + break; + + default: + PLAT_LOG("Unhandled cluster ID: %d", clusterId); + break; + } + + return chip::Protocols::InteractionModel::Status::Success; +} + +void DeviceCallbacks::PostAttributeChangeCallback(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId, uint8_t type, + uint16_t size, uint8_t * value) +{ + PLAT_LOG("PostAttributeChangeCallback - Cluster ID: '0x%04x', EndPoint ID: '0x%02x', Attribute ID: '0x%04x'", clusterId, + endpointId, attributeId); + + switch (clusterId) + { + case PumpConfigurationAndControl::Id: + break; + + case OnOff::Id: + OnOnOffPostAttributeChangeCallback(endpointId, attributeId, value); + break; + + case LevelControl::Id: + OnLevelControlAttributeChangeCallback(endpointId, attributeId, value); + break; + + default: + PLAT_LOG("Unhandled cluster ID: %d", clusterId); + break; + } +} + +void DeviceCallbacks::OnInternetConnectivityChange(const ChipDeviceEvent * event) +{ + if (event->InternetConnectivityChange.IPv4 == kConnectivity_Established) + { + PLAT_LOG("Server ready at: %s:%d", event->InternetConnectivityChange.ipAddress, CHIP_PORT); + chip::app::DnssdServer::Instance().StartServer(); + } + else if (event->InternetConnectivityChange.IPv4 == kConnectivity_Lost) + { + PLAT_LOG("Lost IPv4 connectivity..."); + } + if (event->InternetConnectivityChange.IPv6 == kConnectivity_Established) + { + PLAT_LOG("IPv6 Server ready..."); + chip::app::DnssdServer::Instance().StartServer(); + } + else if (event->InternetConnectivityChange.IPv6 == kConnectivity_Lost) + { + PLAT_LOG("Lost IPv6 connectivity..."); + } +} + +void DeviceCallbacks::OnThreadConnectivityChange(const ChipDeviceEvent * event) +{ + if (event->ThreadConnectivityChange.Result == kConnectivity_Established) + { + PLAT_LOG("## Thread connectivity established..."); + } + else if (event->ThreadConnectivityChange.Result == kConnectivity_Lost) + { + PLAT_LOG("## Thread connectivity lost..."); + } + else if (event->ThreadConnectivityChange.Result == kConnectivity_NoChange) + { + PLAT_LOG("## No change in Thread connectivity..."); + } +} + +void DeviceCallbacks::OnOnOffPostAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value) +{ + VerifyOrExit(attributeId == OnOff::Attributes::OnOff::Id, PLAT_LOG("Unhandled Attribute ID: '0x%04x", attributeId)); + VerifyOrExit(endpointId == 1, PLAT_LOG("Unexpected EndPoint ID: `0x%02x'", endpointId)); + + PumpMgr().InitiateAction(0, *value ? PumpManager::START_ACTION : PumpManager::STOP_ACTION); + +exit: + return; +} + +void DeviceCallbacks::OnLevelControlAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value) +{ + VerifyOrExit(attributeId == LevelControl::Attributes::CurrentLevel::Id, + PLAT_LOG("Unhandled Attribute ID: '0x%04x", attributeId)); + VerifyOrExit(endpointId == 1, PLAT_LOG("Unexpected EndPoint ID: `0x%02x'", endpointId)); + + ChipLogProgress(Zcl, "[pump-app] Cluster LevelControl: attribute CurrentLevel set to %u", *value); + +exit: + return; +} diff --git a/examples/pump-app/cc13x4_26x4/main/PumpManager.cpp b/examples/pump-app/cc13x4_26x4/main/PumpManager.cpp new file mode 100644 index 00000000000000..0e7e90e27aba40 --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/main/PumpManager.cpp @@ -0,0 +1,333 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * 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 "PumpManager.h" + +#include "AppConfig.h" +#include "AppTask.h" +#include "FreeRTOS.h" + +#define ACTUATOR_MOVEMENT_PERIOS_MS 500 + +PumpManager PumpManager::sPump; + +int PumpManager::Init() +{ + int ret = 0; + + mTimerHandle = xTimerCreate("BLT_TIMER", pdMS_TO_TICKS(ACTUATOR_MOVEMENT_PERIOS_MS), pdFALSE, this, TimerEventHandler); + if (NULL == mTimerHandle) + { + PLAT_LOG("failed to create pump timer"); + while (true) + ; + } + + mState = kState_StopCompleted; + mAutoStartTimerArmed = false; + mAutoRestart = false; + mAutoStartDuration = 0; + + return ret; +} + +void PumpManager::SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB) +{ + mActionInitiated_CB = aActionInitiated_CB; + mActionCompleted_CB = aActionCompleted_CB; +} + +bool PumpManager::IsActionInProgress() +{ + return (mState == kState_StartInitiated || mState == kState_StopInitiated); +} + +bool PumpManager::IsStopped() +{ + return (mState == kState_StopCompleted); +} + +void PumpManager::EnableAutoRestart(bool aOn) +{ + mAutoRestart = aOn; +} + +void PumpManager::SetAutoStartDuration(uint32_t aDurationInSecs) +{ + mAutoStartDuration = aDurationInSecs; +} + +bool PumpManager::InitiateAction(int32_t aActor, Action_t aAction) +{ + bool action_initiated = false; + State_t new_state; + + // Initiate Start/Stop Action only when the previous one is complete. + if (mState == kState_StartCompleted && aAction == STOP_ACTION) + { + action_initiated = true; + mCurrentActor = aActor; + new_state = kState_StopInitiated; + } + else if (mState == kState_StopCompleted && aAction == START_ACTION) + { + action_initiated = true; + mCurrentActor = aActor; + new_state = kState_StartInitiated; + } + + if (action_initiated) + { + if (mAutoStartTimerArmed && new_state == kState_StartInitiated) + { + // If auto start timer has been armed and someone initiates start, + // cancel the timer and continue as normal. + mAutoStartTimerArmed = false; + + CancelTimer(); + } + + PumpTimer(ACTUATOR_MOVEMENT_PERIOS_MS); + + // Since the timer started successfully, update the state and trigger callback + mState = new_state; + + if (mActionInitiated_CB) + { + mActionInitiated_CB(aAction, aActor); + } + } + return action_initiated; +} + +void PumpManager::PumpTimer(uint32_t aTimeoutMs) +{ + xTimerChangePeriod(mTimerHandle, pdMS_TO_TICKS(aTimeoutMs), 100); + xTimerStart(mTimerHandle, 100); +} + +void PumpManager::CancelTimer(void) +{ + xTimerStop(mTimerHandle, 100); +} + +void PumpManager::TimerEventHandler(TimerHandle_t aTimer) +{ + PumpManager * pump = static_cast(pvTimerGetTimerID(aTimer)); + + // The timer event handler will be called in the context of the timer task + // once sPumpTimer expires. Post an event to apptask queue with the actual handler + // so that the event can be handled in the context of the apptask. + AppEvent event; + event.Type = AppEvent::kEventType_AppEvent; + event.PumpStateEvent.Context = static_cast(pump); + if (pump->mAutoStartTimerArmed) + { + event.Handler = AutoRestartTimerEventHandler; + } + else + { + event.Handler = ActuatorMovementTimerEventHandler; + } + GetAppTask().PostEvent(&event); +} + +void PumpManager::AutoRestartTimerEventHandler(AppEvent * aEvent) +{ + PumpManager * pump = static_cast(aEvent->PumpStateEvent.Context); + int32_t actor = 0; + + // Make sure auto start timer is still armed. + if (!pump->mAutoStartTimerArmed) + { + return; + } + + pump->mAutoStartTimerArmed = false; + + PLAT_LOG("Auto Re-Start has been triggered!"); + + pump->InitiateAction(actor, START_ACTION); +} + +void PumpManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent) +{ + Action_t actionCompleted = INVALID_ACTION; + + PumpManager * pump = static_cast(aEvent->PumpStateEvent.Context); + + if (pump->mState == kState_StartInitiated) + { + pump->mState = kState_StartCompleted; + actionCompleted = START_ACTION; + } + else if (pump->mState == kState_StopInitiated) + { + pump->mState = kState_StopCompleted; + actionCompleted = STOP_ACTION; + } + + if (actionCompleted != INVALID_ACTION) + { + if (pump->mActionCompleted_CB) + { + pump->mActionCompleted_CB(actionCompleted, pump->mCurrentActor); + } + + if (pump->mAutoRestart && actionCompleted == STOP_ACTION) + { + // Start the timer for auto restart + pump->PumpTimer(pump->mAutoStartDuration * 1000); + + pump->mAutoStartTimerArmed = true; + + PLAT_LOG("Auto Re-start enabled. Will be triggered in %u seconds", pump->mAutoStartDuration); + } + } +} + +int16_t PumpManager::GetMaxPressure() +{ + // 1.6.1. MaxPressure Attribute + // Range -3276.7 kPa to 3276.7 kPa (steps of 0.1 kPa) + // -3276.8 is invalid value - perhaps 'null' + + // Return 2000.0 kPa as Max Pressure + return 20000; +} + +uint16_t PumpManager::GetMaxSpeed() +{ + // 1.6.2. MaxSpeed Attribute + // Range 0 RPM to 65534 RPM (steps of 1 RPM) + // 65535 is invalid value - perhaps 'null' + + // Return 1000 RPM as MaxSpeed + return 1000; +} + +uint16_t PumpManager::GetMaxFlow() +{ + // 1.6.3. MaxFlow Attribute + // Range 0 m3/h to 6553.4 m3/h (steps of 0.1 m3/h) + // 6553.5 m3/h is invalid value - perhaps 'null' + + // Return 200.0 m3/h as MaxFlow + return 2000; +} + +int16_t PumpManager::GetMinConstPressure() +{ + // 1.6.4. MinConstPressure Attribute + // Range -3276.7 kPa to 3276.7 kPa (steps of 0.1 kPa) + // -3276.8 is invalid value - perhaps 'null' + + // Return -100.0 kPa as MinConstPressure + return -1000; +} + +int16_t PumpManager::GetMaxConstPressure() +{ + // 1.6.5. MaxConstPressure Attribute + // Range -3276.7 kPa to 3276.7 kPa (steps of 0.1 kPa) + // -3276.8 is invalid value - perhaps 'null' + + // Return 100.0 kPa as MaxConstPressure + return 1000; +} + +int16_t PumpManager::GetMinCompPressure() +{ + // 1.6.6. MinCompPressure Attribute + // Range -3276.7 kPa to 3276.7 kPa (steps of 0.1 kPa) + // -3276.8 is invalid value - perhaps 'null' + + // Return -20.0 kPa as MinCompPressure + return -200; +} + +int16_t PumpManager::GetMaxCompPressure() +{ + // 1.6.7. MaxCompPressure Attribute + // Range -3276.7 kPa to 3276.7 kPa (steps of 0.1 kPa) + // -3276.8 is invalid value - perhaps 'null' + + // Return 20.0 kPa as MaxCompPressure + return 200; +} + +uint16_t PumpManager::GetMinConstSpeed() +{ + // 1.6.8. MinConstSpeed Attribute + // Range 0 to 65534 RPM (steps of 1 RPM) + // 65535 RPM is invalid valud - perhaps 'null' + + // Return 200 RPM as MinConstSpeed + return 200; +} + +uint16_t PumpManager::GetMaxConstSpeed() +{ + // 1.6.9. MaxConstSpeed Attribute + // Range 0 to 65534 RPM (steps of 1 RPM) + // 65535 RPM is invalid valud - perhaps 'null' + + // Return 2000 RPM as MaxConstSpeed + return 2000; +} + +uint16_t PumpManager::GetMinConstFlow() +{ + // 1.6.10. MinConstFlow Attribute + // Range 0 m3/h to 6553.4 m3/h (steps of 0.1 m3/h) + // 6553.5 m3/h is invalid value - perhaps 'null' + + // Return 12.5 m3/h as MinConstFlow + return 125; +} + +uint16_t PumpManager::GetMaxConstFlow() +{ + // 1.6.11. MaxConstFlow Attribute + // Range 0 m3/h to 6553.4 m3/h (steps of 0.1 m3/h) + // 6553.5 m3/h is invalid value - perhaps 'null' + + // Return 655.7 m3/h as MaxConstFlow + return 6557; +} + +int16_t PumpManager::GetMinConstTemp() +{ + // 1.6.12. MinConstTemp Attribute + // Range -273.15 C to 327.67 C (steps of 0.01 C) + // All other values are invalid values - perhaps 'null' + + // Return 30.00 C as MinConstTemp + return 3000; +} + +int16_t PumpManager::GetMaxConstTemp() +{ + // 1.6.13. MaxConstTemp Attribute + // Range -273.15 C to 327.67 C (steps of 0.01 C) + // All other values are invalid values - perhaps 'null' + + // Return 56.00 C as MaxConstTemp + return 5600; +} diff --git a/examples/pump-app/cc13x4_26x4/main/ZclCallbacks.cpp b/examples/pump-app/cc13x4_26x4/main/ZclCallbacks.cpp new file mode 100644 index 00000000000000..54faa0db6e7314 --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/main/ZclCallbacks.cpp @@ -0,0 +1,55 @@ +/* + * + * Copyright (c) 2020 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. + */ + +#include + +#include "AppConfig.h" +#include "AppTask.h" +#include "PumpManager.h" + +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::app::Clusters; + +/** @brief OnOff Cluster Init + * + * This function is called when a specific cluster is initialized. It gives the + * application an opportunity to take care of cluster initialization procedures. + * It is called exactly once for each endpoint where cluster is present. + * + * @param endpoint Ver.: always + * + * TODO Issue #3841 + * emberAfOnOffClusterInitCallback happens before the stack initialize the cluster + * attributes to the default value. + * The logic here expects something similar to the deprecated Plugins callback + * emberAfPluginOnOffClusterServerPostInitCallback. + * + */ +void emberAfOnOffClusterInitCallback(EndpointId endpoint) +{ + GetAppTask().InitOnOffClusterState(); +} + +void emberAfPumpConfigurationAndControlClusterInitCallback(chip::EndpointId endpoint) +{ + GetAppTask().InitPCCClusterState(); +} diff --git a/examples/pump-app/cc13x4_26x4/main/include/AppConfig.h b/examples/pump-app/cc13x4_26x4/main/include/AppConfig.h new file mode 100644 index 00000000000000..b925344ddb4c9a --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/main/include/AppConfig.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef APP_CONFIG_H +#define APP_CONFIG_H + +// Logging +#ifdef __cplusplus +extern "C" { +#endif + +int cc13xx_26xxLogInit(void); +void cc13xx_26xxLog(const char * aFormat, ...); +#define PLAT_LOG(...) cc13xx_26xxLog(__VA_ARGS__); + +#ifdef __cplusplus +} +#endif +#endif // APP_CONFIG_H diff --git a/examples/pump-app/cc13x4_26x4/main/include/AppEvent.h b/examples/pump-app/cc13x4_26x4/main/include/AppEvent.h new file mode 100644 index 00000000000000..3a9c606e95c330 --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/main/include/AppEvent.h @@ -0,0 +1,63 @@ +/* + * + * Copyright (c) 2021 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. + */ + +#ifndef APP_EVENT_H +#define APP_EVENT_H + +struct AppEvent; +typedef void (*EventHandler)(AppEvent *); + +struct AppEvent +{ + enum AppEventType + { + kEventType_None = 0, + kEventType_ButtonLeft, + kEventType_ButtonRight, + kEventType_AppEvent, + kEventType_IdentifyStart, + kEventType_IdentifyStop, + }; + + enum AppEventButtonType + { + kAppEventButtonType_None = 0, + kAppEventButtonType_Clicked, + kAppEventButtonType_LongClicked, + kAppEventButtonType_LongPressed, + }; + + enum AppEventType Type; + + union + { + struct + { + enum AppEventButtonType Type; + } ButtonEvent; + + struct + { + void * Context; + } PumpStateEvent; + }; + + EventHandler Handler; +}; + +#endif // APP_EVENT_H diff --git a/examples/pump-app/cc13x4_26x4/main/include/AppTask.h b/examples/pump-app/cc13x4_26x4/main/include/AppTask.h new file mode 100644 index 00000000000000..7fd3f38ff6f0d5 --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/main/include/AppTask.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APP_TASK_H +#define APP_TASK_H + +#include +#include + +#include "FreeRTOS.h" +#include "semphr.h" +#include "task.h" + +#include "AppEvent.h" +#include "PumpManager.h" + +#include + +struct Identify; + +class AppTask +{ +public: + int StartAppTask(); + static void AppTaskMain(void * pvParameter); + + void PostStartActionRequest(int32_t aActor, PumpManager::Action_t aAction); + void PostEvent(const AppEvent * event); + void UpdateClusterState(); + void InitOnOffClusterState(); + void InitPCCClusterState(); + + static void IdentifyStartHandler(::Identify *); + static void IdentifyStopHandler(::Identify *); + static void TriggerIdentifyEffectHandler(::Identify * identify); + +private: + friend AppTask & GetAppTask(void); + + int Init(); + + static void ActionInitiated(PumpManager::Action_t aAction, int32_t aActor); + static void ActionCompleted(PumpManager::Action_t aAction, int32_t aActor); + + static void UpdateCluster(intptr_t context); + + void DispatchEvent(AppEvent * event); + + static void ButtonLeftEventHandler(Button_Handle handle, Button_EventMask events); + static void ButtonRightEventHandler(Button_Handle handle, Button_EventMask events); + static void TimerEventHandler(void * p_context); + static void PostEvents(intptr_t context); + + enum Function_t + { + kFunction_NoneSelected = 0, + kFunction_SoftwareUpdate = 0, + kFunction_FactoryReset, + + kFunction_Invalid + } Function; + + Function_t mFunction; + bool mFunctionTimerActive; + + static AppTask sAppTask; +}; + +inline AppTask & GetAppTask(void) +{ + return AppTask::sAppTask; +} + +#endif // APP_TASK_H diff --git a/examples/pump-app/cc13x4_26x4/main/include/CHIPDeviceManager.h b/examples/pump-app/cc13x4_26x4/main/include/CHIPDeviceManager.h new file mode 100644 index 00000000000000..01703fe335b6af --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/main/include/CHIPDeviceManager.h @@ -0,0 +1,144 @@ +/* + * + * 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. + */ + +/** + * @file + * This file contains definitions for the CHIP DeviceManager Interface + * + * This object will co-ordinate multiple activities such as + * initialisation, rendezvous, session mgmt and other such + * activities within the CHIP stack. This is a singleton object. + */ + +#pragma once + +#include +#include +#include + +#include + +#include +#include + +#include + +namespace chip { +namespace DeviceManager { + +/** + * @brief + * This class provides a skeleton for all the callback functions. The functions will be + * called by other objects within the CHIP stack for specific events. + * Applications interested in receiving specific callbacks can specialize this class and handle + * these events in their implementation of this class. + */ +class DLL_EXPORT CHIPDeviceManagerCallbacks +{ +public: + /** + * @brief + * Called when CHIP Device events (PublicEventTypes) are triggered. + * + * @param event ChipDeviceEvent that occurred + * @param arg arguments specific to the event, if any + */ + virtual void DeviceEventCallback(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + /** + * @brief + * Called after an attribute has been changed + * + * @param endpoint endpoint id + * @param clusterID cluster id + * @param attributeId attribute id that was changed + * @param mask mask of the attribute + * @param manufacturerCode manufacturer code + * @param type attribute type + * @param size size of the attribute + * @param value pointer to the new value + */ + virtual void PostAttributeChangeCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, chip::AttributeId attributeId, + uint8_t type, uint16_t size, uint8_t * value) + {} + /** + * @brief + * Called just before an attribute will be changed + * + * @param endpoint endpoint id + * @param clusterID cluster id + * @param attributeId attribute id that was changed + * @param mask mask of the attribute + * @param manufacturerCode manufacturer code + * @param type attribute type + * @param size size of the attribute + * @param value pointer to the new value + * + * @return Success if the attribute can be changed, otherwise Failed. + */ + virtual chip::Protocols::InteractionModel::Status PreAttributeChangeCallback(chip::EndpointId endpoint, + chip::ClusterId clusterId, + chip::AttributeId attributeId, uint8_t type, + uint16_t size, uint8_t * value) + { + return chip::Protocols::InteractionModel::Status::Success; + } + virtual ~CHIPDeviceManagerCallbacks() {} +}; + +/** + * @brief + * A common class that drives other components of the CHIP stack + */ +class DLL_EXPORT CHIPDeviceManager +{ +public: + CHIPDeviceManager(const CHIPDeviceManager &) = delete; + CHIPDeviceManager(const CHIPDeviceManager &&) = delete; + CHIPDeviceManager & operator=(const CHIPDeviceManager &) = delete; + + static CHIPDeviceManager & GetInstance() + { + static CHIPDeviceManager instance; + return instance; + } + + /** + * @brief + * Initialise CHIPDeviceManager + * + * @param cb Application's instance of the CHIPDeviceManagerCallbacks for consuming events + */ + CHIP_ERROR Init(CHIPDeviceManagerCallbacks * cb); + /** + * @brief + * Fetch a pointer to the registered CHIPDeviceManagerCallbacks object. + * + */ + CHIPDeviceManagerCallbacks * GetCHIPDeviceManagerCallbacks() { return mCB; } + + /** + * Use internally for registration of the ChipDeviceEvents + */ + static void CommonDeviceEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + +private: + CHIPDeviceManagerCallbacks * mCB = nullptr; + CHIPDeviceManager() {} +}; + +} // namespace DeviceManager +} // namespace chip diff --git a/examples/pump-app/cc13x4_26x4/main/include/CHIPProjectConfig.h b/examples/pump-app/cc13x4_26x4/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..49a0e036a33181 --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/main/include/CHIPProjectConfig.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * 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. + * + */ + +#ifndef CHIP_PROJECT_CONFIG_H +#define CHIP_PROJECT_CONFIG_H + +// Security and Authentication always enabled +#define CHIP_CONFIG_SECURITY_TEST_MODE 0 + +#if BUILD_RELEASE // release build +// Note: Default Pairing/PIN/Serial Numbers being used. These should not be enabled for production builds +#endif // BUILD_RELEASE + +// 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 + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 1 + +/** + * Values set by args.gni: + * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION + */ + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + * + * Enable support for CHIP-over-BLE (CHIPOBLE). + */ +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote CHIP Time service + * using the CHIP Time Sync protocol. + */ +// #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 + +/** + * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE + * + * A size, in bytes, of the individual debug event logging buffer. + */ +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) + +#define MATTER_CC13XX_26XX_PLATFORM_LOG_ENABLED 1 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + * + * Enable the OpenThread SRP client to allow for CHIP device discovery. + */ +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT 1 + +/** + * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE + * + * For a development build, set the default importance of events to be logged as Debug. + * Since debug is the lowest importance level, this means all standard, critical, info and + * debug importance level vi events get logged. + */ +#if BUILD_RELEASE +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production +#else +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug +#endif // BUILD_RELEASE + +#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 + +/** + * @def CHIP_IM_MAX_NUM_COMMAND_HANDLER + * + * @brief Defines the maximum number of CommandHandler, limits the number of active commands transactions on server. + * + * TODO: (#17080) 1 should be OK since almost all commands are synchronous, should be some larger number after we resolved the issue + * of the large memory footprint of ReadHandler. + */ +#define CHIP_IM_MAX_NUM_COMMAND_HANDLER 1 + +/** + * @def CHIP_IM_MAX_NUM_WRITE_HANDLER + * + * @brief Defines the maximum number of WriteHandler, limits the number of active write transactions on server. + * + * TODO: (#17080) 1 should be OK since most write requests can be synchronous (not chunked), should be some larger number after we + * resolved the issue of the large memory footprint of ReadHandler. + */ +#define CHIP_IM_MAX_NUM_WRITE_HANDLER 1 + +#endif // CHIP_PROJECT_CONFIG_H diff --git a/examples/pump-app/cc13x4_26x4/main/include/DeviceCallbacks.h b/examples/pump-app/cc13x4_26x4/main/include/DeviceCallbacks.h new file mode 100644 index 00000000000000..7e2633b54bb9db --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/main/include/DeviceCallbacks.h @@ -0,0 +1,49 @@ +/* + * + * Copyright (c) 2021 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 DeviceCallbacks.h + * + * Implementations for the DeviceManager callbacks for this application + * + **/ + +#pragma once + +#include "CHIPDeviceManager.h" +#include +#include + +class DeviceCallbacks : public chip::DeviceManager::CHIPDeviceManagerCallbacks +{ +public: + virtual void DeviceEventCallback(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + virtual chip::Protocols::InteractionModel::Status PreAttributeChangeCallback(chip::EndpointId endpointId, + chip::ClusterId clusterId, + chip::AttributeId attributeId, uint8_t type, + uint16_t size, uint8_t * value); + virtual void PostAttributeChangeCallback(chip::EndpointId endpointId, chip::ClusterId clusterId, chip::AttributeId attributeId, + uint8_t type, uint16_t size, uint8_t * value); + +private: + void OnInternetConnectivityChange(const chip::DeviceLayer::ChipDeviceEvent * event); + void OnThreadConnectivityChange(const chip::DeviceLayer::ChipDeviceEvent * event); + void OnIdentifyPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); + void OnOnOffPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); + void OnLevelControlAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); +}; diff --git a/examples/pump-app/cc13x4_26x4/main/include/OpenThreadConfig.h b/examples/pump-app/cc13x4_26x4/main/include/OpenThreadConfig.h new file mode 100644 index 00000000000000..7d227258b1eaae --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/main/include/OpenThreadConfig.h @@ -0,0 +1,29 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * 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 + * Overrides to default OpenThread configuration. + * + */ + +#pragma once + +// Use the TI-supplied default platform configuration for remainder +#include "openthread-core-cc13x4_26x4-config.h" diff --git a/examples/pump-app/cc13x4_26x4/main/include/PumpManager.h b/examples/pump-app/cc13x4_26x4/main/include/PumpManager.h new file mode 100644 index 00000000000000..ea742c22acb765 --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/main/include/PumpManager.h @@ -0,0 +1,102 @@ +/* + * + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PUMP_MANAGER_H +#define PUMP_MANAGER_H + +#include +#include + +#include "AppEvent.h" + +#include +#include + +class PumpManager +{ +public: + enum Action_t + { + START_ACTION = 0, + STOP_ACTION, + + INVALID_ACTION + } Action; + + enum State_t + { + kState_StartInitiated = 0, + kState_StartCompleted, + kState_StopInitiated, + kState_StopCompleted, + } State; + + int Init(); + bool IsStopped(); + void EnableAutoRestart(bool aOn); + void SetAutoStartDuration(uint32_t aDurationInSecs); + bool IsActionInProgress(); + bool InitiateAction(int32_t aActor, Action_t aAction); + + int16_t GetMaxPressure(); + uint16_t GetMaxSpeed(); + uint16_t GetMaxFlow(); + int16_t GetMinConstPressure(); + int16_t GetMaxConstPressure(); + int16_t GetMinCompPressure(); + int16_t GetMaxCompPressure(); + uint16_t GetMinConstSpeed(); + uint16_t GetMaxConstSpeed(); + uint16_t GetMinConstFlow(); + uint16_t GetMaxConstFlow(); + int16_t GetMinConstTemp(); + int16_t GetMaxConstTemp(); + + typedef void (*Callback_fn_initiated)(Action_t, int32_t aActor); + typedef void (*Callback_fn_completed)(Action_t, int32_t aActor); + void SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB); + +private: + friend PumpManager & PumpMgr(void); + State_t mState; + + Callback_fn_initiated mActionInitiated_CB; + Callback_fn_completed mActionCompleted_CB; + + bool mAutoRestart; + uint32_t mAutoStartDuration; + bool mAutoStartTimerArmed; + TimerHandle_t mTimerHandle; + int32_t mCurrentActor; + + void CancelTimer(void); + void PumpTimer(uint32_t aTimeoutMs); + + static void TimerEventHandler(TimerHandle_t aTimer); + static void AutoRestartTimerEventHandler(AppEvent * aEvent); + static void ActuatorMovementTimerEventHandler(AppEvent * aEvent); + + static PumpManager sPump; +}; + +inline PumpManager & PumpMgr(void) +{ + return PumpManager::sPump; +} + +#endif // PUMP_MANAGER_H diff --git a/examples/pump-app/cc13x4_26x4/main/main.cpp b/examples/pump-app/cc13x4_26x4/main/main.cpp new file mode 100644 index 00000000000000..ba98379ecc741a --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/main/main.cpp @@ -0,0 +1,104 @@ +/* + * + * Copyright (c) 2020 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. + */ + +#include +#include + +#include + +#include +#include + +#include + +/* Driver Header files */ +#include +#include +#include + +#include +#include +#include +#include + +#include +#define TOTAL_ICALL_HEAP_SIZE (0xC700) + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::DeviceLayer; + +__attribute__((section(".heap"))) uint8_t GlobalHeapZoneBuffer[TOTAL_ICALL_HEAP_SIZE]; +uint32_t heapSize = TOTAL_ICALL_HEAP_SIZE; + +// ================================================================================ +// FreeRTOS Callbacks +// ================================================================================ +extern "C" void vApplicationStackOverflowHook(void) +{ + while (true) + { + ; + } +} + +/* Wrapper functions for using the queue registry regardless of whether it is enabled or disabled */ +extern "C" void vQueueAddToRegistryWrapper(QueueHandle_t xQueue, const char * pcQueueName) +{ + /* This function is intentionally left empty as the Queue Registry is disabled */ +} + +extern "C" void vQueueUnregisterQueueWrapper(QueueHandle_t xQueue) +{ + /* This function is intentionally left empty as the Queue Registry is disabled */ +} + +// ================================================================================ +// Main Code +// ================================================================================ +int main(void) +{ + Board_init(); + bpool((void *) GlobalHeapZoneBuffer, TOTAL_ICALL_HEAP_SIZE); + + GPIO_init(); + + NVS_init(); + + ECDH_init(); + + ECDSA_init(); + + AESECB_init(); + + SHA2_init(); + + int ret = GetAppTask().StartAppTask(); + if (ret != 0) + { + // can't log until the kernel is started + // PLAT_LOG("GetAppTask().StartAppTask() failed"); + while (true) + ; + } + + vTaskStartScheduler(); + + // Should never get here. + while (true) + ; +} diff --git a/examples/pump-app/cc13x4_26x4/third_party/connectedhomeip b/examples/pump-app/cc13x4_26x4/third_party/connectedhomeip new file mode 120000 index 00000000000000..c866b86874994d --- /dev/null +++ b/examples/pump-app/cc13x4_26x4/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../.. \ No newline at end of file diff --git a/examples/pump-controller-app/cc13x2x7_26x2x7/README.md b/examples/pump-controller-app/cc13x2x7_26x2x7/README.md index 5b17d395da1b47..90df4c9c7bd521 100644 --- a/examples/pump-controller-app/cc13x2x7_26x2x7/README.md +++ b/examples/pump-controller-app/cc13x2x7_26x2x7/README.md @@ -1,33 +1,29 @@ -# Matter CC1352 CC2652 Pump Controller Example Application +# Matter Pump Controller Example Application An example application showing the use of [Matter][matter] on the Texas Instruments CC13XX_26XX family of Wireless MCUs. --- -- [Matter CC1352 CC2652 Pump Controller Example Application](#matter-cc1352-cc2652-pump-controller-example-application) +- [Matter Pump Controller Example Application](#matter-pump-controller-example-application) - [Introduction](#introduction) - [Device UI](#device-ui) - [Building](#building) - [Preparation](#preparation) - [Compilation](#compilation) - [Programming](#programming) - - [UniFlash](#uniflash) - [Code Composer Studio](#code-composer-studio) - - [Viewing Logging Output](#viewing-logging-output) + - [UniFlash](#uniflash) - [Running the Example](#running-the-example) - [Provisioning](#provisioning) - [Bluetooth LE Advertising](#bluetooth-le-advertising) - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) - - [Matter Remote Commands](#matter-remote-commands) - [TI Support](#ti-support) --- ## Introduction -![CC1352R1_LAUNCHXL](doc/images/cc1352r1_launchxl.jpg) - The CC13XX_26XX pump controller example application provides a working demonstration of a connected pump controller device. This uses the open-source Matter implementation and the Texas Instruments SimpleLinkā„¢ CC13XX and CC26XX @@ -41,20 +37,14 @@ Instruments devices. ## Device UI -This example application has a simple User Interface to depict the state of the -pump and to control the state. The user LEDs on the LaunchPad are set on when -the pump is started, and are set off when stopped. The LEDs will flash when in -the transition state between started and stopped. - -Short presses (less than 1000ms) of the right user button (`BTN-2`) are used for -toggling the pump state. - -Short presses (less than 1000ms) of the left user button (`BTN-1`) are used for -toggling Matter BLE advertisements. - -Long presses (greater than 5000ms) of the left user button (`BTN-1`) will -initiate a factory reset of the device clearing all stored provisioning -information to allow for a new network setup. +| Action | Functionality | +| ------------------------------------------------ | -------------------------------------- | +| Left Button (`BTN-1`) Press (less than 1000 ms) | BLE Advertisement (Enable/Disable) | +| Left Button (`BTN-1`) Press (more than 5000 ms) | Factory Reset | +| Right Button (`BTN-2`) Press (less than 1000 ms) | Toggle pump state | +| Red & Green LED Blinking State | Pump transition from either Start/Stop | +| Red & LED On State | Pump is started | +| Red & Green LED Off State | Pump stopped | ## Building @@ -64,15 +54,14 @@ Some initial setup is necessary for preparing the build environment. This section will need to be done when migrating to new versions of the SDK. This guide assumes that the environment is linux based, and recommends Ubuntu 20.04. -- Download and install [SysConfig][sysconfig] ([recommended - version][sysconfig_recommended]). This can be done simply with the following - commands. +- Download and install [SysConfig][sysconfig]. This can be done simply with + the following commands. ``` $ cd ~ - $ wget https://software-dl.ti.com/ccs/esd/sysconfig/sysconfig-1.11.0_2225-setup.run - $ chmod +x sysconfig-1.11.0_2225-setup.run - $ ./sysconfig-1.11.0_2225-setup.run + $ `wget https://dr-download.ti.com/software-development/ide-configuration-compiler-or-debugger/MD-nsUM6f7Vvb/1.15.0.2826/sysconfig-1.15.0_2826-setup.run` + $ chmod +x sysconfig-1.15.0_2826-setup.run + $ ./sysconfig-1.15.0_2826-setup.run ``` - Run the bootstrap script to setup the build environment. @@ -99,32 +88,95 @@ Ninja to build the executable. - Run the build to produce a default executable. By default on Linux both the TI SimpleLink SDK and Sysconfig are located in a `ti` folder in the user's home directory, and you must provide the absolute path to them. For example - `/home/username/ti/sysconfig_1.11.0`. On Windows the default directory is + `/home/username/ti/sysconfig_1.15.0`. On Windows the default directory is `C:\ti`. Take note of this install path, as it will be used in the next step. ``` $ cd ~/connectedhomeip/examples/pump-controller-app/cc13x2x7_26x2x7 - $ gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.11.0\"" + OR + $ cd ~/connectedhomeip/examples/pump-controller-app/cc13x4_26x4 + $ gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\"" $ ninja -C out/debug ``` + If you would like to define arguments on the command line you may add them + to the GN call. + + ``` + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\" target_defines=[\"CC13X2_26X2_ATTESTATION_CREDENTIALS=1\"]" + ``` + ## Programming Loading the built image onto a LaunchPad is supported through two methods; Uniflash and Code Composer Studio (CCS). UniFlash can be used to load the image. Code Composer Studio can be used to load the image and debug the source code. +### Code Composer Studio + +Programming with CCS will allow for a full debug environment within the IDE. +This is accomplished by creating a target connection to the XDS110 debugger and +starting a project-less debug session. The CCS IDE will attempt to find the +source files on the local machine based on the debug information embedded within +the ELF. CCS may prompt you to find the source code if the image was built on +another machine or the source code is located in a different location than is +recorded within the ELF. + +Download and install [Code Composer Studio][ccs]. + +First open CCS and create a new workspace. + +Create a target connection (sometimes called the CCXML) for your target SoC and +debugger as described in the [Manual Method][ccs_manual_method] section of the +CCS User's Guide. + +Next initiate a project-less debug session as described in the [Manual +Launch][ccs_manual_launch] section of the CCS User's Guide. + +CCS should switch to the debug view described in the [After +Launch][ccs_after_launch] section of the User's Guide. The SoC core will likely +be disconnected and symbols will not be loaded. Connect to the core as described +in the [Debug View][ccs_debug_view] section of the User's Guide. Once the core +is connected, use the `Load` button on the toolbar to load the ELF image. + +Note that the default configuration of the CCXML uses 2-wire cJTAG instead of +the full 4-wire JTAG connection to match the default jumper configuration of the +LaunchPad. + ### UniFlash -[Programming UniFlash](doc/programming-uniflash.md) +Uniflash is Texas Instrument's uniform programming tool for embedded processors. +This will allow you to erase, flash, and inspect the SoC without setting up a +debugging environment. -### Code Composer Studio +Download and install [UniFlash][uniflash]. -[Programming and Debugging with CCS](doc/programming-ccs.md) +First open UniFlash. Debug probes connected to the computer will usually be +displayed under the Detected Devices due to the automatic device detection +feature. If your device does not show up in this view it my be disconnected, or +you may have to create a New Configuration. If you already have a CCXML for your +SoC and debug connection you can use that in the section at the bottom. Once +your device is selected, click the `Start` button within the section to launch +the session. -## Viewing Logging Output +Select the ELF image to load on the device with the `Browse` button. This file +is placed in the `out/debug` folder by this guide and ends with the `*.out` file +extension. For OTA enabled applications, the standalone image will instead end +with the `*-bim.hex` file extension. This this is a combined image with +application and and `BIM` included. The flag to enable or disable the OTA +feature is determined by "chip_enable_ota_requestor" in the application's +args.gni file. + +Finally click the `Load Image` button to load the executable image onto the +device. You should be able to see the log output over the XDS110 User UART. + +Note that programming the device through JTAG sets the Halt-in-Boot flag and may +cause issues when performing a software reset. This flag can be reset by +power-cycling the LaunchPad. + +## Running the Example By default the log output will be sent to the Application/User UART. Open a terminal emulator to that port to see the output with the following options: @@ -140,68 +192,105 @@ terminal emulator to that port to see the output with the following options: ## Running the Example Once a device has been flashed with this example, it can now join and operate in -an existing Thread network. The following sections assume that a Thread network +an existing Matter network. The following sections assume that a Matter network is already active, and has at least one [OpenThread Border Router][ot_border_router_setup]. -### Provisioning +For insight into what other components are needed to run this example, please +refer to our [Matter Getting Started Guide][matter-e2e-faq]. -The first step to bring the Matter device onto the network is to provision it. -Our example accomplishes this with Bluetooth Low Energy (BLE) and the -[CHIPTool](../../../examples/android/CHIPTool/README.md) mobile app. +The steps below should be followed to commission the device onto the network and +control it once it has been commissioned. -#### Bluetooth LE Advertising +**Step 0** -To provision this example onto a Thread network, the device must be discoverable -over Bluetooth LE. BLE advertising is started by pressing the right button (less -than 1000ms), labeled `BTN-2` on the silkscreen. Once the device is fully -provisioned, BLE advertising will stop. +Set up the CHIP tool by following the instructions outlined in our [Matter +Getting Started Guide][matter-e2e-faq]. -#### Bluetooth LE Rendezvous +**Step 1** + +Commission the device onto the Matter network. Run the following command on the +CHIP tool: + +``` + +./chip-tool pairing ble-thread hex: 20202021 3840 + +``` + +Interacting with the application begins by enabling BLE advertisements and then +pairing the device into a Thread network. To provision this example onto a +Matter network, the device must be discoverable over Bluetooth LE. + +On the LaunchPad, press and hold the right button, labeled `BTN-1`, for more +than 1 second. Upon release, the Bluetooth LE advertising will begin. Once the +device is fully provisioned, BLE advertising will stop. + +Once the device has been successfully commissioned, you will see the following +message on the CHIP tool output: + +``` -In this example, the provisioning procedure (called Rendezvous) is done over -Bluetooth LE between a Matter device (pump-controller-app) and the Matter -controller (CHIPTool), where the controller has the commissioner role. +[1677648218.370754][39785:39790] CHIP:CTL: Received CommissioningComplete response, errorCode=0 +[1677648218.370821][39785:39790] CHIP:CTL: Successfully finished commissioning step 'SendComplete' -To start the rendezvous, the controller must get the commissioning information -from the Matter device. +``` -This is done by scanning a QR code. A URL will be displayed on the pump-app's -log ([UART terminal](#viewing-logging-output)). It will look like the following: +An accompanying message will be seen from the device: ``` -SetupQRCode: [MT:.81TM -00 0C9SS0] -Copy/paste the below URL in a browser to see the QR Code: -https://project-chip.github.io/connectedhomeip/qrcode.html?data=CH%3A.81TM%20-00%200C9SS0 + +Commissioning complete, notify platform driver to persist network credentials. + ``` -You can directly navigate to the webpage URL displayed (which has QR payload -pre-loaded). Alternatively, you can navigate to [the QR code -generator][qr_code_generator] and enter in the payload shown in `SetupQRCode` -(in this case `MT:.81TM -00 0C9SS0`). +**Step 2** Read generic vendor name from Basic cluster -### Matter Remote Commands +``` +./chip-tool basic read vendor-name 1 0 +``` + +### Provisioning -Once the Matter device is provisioned and operating on the network, CHIPTool can -be used to control the device. During the provisioning process, the Matter -device would have sent one of its newly assigned IPv6 addresses to the CHIPTool. +Interacting with the application begins by enabling BLE advertisements and then +pairing the device into a Thread network. + +#### Bluetooth LE Advertising + +To provision this example onto a Thread network, the device must be discoverable +over Bluetooth LE. BLE advertising is started by long pressing the right button +(greater than 1000ms), labeled `BTN-1` on the silkscreen. Once the device is +fully provisioned, BLE advertising will stop. + +#### Bluetooth LE Rendezvous -In the app, you should see an On/Off cluster; this corresponds to the pump-app. -You can now control the pump-controller-app Matter device from the smartphone! +Pairing this application with `ble-thread` can be done with any of the enabled +[CHIP Controller](../../../src/controller/README.md) applications. Use the +information printed on the console to aide in pairing the device. The controller +application can also be used to control the example app with the cluster +commands. ## TI Support For technical support, please consider creating a post on TI's [E2E forum][e2e]. Additionally, we welcome any feedback. -[matter]: https://github.com/project-chip/connectedhomeip -[cc1352r1_launchxl]: https://www.ti.com/tool/LAUNCHXL-CC1352R1 -[e2e]: https://e2e.ti.com/support/wireless-connectivity/zigbee-and-thread +[matter]: https://csa-iot.org/all-solutions/matter/ +[ccs]: https://www.ti.com/tool/CCSTUDIO +[ccs_after_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#after-launch +[ccs_debug_view]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#debug-view +[ccs_manual_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-launch +[ccs_manual_method]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-method +[e2e]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum +[matter-e2e-faq]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/1082428/faq-cc2652r7-matter----getting-started-guide [sysconfig]: https://www.ti.com/tool/SYSCONFIG -[sysconfig_recommended]: - https://software-dl.ti.com/ccs/esd/sysconfig/sysconfig-1.11.0_2225-setup.run [ti_thread_dnd]: https://www.ti.com/wireless-connectivity/thread/design-development.html -[ot_border_router_setup]: - https://openthread.io/guides/border-router/beaglebone-black -[qr_code_generator]: https://project-chip.github.io/connectedhomeip/qrcode.html +[ot_border_router_setup]: https://openthread.io/guides/border-router/build +[uniflash]: https://www.ti.com/tool/download/UNIFLASH diff --git a/examples/pump-controller-app/cc13x4_26x4/.gn b/examples/pump-controller-app/cc13x4_26x4/.gn new file mode 100644 index 00000000000000..3d48789e30ab3d --- /dev/null +++ b/examples/pump-controller-app/cc13x4_26x4/.gn @@ -0,0 +1,28 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/build.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "freertos" + + import("//args.gni") +} diff --git a/examples/pump-controller-app/cc13x4_26x4/BUILD.gn b/examples/pump-controller-app/cc13x4_26x4/BUILD.gn new file mode 100644 index 00000000000000..49fc1b270c7598 --- /dev/null +++ b/examples/pump-controller-app/cc13x4_26x4/BUILD.gn @@ -0,0 +1,118 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/openthread.gni") +import("//build_overrides/ti_simplelink_sdk.gni") + +import("${build_root}/config/defaults.gni") + +import("${chip_root}/src/platform/device.gni") + +import("${ti_simplelink_sdk_build_root}/ti_simplelink_executable.gni") +import("${ti_simplelink_sdk_build_root}/ti_simplelink_sdk.gni") + +assert(current_os == "freertos") + +project_dir = "${chip_root}/examples/pump-controller-app/cc13x4_26x4" + +ti_simplelink_sdk("sdk") { + include_dirs = [ "${project_dir}/main/include" ] + public_configs = [ ":pump_controller_app_config" ] +} + +ti_sysconfig("sysconfig") { + sources = [ "${project_dir}/chip.syscfg" ] + + outputs = [ + "ti_devices_config.c", + "ti_radio_config.c", + "ti_radio_config.h", + "ti_drivers_config.c", + "ti_drivers_config.h", + "ti_ble_config.c", + "ti_ble_config.h", + "ti_dmm_application_policy.c", + "ti_dmm_application_policy.h", + + # disabled until upstream generation is aligned + #"tiop_config.h", + #"tiop_config.c", + + # not traditional source files + #"ti_utils_build_linker.cmd.genlibs", + #"syscfg_c.rov.xs", + #"ti_utils_runtime_model.gv", + #"ti_utils_runtime_Makefile", + #"ti_ble_app_config.opt", + #"ti_build_config.opt", + ] + + public_configs = [ ":sdk_dmm_config" ] + + cflags = [ + "-Wno-comment", + "@" + rebase_path("${target_gen_dir}/sysconfig/ti_ble_app_config.opt", + root_build_dir), + "@" + rebase_path("${target_gen_dir}/sysconfig/ti_build_config.opt", + root_build_dir), + ] +} + +ti_simplelink_executable("pump_controller_app") { + output_name = "chip-${ti_simplelink_board}-pump-controller-example.out" + + sources = [ + "${project_dir}/main/AppTask.cpp", + "${project_dir}/main/PumpManager.cpp", + "${project_dir}/main/ZclCallbacks.cpp", + "${project_dir}/main/main.cpp", + ] + + deps = [ + ":sdk", + ":sysconfig", + "${chip_root}/examples/platform/cc13x4_26x4:cc13x4_26x4-attestation-credentials", + "${chip_root}/examples/pump-controller-app/pump-controller-common", + "${chip_root}/src/lib", + ] + + if (chip_openthread_ftd) { + deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-ftd" ] + } else { + deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-mtd" ] + } + + include_dirs = [ + "${project_dir}", + "${project_dir}/main", + ] + + cflags = [ + "-Wno-implicit-fallthrough", + "-Wno-sign-compare", + "-Wconversion", + ] + + output_dir = root_out_dir +} + +group("cc13x4_26x4") { + deps = [ ":pump_controller_app" ] +} + +group("default") { + deps = [ ":cc13x4_26x4" ] +} diff --git a/examples/pump-controller-app/cc13x4_26x4/README.md b/examples/pump-controller-app/cc13x4_26x4/README.md new file mode 100644 index 00000000000000..dc917f93c5544e --- /dev/null +++ b/examples/pump-controller-app/cc13x4_26x4/README.md @@ -0,0 +1,298 @@ +# Matter Pump Controller Example Application + +An example application showing the use of [Matter][matter] on the Texas +Instruments CC13XX_26XX family of Wireless MCUs. + +--- + +- [Matter Pump Controller Example Application](#matter-pump-controller-example-application) + - [Introduction](#introduction) + - [Device UI](#device-ui) + - [Building](#building) + - [Preparation](#preparation) + - [Compilation](#compilation) + - [Programming](#programming) + - [Code Composer Studio](#code-composer-studio) + - [UniFlash](#uniflash) + - [Running the Example](#running-the-example) + - [Provisioning](#provisioning) + - [Bluetooth LE Advertising](#bluetooth-le-advertising) + - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) + - [TI Support](#ti-support) + +--- + +## Introduction + +The CC13XX_26XX pump controller example application provides a working +demonstration of a connected pump controller device. This uses the open-source +Matter implementation and the Texas Instruments SimpleLinkā„¢ CC13XX and CC26XX +software development kit. + +This example is enabled to build for CC1354P10 devices. + +The pump example is intended to serve both as a means to explore the workings of +Matter, as well as a template for creating real products based on the Texas +Instruments devices. + +## Device UI + +| Action | Functionality | +| ------------------------------------------------ | -------------------------------------- | +| Left Button (`BTN-1`) Press (less than 1000 ms) | BLE Advertisement (Enable/Disable) | +| Left Button (`BTN-1`) Press (more than 5000 ms) | Factory Reset | +| Right Button (`BTN-2`) Press (less than 1000 ms) | Toggle pump state | +| Red & Green LED Blinking State | Pump transition from either Start/Stop | +| Red & LED On State | Pump is started | +| Red & Green LED Off State | Pump stopped | + +## Building + +### Preparation + +Some initial setup is necessary for preparing the build environment. This +section will need to be done when migrating to new versions of the SDK. This +guide assumes that the environment is linux based, and recommends Ubuntu 20.04. + +- Download and install [SysConfig][sysconfig]. This can be done simply with + the following commands. + + ``` + $ cd ~ + $ `wget https://dr-download.ti.com/software-development/ide-configuration-compiler-or-debugger/MD-nsUM6f7Vvb/1.15.0.2826/sysconfig-1.15.0_2826-setup.run` + $ chmod +x sysconfig-1.15.0_2826-setup.run + $ ./sysconfig-1.15.0_2826-setup.run + ``` + +- Run the bootstrap script to setup the build environment. + + ``` + $ cd ~/connectedhomeip + $ source ./scripts/bootstrap.sh + + ``` + +### Compilation + +It is necessary to activate the environment in every new shell. Then run GN and +Ninja to build the executable. + +- Activate the build environment with the repository activate script. + + ``` + $ cd ~/connectedhomeip + $ source ./scripts/activate.sh + + ``` + +- Run the build to produce a default executable. By default on Linux both the + TI SimpleLink SDK and Sysconfig are located in a `ti` folder in the user's + home directory, and you must provide the absolute path to them. For example + `/home/username/ti/sysconfig_1.15.0`. On Windows the default directory is + `C:\ti`. Take note of this install path, as it will be used in the next + step. + + ``` + $ cd ~/connectedhomeip/examples/pump-controller-app/cc13x2x7_26x2x7 + OR + $ cd ~/connectedhomeip/examples/pump-controller-app/cc13x4_26x4 + $ gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\"" + $ ninja -C out/debug + + ``` + + If you would like to define arguments on the command line you may add them + to the GN call. + + ``` + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + ``` + +## Programming + +Loading the built image onto a LaunchPad is supported through two methods; +Uniflash and Code Composer Studio (CCS). UniFlash can be used to load the image. +Code Composer Studio can be used to load the image and debug the source code. + +### Code Composer Studio + +Programming with CCS will allow for a full debug environment within the IDE. +This is accomplished by creating a target connection to the XDS110 debugger and +starting a project-less debug session. The CCS IDE will attempt to find the +source files on the local machine based on the debug information embedded within +the ELF. CCS may prompt you to find the source code if the image was built on +another machine or the source code is located in a different location than is +recorded within the ELF. + +Download and install [Code Composer Studio][ccs]. + +First open CCS and create a new workspace. + +Create a target connection (sometimes called the CCXML) for your target SoC and +debugger as described in the [Manual Method][ccs_manual_method] section of the +CCS User's Guide. + +Next initiate a project-less debug session as described in the [Manual +Launch][ccs_manual_launch] section of the CCS User's Guide. + +CCS should switch to the debug view described in the [After +Launch][ccs_after_launch] section of the User's Guide. The SoC core will likely +be disconnected and symbols will not be loaded. Connect to the core as described +in the [Debug View][ccs_debug_view] section of the User's Guide. Once the core +is connected, use the `Load` button on the toolbar to load the ELF image. + +Note that the default configuration of the CCXML uses 2-wire cJTAG instead of +the full 4-wire JTAG connection to match the default jumper configuration of the +LaunchPad. + +### UniFlash + +Uniflash is Texas Instrument's uniform programming tool for embedded processors. +This will allow you to erase, flash, and inspect the SoC without setting up a +debugging environment. + +Download and install [UniFlash][uniflash]. + +First open UniFlash. Debug probes connected to the computer will usually be +displayed under the Detected Devices due to the automatic device detection +feature. If your device does not show up in this view it my be disconnected, or +you may have to create a New Configuration. If you already have a CCXML for your +SoC and debug connection you can use that in the section at the bottom. Once +your device is selected, click the `Start` button within the section to launch +the session. + +Select the ELF image to load on the device with the `Browse` button. This file +is placed in the `out/debug` folder by this guide and ends with the `*.out` file +extension. For OTA enabled applications, the standalone image will instead end +with the `*-bim.hex` file extension. This this is a combined image with +application and and `BIM` included. The flag to enable or disable the OTA +feature is determined by "chip_enable_ota_requestor" in the application's +args.gni file. + +Finally click the `Load Image` button to load the executable image onto the +device. You should be able to see the log output over the XDS110 User UART. + +Note that programming the device through JTAG sets the Halt-in-Boot flag and may +cause issues when performing a software reset. This flag can be reset by +power-cycling the LaunchPad. + +## Running the Example + +By default the log output will be sent to the Application/User UART. Open a +terminal emulator to that port to see the output with the following options: + +| Parameter | Value | +| ------------ | -------- | +| Speed (baud) | `115200` | +| Data bits | `8` | +| Stop bits | `1` | +| Parity | `None` | +| Flow control | `None` | + +## Running the Example + +Once a device has been flashed with this example, it can now join and operate in +an existing Matter network. The following sections assume that a Matter network +is already active, and has at least one [OpenThread Border +Router][ot_border_router_setup]. + +For insight into what other components are needed to run this example, please +refer to our [Matter Getting Started Guide][matter-e2e-faq]. + +The steps below should be followed to commission the device onto the network and +control it once it has been commissioned. + +**Step 0** + +Set up the CHIP tool by following the instructions outlined in our [Matter +Getting Started Guide][matter-e2e-faq]. + +**Step 1** + +Commission the device onto the Matter network. Run the following command on the +CHIP tool: + +``` + +./chip-tool pairing ble-thread hex: 20202021 3840 + +``` + +Interacting with the application begins by enabling BLE advertisements and then +pairing the device into a Thread network. To provision this example onto a +Matter network, the device must be discoverable over Bluetooth LE. + +On the LaunchPad, press and hold the right button, labeled `BTN-1`, for more +than 1 second. Upon release, the Bluetooth LE advertising will begin. Once the +device is fully provisioned, BLE advertising will stop. + +Once the device has been successfully commissioned, you will see the following +message on the CHIP tool output: + +``` + +[1677648218.370754][39785:39790] CHIP:CTL: Received CommissioningComplete response, errorCode=0 +[1677648218.370821][39785:39790] CHIP:CTL: Successfully finished commissioning step 'SendComplete' + +``` + +An accompanying message will be seen from the device: + +``` + +Commissioning complete, notify platform driver to persist network credentials. + +``` + +**Step 2** + +Read generic vendor name from Basic cluster + +``` +./chip-tool basic read vendor-name 1 0 +``` + +### Provisioning + +Interacting with the application begins by enabling BLE advertisements and then +pairing the device into a Thread network. + +#### Bluetooth LE Advertising + +To provision this example onto a Thread network, the device must be discoverable +over Bluetooth LE. BLE advertising is started by long pressing the right button +(greater than 1000ms), labeled `BTN-1` on the silkscreen. Once the device is +fully provisioned, BLE advertising will stop. + +#### Bluetooth LE Rendezvous + +Pairing this application with `ble-thread` can be done with any of the enabled +[CHIP Controller](../../../src/controller/README.md) applications. Use the +information printed on the console to aide in pairing the device. The controller +application can also be used to control the example app with the cluster +commands. + +## TI Support + +For technical support, please consider creating a post on TI's [E2E forum][e2e]. +Additionally, we welcome any feedback. + +[matter]: https://csa-iot.org/all-solutions/matter/ +[ccs]: https://www.ti.com/tool/CCSTUDIO +[ccs_after_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#after-launch +[ccs_debug_view]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#debug-view +[ccs_manual_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-launch +[ccs_manual_method]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-method +[e2e]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum +[matter-e2e-faq]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/1082428/faq-cc2652r7-matter----getting-started-guide +[sysconfig]: https://www.ti.com/tool/SYSCONFIG +[ti_thread_dnd]: + https://www.ti.com/wireless-connectivity/thread/design-development.html +[ot_border_router_setup]: https://openthread.io/guides/border-router/build +[uniflash]: https://www.ti.com/tool/download/UNIFLASH diff --git a/examples/pump-controller-app/cc13x4_26x4/args.gni b/examples/pump-controller-app/cc13x4_26x4/args.gni new file mode 100644 index 00000000000000..39b1c91806af19 --- /dev/null +++ b/examples/pump-controller-app/cc13x4_26x4/args.gni @@ -0,0 +1,48 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/chip.gni") +import("${chip_root}/examples/platform/cc13x4_26x4/args.gni") + +ti_simplelink_sdk_target = get_label_info(":sdk", "label_no_toolchain") +ti_simplelink_sysconfig_target = + get_label_info(":sysconfig", "label_no_toolchain") + +ti_simplelink_board = "LP_EM_CC1354P10_6" + +# Size Optimizations +# use -Os instead of -Og, LWIP release build +optimize_debug_level = "s" +lwip_debug = false + +chip_enable_ota_requestor = false + +openthread_external_platform = "${chip_root}/third_party/openthread/platforms/cc13x4_26x4:libopenthread-cc13x4_cc26x4" + +# Disable CHIP Logging +#chip_progress_logging = false +#chip_detail_logging = false +#chip_automation_logging = false + +# BLE options +chip_config_network_layer_ble = true + +# Disable lock tracking, since our FreeRTOS configuration does not set +# INCLUDE_xSemaphoreGetMutexHolder +chip_stack_lock_tracking = "none" + +matter_device_vid = "0xFFF1" +matter_device_pid = "0x8011" +matter_software_ver = "0x0001" +matter_software_ver_str = "1.0d1" diff --git a/examples/pump-controller-app/cc13x4_26x4/build_overrides b/examples/pump-controller-app/cc13x4_26x4/build_overrides new file mode 120000 index 00000000000000..e578e73312ebd1 --- /dev/null +++ b/examples/pump-controller-app/cc13x4_26x4/build_overrides @@ -0,0 +1 @@ +../../build_overrides \ No newline at end of file diff --git a/examples/pump-controller-app/cc13x4_26x4/chip.syscfg b/examples/pump-controller-app/cc13x4_26x4/chip.syscfg new file mode 100644 index 00000000000000..e9cb55c3e22f07 --- /dev/null +++ b/examples/pump-controller-app/cc13x4_26x4/chip.syscfg @@ -0,0 +1,242 @@ +/* + * + * Copyright (c) 2020 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. + */ + + +/* Modules */ +var AESCCM = scripting.addModule("/ti/drivers/AESCCM"); +var AESECB = scripting.addModule("/ti/drivers/AESECB"); +var Button = scripting.addModule("/ti/drivers/apps/Button"); +var LED = scripting.addModule("/ti/drivers/apps/LED"); +var NVS = scripting.addModule("/ti/drivers/NVS"); +var RF = scripting.addModule("/ti/drivers/RF"); +var RFDesign = scripting.addModule("ti/devices/radioconfig/rfdesign"); +var RFCustom = scripting.addModule("/ti/devices/radioconfig/custom"); +var TRNG = scripting.addModule("/ti/drivers/TRNG"); +var SHA2 = scripting.addModule("/ti/drivers/SHA2"); +var UART2 = scripting.addModule("/ti/drivers/UART2"); +var ble = scripting.addModule("/ti/ble5stack/ble"); +var dmm = scripting.addModule("/ti/dmm/dmm"); +var AESCTRDRBG = scripting.addModule("/ti/drivers/AESCTRDRBG"); +var ECDH = scripting.addModule("/ti/drivers/ECDH"); + +/* Instances */ +var AESCCM1 = AESCCM.addInstance(); +var AESECB1 = AESECB.addInstance(); +var AESECB2 = AESECB.addInstance(); +var Button1 = Button.addInstance(); +var Button2 = Button.addInstance(); +var NVS1 = NVS.addInstance(); +var NVS2 = NVS.addInstance(); +var SHA21 = SHA2.addInstance(); +var LED1 = LED.addInstance(); +var LED2 = LED.addInstance(); +var TRNG1 = TRNG.addInstance(); +var TRNG2 = TRNG.addInstance(); +var TRNG3 = TRNG.addInstance(); +var UART2 = UART2.addInstance(); +var AESCTRDRBG1 = AESCTRDRBG.addInstance(); +var ECDH1 = ECDH.addInstance(); + +AESCTRDRBG1.$name = "CONFIG_AESCTRDRBG_0"; + +AESCCM1.$name = "CONFIG_AESCCM0"; + +AESECB1.$name = "CONFIG_AESECB0"; +AESECB2.$name = "CONFIG_AESECB_1"; + +ECDH1.$name = "CONFIG_ECDH0"; + +/* Left Button */ +Button1.$name = "CONFIG_BTN_LEFT"; +Button1.$hardware = system.deviceData.board.components["BTN-1"]; +Button1.gpioPin.$name = "CONFIG_GPIO_BTN1"; +Button1.gpioPin.pull = "Pull Up"; +Button1.gpioPin.interruptTrigger = "Falling Edge"; + +/* Left Button */ +Button2.$name = "CONFIG_BTN_RIGHT"; +Button2.$hardware = system.deviceData.board.components["BTN-2"]; +Button2.gpioPin.$name = "CONFIG_GPIO_BTN2"; +Button2.gpioPin.pull = "Pull Up"; +Button2.gpioPin.interruptTrigger = "Falling Edge"; + +/* ======== CCFG ======== */ +var CCFG = scripting.addModule("/ti/devices/CCFG"); +const ccfgSettings = system.getScript("/ti/common/lprf_ccfg_settings.js").ccfgSettings; +for(var setting in ccfgSettings) +{ + CCFG[setting] = ccfgSettings[setting]; +} + +CCFG.enableCodeGeneration = true; + + +/* NVS */ +NVS1.$name = "CONFIG_NVSINTERNAL"; +NVS1.internalFlash.regionBase = 0xFB800; +NVS1.internalFlash.regionSize = 0x2800; + + +NVS2.$name = "CONFIG_NVSEXTERNAL"; +NVS2.nvsType = "External"; // NVS Region Type +NVS2.$hardware = system.deviceData.board.components.MX25R8035F; + +/* RF */ +/* if an antenna component exists, assign it to the rf instance */ +if (system.deviceData.board && system.deviceData.board.components.RF) { + RF.$hardware = system.deviceData.board.components.RF; +} + +const rfDesignSettings = system.getScript("/ti/common/lprf_rf_design_settings.js").rfDesignSettings; +for(var setting in rfDesignSettings) +{ + RFDesign[setting] = rfDesignSettings[setting]; +} + + + +/* Handling for RF frontend characterization */ +if(RFDesign.rfDesign.match(/LP_CC2652PSIP/)) +{ + RFCustom.ieee = ["ieee154p10"]; + var rfCodeExportConfig = RFCustom.radioConfigieee154p10.codeExportConfig +} +else +{ + RFCustom.ieee = ["ieee154"]; + var rfCodeExportConfig = RFCustom.radioConfigieee154.codeExportConfig +} + +var cmdList = [ + "cmdIeeeTx", + "cmdIeeeRx", + "cmdIeeeCsma", + "cmdIeeeEdScan", + "cmdIeeeRxAck", + "cmdTxTest" +]; + +rfCodeExportConfig.useConst = true; +rfCodeExportConfig.useMulti = true; +rfCodeExportConfig.symGenMethod = "Custom"; + +const deviceId = system.deviceData.deviceId; + +// Add high PA options if present +if(deviceId.match(/CC(265[12]R|2674R|1352R1|1354R)/)) +{ + cmdList.push("cmdRadioSetup"); + rfCodeExportConfig.cmdRadioSetup = "RF_cmdIeeeRadioSetup"; +} +else if(deviceId.match(/CC(265[12]P|2674P|1352P)/)) +{ + cmdList.push("cmdRadioSetupPa"); + rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; + rfCodeExportConfig.paExport = "combined"; +} +else if(deviceId.match(/CC(265[34]|1354)P/)) +{ + cmdList.push("cmdRadioSetupPa"); + rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; + // currently not characterized for high PA +} +else +{ + throw new Error("Could not match platform to any known platform types"); +} + +rfCodeExportConfig.cmdList_ieee_15_4 = cmdList; + +/* Red LED */ +LED1.$name = "CONFIG_LED_RED"; +LED1.$hardware = system.deviceData.board.components.LED_RED; +LED1.gpioPin.$name = "CONFIG_GPIO_RLED"; +LED1.gpioPin.mode = "Output"; +LED1.gpioPin.callbackFunction = ""; + +/* Green LED */ +LED2.$name = "CONFIG_LED_GREEN"; +LED2.$hardware = system.deviceData.board.components.LED_GREEN; +LED2.gpioPin.$name = "CONFIG_GPIO_GLED"; +LED2.gpioPin.mode = "Output"; +LED2.gpioPin.callbackFunction = ""; + +/* Debug UART */ +UART2.$hardware = system.deviceData.board.components.XDS110UART; +UART2.$name = "CONFIG_UART2_DEBUG"; + +/* TRNG */ +TRNG1.$name = "CONFIG_TRNG_0"; +TRNG2.$name = "CONFIG_TRNG_THREAD"; +TRNG3.$name = "CONFIG_TRNG_APP"; + +/* BLE */ +ble.addressMode = "ADDRMODE_RP_WITH_PUBLIC_ID"; +ble.maxConnNum = 1; +ble.numOfAdvSets = 1; +ble.lockProject = true; +ble.oneLibSizeOpt = true; +ble.maxPDUSize = 255; +ble.radioConfig.codeExportConfig.$name = "ti_devices_radioconfig_code_export_param1"; +ble.connUpdateParamsPeripheral.$name = "ti_ble5stack_general_ble_conn_update_params0"; +ble.connUpdateParamsPeripheral.reqMinConnInt = 30; +ble.connUpdateParamsPeripheral.reqMaxConnInt = 50; + +ble.advSet1.$name = "ti_ble5stack_broadcaster_advertisement_set0"; +ble.advSet1.advParam1.$name = "ti_ble5stack_broadcaster_advertisement_params0"; + +ble.rfDesign = "LP_EM_CC1354P10_6"; + +ble.thorPg = 2; +/* DMM */ +dmm.project = "ti_thread_thermostat_remote_display"; +dmm.stackRoles = ["blePeripheral","threadFTD"]; +dmm.lockStackRoles = true; +dmm.numApplicationStates = 10; +dmm.applicationState0 = "ANY"; +dmm.applicationState1 = "DMMPOLICY_BLE_IDLE"; +dmm.applicationState2 = "DMMPOLICY_BLE_ADV"; +dmm.applicationState3 = "DMMPOLICY_BLE_CONNECTING"; +dmm.applicationState4 = "DMMPOLICY_BLE_HIGH_BANDWIDTH"; +dmm.applicationState5 = "DMMPOLICY_BLE_CONNECTED"; +dmm.applicationState6 = "DMMPOLICY_BLE_OAD"; +dmm.applicationState7 = "DMMPOLICY_THREAD_IDLE"; +dmm.applicationState8 = "DMMPOLICY_THREAD_LINK_EST"; +dmm.applicationState9 = "DMMPOLICY_THREAD_DATA"; +dmm.policyArray.create(4); +dmm.policyArray[0].$name = "ti_dmm_policy_dmm_policy0"; +dmm.policyArray[0].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble0"; +dmm.policyArray[0].blePeripheral.applicationStates = ["applicationState6"]; +dmm.policyArray[0].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread0"; +dmm.policyArray[0].threadFTD.pause = "DMMPOLICY_PAUSED"; +dmm.policyArray[1].$name = "ti_dmm_policy_dmm_policy1"; +dmm.policyArray[1].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble1"; +dmm.policyArray[1].blePeripheral.applicationStates = ["applicationState3","applicationState4"]; +dmm.policyArray[1].blePeripheral.weight = 25; +dmm.policyArray[1].blePeripheral.appliedActivity = ["DMMPOLICY_APPLIED_ACTIVITY_BLE_CONNECTION"]; +dmm.policyArray[1].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread1"; +dmm.policyArray[2].$name = "ti_dmm_policy_dmm_policy2"; +dmm.policyArray[2].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble2"; +dmm.policyArray[2].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread2"; +dmm.policyArray[2].threadFTD.weight = 30; +dmm.policyArray[2].threadFTD.applicationStates = ["applicationState8"]; +dmm.policyArray[2].threadFTD.appliedActivity = ["DMMPOLICY_APPLIED_ACTIVITY_ALL"]; +dmm.policyArray[3].$name = "ti_dmm_policy_dmm_policy3"; +dmm.policyArray[3].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble3"; +dmm.policyArray[3].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread3"; +dmm.policyArray[3].threadFTD.weight = 1; diff --git a/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp b/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp new file mode 100644 index 00000000000000..e2470d3375ab45 --- /dev/null +++ b/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp @@ -0,0 +1,461 @@ +/* + * + * Copyright (c) 2020 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 + +#include "FreeRTOS.h" +#include +#include + +#include + +#include +#include + +#if defined(CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR) +#include +#include +#include +#include +#include +#endif +#include +#include +#include +#include +#include + +#include + +#include +#include + +/* syscfg */ +#include + +#define APP_TASK_STACK_SIZE (4096) +#define APP_TASK_PRIORITY 4 +#define APP_EVENT_QUEUE_SIZE 10 + +using namespace ::chip; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; + +static TaskHandle_t sAppTaskHandle; +static QueueHandle_t sAppEventQueue; + +static LED_Handle sAppRedHandle; +static LED_Handle sAppGreenHandle; +static Button_Handle sAppLeftHandle; +static Button_Handle sAppRightHandle; + +AppTask AppTask::sAppTask; + +#if defined(CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR) +static DefaultOTARequestor sRequestorCore; +static DefaultOTARequestorStorage sRequestorStorage; +static DefaultOTARequestorDriver sRequestorUser; +static BDXDownloader sDownloader; +static OTAImageProcessorImpl sImageProcessor; + +void InitializeOTARequestor(void) +{ + // Initialize and interconnect the Requestor and Image Processor objects + SetRequestorInstance(&sRequestorCore); + + sRequestorStorage.Init(chip::Server::GetInstance().GetPersistentStorage()); + sRequestorCore.Init(chip::Server::GetInstance(), sRequestorStorage, sRequestorUser, sDownloader); + sImageProcessor.SetOTADownloader(&sDownloader); + sDownloader.SetImageProcessorDelegate(&sImageProcessor); + sRequestorUser.Init(&sRequestorCore, &sImageProcessor); +} +#endif + +static const chip::EndpointId sIdentifyEndpointId = 0; +static const uint32_t sIdentifyBlinkRateMs = 500; + +::Identify stIdentify = { sIdentifyEndpointId, AppTask::IdentifyStartHandler, AppTask::IdentifyStopHandler, + EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, AppTask::TriggerIdentifyEffectHandler }; + +int AppTask::StartAppTask() +{ + int ret = 0; + + sAppEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent)); + if (sAppEventQueue == NULL) + { + PLAT_LOG("Failed to allocate app event queue"); + while (true) + ; + } + + // Start App task. + if (xTaskCreate(AppTaskMain, "APP", APP_TASK_STACK_SIZE / sizeof(StackType_t), NULL, APP_TASK_PRIORITY, &sAppTaskHandle) != + pdPASS) + { + PLAT_LOG("Failed to create app task"); + while (true) + ; + } + return ret; +} + +int AppTask::Init() +{ + LED_Params ledParams; + Button_Params buttonParams; + + cc13xx_26xxLogInit(); + + // Init Chip memory management before the stack + chip::Platform::MemoryInit(); + + CHIP_ERROR ret = PlatformMgr().InitChipStack(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("PlatformMgr().InitChipStack() failed"); + while (true) + ; + } + + ret = ThreadStackMgr().InitThreadStack(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("ThreadStackMgr().InitThreadStack() failed"); + while (true) + ; + } + + ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("ConnectivityMgr().SetThreadDeviceType() failed"); + while (true) + ; + } + + ret = PlatformMgr().StartEventLoopTask(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("PlatformMgr().StartEventLoopTask() failed"); + while (true) + ; + } + + ret = ThreadStackMgrImpl().StartThreadTask(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("ThreadStackMgr().StartThreadTask() failed"); + while (true) + ; + } + + // Init ZCL Data Model and start server + PLAT_LOG("Initialize Server"); + static chip::CommonCaseDeviceServerInitParams initParams; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + chip::Server::GetInstance().Init(initParams); + + // Initialize device attestation config +#ifdef CC13X4_26X4_ATTESTATION_CREDENTIALS + SetDeviceAttestationCredentialsProvider(CC13X4_26X4::GetCC13X4_26X4DacProvider()); +#else + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif + + // Initialize LEDs + PLAT_LOG("Initialize LEDs"); + LED_init(); + + LED_Params_init(&ledParams); // default PWM LED + sAppRedHandle = LED_open(CONFIG_LED_RED, &ledParams); + LED_setOff(sAppRedHandle); + + LED_Params_init(&ledParams); // default PWM LED + sAppGreenHandle = LED_open(CONFIG_LED_GREEN, &ledParams); + LED_setOff(sAppGreenHandle); + + // Initialize buttons + PLAT_LOG("Initialize buttons"); + Button_init(); + + Button_Params_init(&buttonParams); + buttonParams.buttonEventMask = Button_EV_CLICKED | Button_EV_LONGPRESSED; + buttonParams.longPressDuration = 5000U; // ms + sAppLeftHandle = Button_open(CONFIG_BTN_LEFT, &buttonParams); + Button_setCallback(sAppLeftHandle, ButtonLeftEventHandler); + + Button_Params_init(&buttonParams); + buttonParams.buttonEventMask = Button_EV_CLICKED; + buttonParams.longPressDuration = 1000U; // ms + sAppRightHandle = Button_open(CONFIG_BTN_RIGHT, &buttonParams); + Button_setCallback(sAppRightHandle, ButtonRightEventHandler); + + // Initialize Pump module + PLAT_LOG("Initialize Pump"); + PumpMgr().Init(); + + PumpMgr().SetCallbacks(ActionInitiated, ActionCompleted); + + ConfigurationMgr().LogDeviceConfig(); + +#if defined(CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR) + InitializeOTARequestor(); +#endif + + // QR code will be used with CHIP Tool + PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); + + return 0; +} + +void AppTask::AppTaskMain(void * pvParameter) +{ + AppEvent event; + + sAppTask.Init(); + + while (true) + { + /* Task pend until we have stuff to do */ + if (xQueueReceive(sAppEventQueue, &event, portMAX_DELAY) == pdTRUE) + { + sAppTask.DispatchEvent(&event); + } + } +} + +void AppTask::PostEvent(const AppEvent * aEvent) +{ + if (xQueueSend(sAppEventQueue, aEvent, 0) != pdPASS) + { + /* Failed to post the message */ + } +} + +void AppTask::ButtonLeftEventHandler(Button_Handle handle, Button_EventMask events) +{ + AppEvent event; + event.Type = AppEvent::kEventType_ButtonLeft; + + if (events & Button_EV_CLICKED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_Clicked; + } + else if (events & Button_EV_LONGPRESSED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_LongPressed; + } + // button callbacks are in ISR context + if (xQueueSendFromISR(sAppEventQueue, &event, NULL) != pdPASS) + { + /* Failed to post the message */ + } +} + +void AppTask::ButtonRightEventHandler(Button_Handle handle, Button_EventMask events) +{ + AppEvent event; + event.Type = AppEvent::kEventType_ButtonRight; + + if (events & Button_EV_CLICKED) + { + event.ButtonEvent.Type = AppEvent::kAppEventButtonType_Clicked; + } + // button callbacks are in ISR context + if (xQueueSendFromISR(sAppEventQueue, &event, NULL) != pdPASS) + { + /* Failed to post the message */ + } +} + +void AppTask::ActionInitiated(PumpManager::Action_t aAction, int32_t aActor) +{ + // If the action has been initiated by the pump, update the pump trait + // and start flashing the LEDs rapidly to indicate action initiation. + if (aAction == PumpManager::START_ACTION) + { + PLAT_LOG("Pump start initiated"); + ; // TODO + } + else if (aAction == PumpManager::STOP_ACTION) + { + PLAT_LOG("Stop initiated"); + ; // TODO + } + + LED_setOn(sAppGreenHandle, LED_BRIGHTNESS_MAX); + LED_startBlinking(sAppGreenHandle, 50 /* ms */, LED_BLINK_FOREVER); + LED_setOn(sAppRedHandle, LED_BRIGHTNESS_MAX); + LED_startBlinking(sAppRedHandle, 110 /* ms */, LED_BLINK_FOREVER); +} + +void AppTask::ActionCompleted(PumpManager::Action_t aAction, int32_t aActor) +{ + // if the action has been completed by the pump, update the pump trait. + // Turn on the pump state LED if in a STARTED state OR + // Turn off the pump state LED if in an STOPPED state. + if (aAction == PumpManager::START_ACTION) + { + PLAT_LOG("Pump start completed"); + LED_stopBlinking(sAppGreenHandle); + LED_setOn(sAppGreenHandle, LED_BRIGHTNESS_MAX); + LED_stopBlinking(sAppRedHandle); + LED_setOn(sAppRedHandle, LED_BRIGHTNESS_MAX); + } + else if (aAction == PumpManager::STOP_ACTION) + { + PLAT_LOG("Pump stop completed"); + LED_stopBlinking(sAppGreenHandle); + LED_setOff(sAppGreenHandle); + LED_stopBlinking(sAppRedHandle); + LED_setOff(sAppRedHandle); + } + if (aActor == AppEvent::kEventType_ButtonLeft) + { + sAppTask.UpdateClusterState(); + } +} + +void AppTask::DispatchEvent(AppEvent * aEvent) +{ + switch (aEvent->Type) + { + case AppEvent::kEventType_ButtonRight: + if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) + { + // Toggle Pump state + if (!PumpMgr().IsStopped()) + { + PumpMgr().InitiateAction(0, PumpManager::STOP_ACTION); + } + else + { + PumpMgr().InitiateAction(0, PumpManager::START_ACTION); + } + } + break; + + case AppEvent::kEventType_ButtonLeft: + if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) + { + // Toggle BLE advertisements + if (!ConnectivityMgr().IsBLEAdvertisingEnabled()) + { + if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() == CHIP_NO_ERROR) + { + PLAT_LOG("Enabled BLE Advertisement"); + } + else + { + PLAT_LOG("OpenBasicCommissioningWindow() failed"); + } + } + else + { + // Disable BLE advertisements + ConnectivityMgr().SetBLEAdvertisingEnabled(false); + PLAT_LOG("Disabled BLE Advertisements"); + } + } + else if (AppEvent::kAppEventButtonType_LongPressed == aEvent->ButtonEvent.Type) + { + chip::Server::GetInstance().ScheduleFactoryReset(); + } + break; + + case AppEvent::kEventType_IdentifyStart: + LED_setOn(sAppGreenHandle, LED_BRIGHTNESS_MAX); + LED_startBlinking(sAppGreenHandle, sIdentifyBlinkRateMs, LED_BLINK_FOREVER); + PLAT_LOG("Identify started"); + break; + + case AppEvent::kEventType_IdentifyStop: + LED_stopBlinking(sAppGreenHandle); + + if (!PumpMgr().IsStopped()) + { + LED_setOn(sAppGreenHandle, LED_BRIGHTNESS_MAX); + } + else + { + LED_setOff(sAppGreenHandle); + } + PLAT_LOG("Identify stopped"); + break; + + case AppEvent::kEventType_AppEvent: + if (NULL != aEvent->Handler) + { + aEvent->Handler(aEvent); + } + break; + + case AppEvent::kEventType_None: + default: + break; + } +} + +void AppTask::UpdateClusterState() {} + +void AppTask::IdentifyStartHandler(::Identify *) +{ + AppEvent event; + event.Type = AppEvent::kEventType_IdentifyStart; + sAppTask.PostEvent(&event); +} + +void AppTask::IdentifyStopHandler(::Identify *) +{ + AppEvent event; + event.Type = AppEvent::kEventType_IdentifyStop; + sAppTask.PostEvent(&event); +} + +void AppTask::TriggerIdentifyEffectHandler(::Identify * identify) +{ + switch (identify->mCurrentEffectIdentifier) + { + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: + PLAT_LOG("Starting blink identifier effect"); + IdentifyStartHandler(identify); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: + PLAT_LOG("Breathe identifier effect not implemented"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: + PLAT_LOG("Okay identifier effect not implemented"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: + PLAT_LOG("Channel Change identifier effect not implemented"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: + PLAT_LOG("Finish identifier effect not implemented"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: + PLAT_LOG("Stop identifier effect"); + IdentifyStopHandler(identify); + break; + default: + PLAT_LOG("No identifier effect"); + } +} diff --git a/examples/pump-controller-app/cc13x4_26x4/main/PumpManager.cpp b/examples/pump-controller-app/cc13x4_26x4/main/PumpManager.cpp new file mode 100644 index 00000000000000..2afc7fd7b37ded --- /dev/null +++ b/examples/pump-controller-app/cc13x4_26x4/main/PumpManager.cpp @@ -0,0 +1,204 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * 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 "PumpManager.h" + +#include "AppConfig.h" +#include "AppTask.h" +#include "FreeRTOS.h" + +#define ACTUATOR_MOVEMENT_PERIOS_MS 500 + +PumpManager PumpManager::sPump; + +int PumpManager::Init() +{ + int ret = 0; + + mTimerHandle = xTimerCreate("BLT_TIMER", pdMS_TO_TICKS(ACTUATOR_MOVEMENT_PERIOS_MS), pdFALSE, this, TimerEventHandler); + if (NULL == mTimerHandle) + { + PLAT_LOG("failed to create pump timer"); + while (true) + ; + } + + mState = kState_StopCompleted; + mAutoStartTimerArmed = false; + mAutoRestart = false; + mAutoStartDuration = 0; + + return ret; +} + +void PumpManager::SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB) +{ + mActionInitiated_CB = aActionInitiated_CB; + mActionCompleted_CB = aActionCompleted_CB; +} + +bool PumpManager::IsActionInProgress() +{ + return (mState == kState_StartInitiated || mState == kState_StopInitiated); +} + +bool PumpManager::IsStopped() +{ + return (mState == kState_StopCompleted); +} + +void PumpManager::EnableAutoRestart(bool aOn) +{ + mAutoRestart = aOn; +} + +void PumpManager::SetAutoStartDuration(uint32_t aDurationInSecs) +{ + mAutoStartDuration = aDurationInSecs; +} + +bool PumpManager::InitiateAction(int32_t aActor, Action_t aAction) +{ + bool action_initiated = false; + State_t new_state; + + // Initiate Start/Stop Action only when the previous one is complete. + if (mState == kState_StartCompleted && aAction == STOP_ACTION) + { + action_initiated = true; + + new_state = kState_StopInitiated; + } + else if (mState == kState_StopCompleted && aAction == START_ACTION) + { + action_initiated = true; + mCurrentActor = aActor; + new_state = kState_StartInitiated; + } + + if (action_initiated) + { + if (mAutoStartTimerArmed && new_state == kState_StartInitiated) + { + // If auto start timer has been armed and someone initiates start, + // cancel the timer and continue as normal. + mAutoStartTimerArmed = false; + + CancelTimer(); + } + + PumpTimer(ACTUATOR_MOVEMENT_PERIOS_MS); + + // Since the timer started successfully, update the state and trigger callback + mState = new_state; + + if (mActionInitiated_CB) + { + mActionInitiated_CB(aAction, aActor); + } + } + + return action_initiated; +} + +void PumpManager::PumpTimer(uint32_t aTimeoutMs) +{ + xTimerChangePeriod(mTimerHandle, pdMS_TO_TICKS(aTimeoutMs), 100); + xTimerStart(mTimerHandle, 100); +} + +void PumpManager::CancelTimer(void) +{ + xTimerStop(mTimerHandle, 100); +} + +void PumpManager::TimerEventHandler(TimerHandle_t aTimer) +{ + PumpManager * pump = static_cast(pvTimerGetTimerID(aTimer)); + + // The timer event handler will be called in the context of the timer task + // once sPumpTimer expires. Post an event to apptask queue with the actual handler + // so that the event can be handled in the context of the apptask. + AppEvent event; + event.Type = AppEvent::kEventType_AppEvent; + event.PumpStateEvent.Context = static_cast(pump); + if (pump->mAutoStartTimerArmed) + { + event.Handler = AutoRestartTimerEventHandler; + } + else + { + event.Handler = ActuatorMovementTimerEventHandler; + } + GetAppTask().PostEvent(&event); +} + +void PumpManager::AutoRestartTimerEventHandler(AppEvent * aEvent) +{ + PumpManager * pump = static_cast(aEvent->PumpStateEvent.Context); + int32_t actor = 0; + + // Make sure auto start timer is still armed. + if (!pump->mAutoStartTimerArmed) + { + return; + } + + pump->mAutoStartTimerArmed = false; + + PLAT_LOG("Auto Re-Start has been triggered!"); + + pump->InitiateAction(actor, START_ACTION); +} + +void PumpManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent) +{ + Action_t actionCompleted = INVALID_ACTION; + + PumpManager * pump = static_cast(aEvent->PumpStateEvent.Context); + + if (pump->mState == kState_StartInitiated) + { + pump->mState = kState_StartCompleted; + actionCompleted = START_ACTION; + } + else if (pump->mState == kState_StopInitiated) + { + pump->mState = kState_StopCompleted; + actionCompleted = STOP_ACTION; + } + + if (actionCompleted != INVALID_ACTION) + { + if (pump->mActionCompleted_CB) + { + pump->mActionCompleted_CB(actionCompleted, pump->mCurrentActor); + } + + if (pump->mAutoRestart && actionCompleted == STOP_ACTION) + { + // Start the timer for auto restart + pump->PumpTimer(pump->mAutoStartDuration * 1000); + + pump->mAutoStartTimerArmed = true; + + PLAT_LOG("Auto Re-start enabled. Will be triggered in %u seconds", pump->mAutoStartDuration); + } + } +} diff --git a/examples/pump-controller-app/cc13x4_26x4/main/ZclCallbacks.cpp b/examples/pump-controller-app/cc13x4_26x4/main/ZclCallbacks.cpp new file mode 100644 index 00000000000000..e450a4b233eddb --- /dev/null +++ b/examples/pump-controller-app/cc13x4_26x4/main/ZclCallbacks.cpp @@ -0,0 +1,69 @@ +/* + * + * Copyright (c) 2020 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. + */ + +#include + +#include "AppConfig.h" +#include "AppTask.h" +#include "PumpManager.h" + +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::app::Clusters; + +void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size, + uint8_t * value) +{ + if (attributePath.mClusterId == OnOff::Id && attributePath.mAttributeId == OnOff::Attributes::OnOff::Id) + { + PumpMgr().InitiateAction(0, *value ? PumpManager::START_ACTION : PumpManager::STOP_ACTION); + } + else if (attributePath.mClusterId == LevelControl::Id && + attributePath.mAttributeId == LevelControl::Attributes::CurrentLevel::Id) + { + ChipLogProgress(Zcl, "[pump-app] Cluster LevelControl: attribute CurrentLevel set to %u", *value); + } + else + { + ChipLogProgress(Zcl, "Unknown attribute ID: " ChipLogFormatMEI, ChipLogValueMEI(attributePath.mAttributeId)); + return; + } +} + +/** @brief OnOff Cluster Init + * + * This function is called when a specific cluster is initialized. It gives the + * application an opportunity to take care of cluster initialization procedures. + * It is called exactly once for each endpoint where cluster is present. + * + * @param endpoint Ver.: always + * + * TODO Issue #3841 + * emberAfOnOffClusterInitCallback happens before the stack initialize the cluster + * attributes to the default value. + * The logic here expects something similar to the deprecated Plugins callback + * emberAfPluginOnOffClusterServerPostInitCallback. + * + */ +void emberAfOnOffClusterInitCallback(EndpointId endpoint) +{ + GetAppTask().UpdateClusterState(); +} diff --git a/examples/pump-controller-app/cc13x4_26x4/main/include/AppConfig.h b/examples/pump-controller-app/cc13x4_26x4/main/include/AppConfig.h new file mode 100644 index 00000000000000..7e0d1716f89144 --- /dev/null +++ b/examples/pump-controller-app/cc13x4_26x4/main/include/AppConfig.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020 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. + */ + +#ifndef APP_CONFIG_H +#define APP_CONFIG_H + +// Logging +#ifdef __cplusplus +extern "C" { +#endif + +int cc13xx_26xxLogInit(void); +void cc13xx_26xxLog(const char * aFormat, ...); +#define PLAT_LOG(...) cc13xx_26xxLog(__VA_ARGS__); + +#ifdef __cplusplus +} + +#endif +#endif // APP_CONFIG_H diff --git a/examples/pump-controller-app/cc13x4_26x4/main/include/AppEvent.h b/examples/pump-controller-app/cc13x4_26x4/main/include/AppEvent.h new file mode 100644 index 00000000000000..3a9c606e95c330 --- /dev/null +++ b/examples/pump-controller-app/cc13x4_26x4/main/include/AppEvent.h @@ -0,0 +1,63 @@ +/* + * + * Copyright (c) 2021 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. + */ + +#ifndef APP_EVENT_H +#define APP_EVENT_H + +struct AppEvent; +typedef void (*EventHandler)(AppEvent *); + +struct AppEvent +{ + enum AppEventType + { + kEventType_None = 0, + kEventType_ButtonLeft, + kEventType_ButtonRight, + kEventType_AppEvent, + kEventType_IdentifyStart, + kEventType_IdentifyStop, + }; + + enum AppEventButtonType + { + kAppEventButtonType_None = 0, + kAppEventButtonType_Clicked, + kAppEventButtonType_LongClicked, + kAppEventButtonType_LongPressed, + }; + + enum AppEventType Type; + + union + { + struct + { + enum AppEventButtonType Type; + } ButtonEvent; + + struct + { + void * Context; + } PumpStateEvent; + }; + + EventHandler Handler; +}; + +#endif // APP_EVENT_H diff --git a/examples/pump-controller-app/cc13x4_26x4/main/include/AppTask.h b/examples/pump-controller-app/cc13x4_26x4/main/include/AppTask.h new file mode 100644 index 00000000000000..bf13d20bca6ee6 --- /dev/null +++ b/examples/pump-controller-app/cc13x4_26x4/main/include/AppTask.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APP_TASK_H +#define APP_TASK_H + +#include +#include + +#include "FreeRTOS.h" +#include "semphr.h" +#include "task.h" + +#include "AppEvent.h" +#include "PumpManager.h" + +#include + +struct Identify; + +class AppTask +{ +public: + int StartAppTask(); + static void AppTaskMain(void * pvParameter); + + void PostStartActionRequest(int32_t aActor, PumpManager::Action_t aAction); + void PostEvent(const AppEvent * event); + void UpdateClusterState(); + + static void IdentifyStartHandler(::Identify *); + static void IdentifyStopHandler(::Identify *); + static void TriggerIdentifyEffectHandler(::Identify * identify); + +private: + friend AppTask & GetAppTask(void); + + int Init(); + + static void ActionInitiated(PumpManager::Action_t aAction, int32_t aActor); + static void ActionCompleted(PumpManager::Action_t aAction, int32_t aActor); + + void DispatchEvent(AppEvent * event); + + static void ButtonLeftEventHandler(Button_Handle handle, Button_EventMask events); + static void ButtonRightEventHandler(Button_Handle handle, Button_EventMask events); + static void TimerEventHandler(void * p_context); + + enum Function_t + { + kFunction_NoneSelected = 0, + kFunction_SoftwareUpdate = 0, + kFunction_FactoryReset, + + kFunction_Invalid + } Function; + + Function_t mFunction; + bool mFunctionTimerActive; + + static AppTask sAppTask; +}; + +inline AppTask & GetAppTask(void) +{ + return AppTask::sAppTask; +} + +#endif // APP_TASK_H diff --git a/examples/pump-controller-app/cc13x4_26x4/main/include/CHIPProjectConfig.h b/examples/pump-controller-app/cc13x4_26x4/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..2b2c3370763af8 --- /dev/null +++ b/examples/pump-controller-app/cc13x4_26x4/main/include/CHIPProjectConfig.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * 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. + * + */ + +#ifndef CHIP_PROJECT_CONFIG_H +#define CHIP_PROJECT_CONFIG_H + +// Security and Authentication always enabled +#define CHIP_CONFIG_SECURITY_TEST_MODE 0 + +#if BUILD_RELEASE // release build +// Note: Default Pairing/PIN/Serial Numbers being used. These should not be enabled for production builds +#endif // BUILD_RELEASE + +// 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 + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 1 + +/** + * Values set by args.gni: + * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION + */ + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + * + * Enable support for CHIP-over-BLE (CHIPOBLE). + */ +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote CHIP Time service + * using the CHIP Time Sync protocol. + */ +// #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 + +/** + * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE + * + * A size, in bytes, of the individual debug event logging buffer. + */ +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) + +#define MATTER_CC13XX_26XX_PLATFORM_LOG_ENABLED 1 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + * + * Enable the OpenThread SRP client to allow for CHIP device discovery. + */ +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT 1 + +/** + * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE + * + * For a development build, set the default importance of events to be logged as Debug. + * Since debug is the lowest importance level, this means all standard, critical, info and + * debug importance level vi events get logged. + */ +#if BUILD_RELEASE +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production +#else +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug +#endif // BUILD_RELEASE + +#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 + +/** + * @def CHIP_IM_MAX_NUM_COMMAND_HANDLER + * + * @brief Defines the maximum number of CommandHandler, limits the number of active commands transactions on server. + */ +#define CHIP_IM_MAX_NUM_COMMAND_HANDLER 2 + +/** + * @def CHIP_IM_MAX_NUM_WRITE_HANDLER + * + * @brief Defines the maximum number of WriteHandler, limits the number of active write transactions on server. + */ +#define CHIP_IM_MAX_NUM_WRITE_HANDLER 2 + +#endif // CHIP_PROJECT_CONFIG_H diff --git a/examples/pump-controller-app/cc13x4_26x4/main/include/OpenThreadConfig.h b/examples/pump-controller-app/cc13x4_26x4/main/include/OpenThreadConfig.h new file mode 100644 index 00000000000000..7d227258b1eaae --- /dev/null +++ b/examples/pump-controller-app/cc13x4_26x4/main/include/OpenThreadConfig.h @@ -0,0 +1,29 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * 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 + * Overrides to default OpenThread configuration. + * + */ + +#pragma once + +// Use the TI-supplied default platform configuration for remainder +#include "openthread-core-cc13x4_26x4-config.h" diff --git a/examples/pump-controller-app/cc13x4_26x4/main/include/PumpManager.h b/examples/pump-controller-app/cc13x4_26x4/main/include/PumpManager.h new file mode 100644 index 00000000000000..40a3961dd09161 --- /dev/null +++ b/examples/pump-controller-app/cc13x4_26x4/main/include/PumpManager.h @@ -0,0 +1,88 @@ +/* + * + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PUMP_MANAGER_H +#define PUMP_MANAGER_H + +#include +#include + +#include "AppEvent.h" + +#include +#include + +class PumpManager +{ +public: + enum Action_t + { + START_ACTION = 0, + STOP_ACTION, + + INVALID_ACTION + } Action; + + enum State_t + { + kState_StartInitiated = 0, + kState_StartCompleted, + kState_StopInitiated, + kState_StopCompleted, + } State; + + int Init(); + bool IsStopped(); + void EnableAutoRestart(bool aOn); + void SetAutoStartDuration(uint32_t aDurationInSecs); + bool IsActionInProgress(); + bool InitiateAction(int32_t aActor, Action_t aAction); + + typedef void (*Callback_fn_initiated)(Action_t, int32_t aActor); + typedef void (*Callback_fn_completed)(Action_t, int32_t aActor); + void SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB); + +private: + friend PumpManager & PumpMgr(void); + State_t mState; + + Callback_fn_initiated mActionInitiated_CB; + Callback_fn_completed mActionCompleted_CB; + + bool mAutoRestart; + uint32_t mAutoStartDuration; + bool mAutoStartTimerArmed; + TimerHandle_t mTimerHandle; + int32_t mCurrentActor; + + void CancelTimer(void); + void PumpTimer(uint32_t aTimeoutMs); + + static void TimerEventHandler(TimerHandle_t aTimer); + static void AutoRestartTimerEventHandler(AppEvent * aEvent); + static void ActuatorMovementTimerEventHandler(AppEvent * aEvent); + + static PumpManager sPump; +}; + +inline PumpManager & PumpMgr(void) +{ + return PumpManager::sPump; +} + +#endif // PUMP_MANAGER_H diff --git a/examples/pump-controller-app/cc13x4_26x4/main/main.cpp b/examples/pump-controller-app/cc13x4_26x4/main/main.cpp new file mode 100644 index 00000000000000..ba98379ecc741a --- /dev/null +++ b/examples/pump-controller-app/cc13x4_26x4/main/main.cpp @@ -0,0 +1,104 @@ +/* + * + * Copyright (c) 2020 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. + */ + +#include +#include + +#include + +#include +#include + +#include + +/* Driver Header files */ +#include +#include +#include + +#include +#include +#include +#include + +#include +#define TOTAL_ICALL_HEAP_SIZE (0xC700) + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::DeviceLayer; + +__attribute__((section(".heap"))) uint8_t GlobalHeapZoneBuffer[TOTAL_ICALL_HEAP_SIZE]; +uint32_t heapSize = TOTAL_ICALL_HEAP_SIZE; + +// ================================================================================ +// FreeRTOS Callbacks +// ================================================================================ +extern "C" void vApplicationStackOverflowHook(void) +{ + while (true) + { + ; + } +} + +/* Wrapper functions for using the queue registry regardless of whether it is enabled or disabled */ +extern "C" void vQueueAddToRegistryWrapper(QueueHandle_t xQueue, const char * pcQueueName) +{ + /* This function is intentionally left empty as the Queue Registry is disabled */ +} + +extern "C" void vQueueUnregisterQueueWrapper(QueueHandle_t xQueue) +{ + /* This function is intentionally left empty as the Queue Registry is disabled */ +} + +// ================================================================================ +// Main Code +// ================================================================================ +int main(void) +{ + Board_init(); + bpool((void *) GlobalHeapZoneBuffer, TOTAL_ICALL_HEAP_SIZE); + + GPIO_init(); + + NVS_init(); + + ECDH_init(); + + ECDSA_init(); + + AESECB_init(); + + SHA2_init(); + + int ret = GetAppTask().StartAppTask(); + if (ret != 0) + { + // can't log until the kernel is started + // PLAT_LOG("GetAppTask().StartAppTask() failed"); + while (true) + ; + } + + vTaskStartScheduler(); + + // Should never get here. + while (true) + ; +} diff --git a/examples/pump-controller-app/cc13x4_26x4/third_party/connectedhomeip b/examples/pump-controller-app/cc13x4_26x4/third_party/connectedhomeip new file mode 120000 index 00000000000000..c866b86874994d --- /dev/null +++ b/examples/pump-controller-app/cc13x4_26x4/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../.. \ No newline at end of file diff --git a/examples/shell/cc13x2x7_26x2x7/README.md b/examples/shell/cc13x2x7_26x2x7/README.md index 4b42e5b6ac5eea..478e3dc8821bd7 100644 --- a/examples/shell/cc13x2x7_26x2x7/README.md +++ b/examples/shell/cc13x2x7_26x2x7/README.md @@ -1,6 +1,6 @@ -# Matter CC1352 CC2652 Shell Application +# Matter Shell Application -A [chip-shell](../README.md) project on the Texas Instruments CC13X2_26X2 family +A [chip-shell](../README.md) project on the Texas Instruments CC13XX_26XX family of Wireless MCUs. ## Building @@ -11,15 +11,14 @@ Some initial setup is necessary for preparing the build environment. This section will need to be done when migrating to new versions of the SDK. This guide assumes that the environment is linux based, and recommends Ubuntu 20.04. -- Download and install [SysConfig][sysconfig] ([recommended - version][sysconfig_recommended]). This can be done simply with the following - commands. +- Download and install [SysConfig][sysconfig]. This can be done simply with + the following commands. ``` $ cd ~ - $ wget https://software-dl.ti.com/ccs/esd/sysconfig/sysconfig-1.11.0_2225-setup.run - $ chmod +x sysconfig-1.11.0_2225-setup.run - $ ./sysconfig-1.11.0_2225-setup.run + $ `wget https://dr-download.ti.com/software-development/ide-configuration-compiler-or-debugger/MD-nsUM6f7Vvb/1.15.0.2826/sysconfig-1.15.0_2826-setup.run` + $ chmod +x sysconfig-1.15.0_2826-setup.run + $ ./sysconfig-1.15.0_2826-setup.run ``` - Run the bootstrap script to setup the build environment. @@ -46,17 +45,27 @@ Ninja to build the executable. - Run the build to produce a default executable. By default on Linux both the TI SimpleLink SDK and Sysconfig are located in a `ti` folder in the user's home directory, and you must provide the absolute path to them. For example - `/home/username/ti/sysconfig_1.11.0`. On Windows the default directory is + `/home/username/ti/sysconfig_1.15.0`. On Windows the default directory is `C:\ti`. Take note of this install path, as it will be used in the next step. ``` - $ cd ~/connectedhomeip/examples/all-clusters-app/cc13x2x7_26x2x7 - $ gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.11.0\"" + $ cd ~/connectedhomeip/examples/shell/cc13x2x7_26x2x7 + OR + $ cd ~/connectedhomeip/examples/shell/cc13x4_26x4 + + $ gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\"" $ ninja -C out/debug ``` + If you would like to define arguments on the command line you may add them + to the GN call. + + ``` + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + ``` + ## Programming Loading the built image onto a LaunchPad is supported through two methods; @@ -137,7 +146,7 @@ terminal emulator to that port to see the output with the following options: ## Running the Example Once a device has been flashed with this example, it can now join and operate in -an existing Thread network. The following sections assume that a Thread network +an existing Matter network. The following sections assume that a Matter network is already active, and has at least one [OpenThread Border Router][ot_border_router_setup]. @@ -152,6 +161,7 @@ For help with the shell itself, refer to the For technical support, please consider creating a post on TI's [E2E forum][e2e]. Additionally, we welcome any feedback. +[matter]: https://csa-iot.org/all-solutions/matter/ [ccs]: https://www.ti.com/tool/CCSTUDIO [ccs_after_launch]: https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#after-launch @@ -161,9 +171,12 @@ Additionally, we welcome any feedback. https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-launch [ccs_manual_method]: https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-method -[e2e]: https://e2e.ti.com/support/wireless-connectivity/zigbee-and-thread +[e2e]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum +[matter-e2e-faq]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/1082428/faq-cc2652r7-matter----getting-started-guide [sysconfig]: https://www.ti.com/tool/SYSCONFIG -[sysconfig_recommended]: - https://software-dl.ti.com/ccs/esd/sysconfig/sysconfig-1.10.0_2163-setup.run -[ti_cc13x2_26x2_r7_matter_request]: https://ti.com/chip_sdk +[ti_thread_dnd]: + https://www.ti.com/wireless-connectivity/thread/design-development.html +[ot_border_router_setup]: https://openthread.io/guides/border-router/build [uniflash]: https://www.ti.com/tool/download/UNIFLASH diff --git a/examples/shell/cc13x4_26x4/.gn b/examples/shell/cc13x4_26x4/.gn new file mode 100644 index 00000000000000..540d01ce0b2bfd --- /dev/null +++ b/examples/shell/cc13x4_26x4/.gn @@ -0,0 +1,28 @@ +# 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. + +import("//build_overrides/build.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "freertos" + + import("//args.gni") +} diff --git a/examples/shell/cc13x4_26x4/BUILD.gn b/examples/shell/cc13x4_26x4/BUILD.gn new file mode 100644 index 00000000000000..1b950f20f1d9bc --- /dev/null +++ b/examples/shell/cc13x4_26x4/BUILD.gn @@ -0,0 +1,122 @@ +# 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. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/openthread.gni") +import("//build_overrides/ti_simplelink_sdk.gni") + +import("${build_root}/config/defaults.gni") + +import("${chip_root}/src/platform/device.gni") + +import("${ti_simplelink_sdk_build_root}/ti_simplelink_executable.gni") +import("${ti_simplelink_sdk_build_root}/ti_simplelink_sdk.gni") + +assert(current_os == "freertos") + +ti_simplelink_sdk("sdk") { + include_dirs = [ "include" ] + + defines = [] +} + +ti_sysconfig("sysconfig") { + sources = [ "chip.syscfg" ] + + outputs = [ + "ti_devices_config.c", + "ti_radio_config.c", + "ti_radio_config.h", + "ti_drivers_config.c", + "ti_drivers_config.h", + "ti_ble_config.c", + "ti_ble_config.h", + "ti_dmm_application_policy.c", + "ti_dmm_application_policy.h", + + # disabled until upstream generation is aligned + #"tiop_config.h", + #"tiop_config.c", + + # not traditional source files + #"ti_utils_build_linker.cmd.genlibs", + #"syscfg_c.rov.xs", + #"ti_utils_runtime_model.gv", + #"ti_utils_runtime_Makefile", + #"ti_ble_app_config.opt", + #"ti_build_config.opt", + ] + + public_configs = [ ":sdk_dmm_config" ] + + cflags = [ + "-Wno-comment", + "@" + rebase_path("${target_gen_dir}/sysconfig/ti_ble_app_config.opt", + root_build_dir), + "@" + rebase_path("${target_gen_dir}/sysconfig/ti_build_config.opt", + root_build_dir), + ] +} + +ti_simplelink_executable("shell_app") { + output_name = "chip-${ti_simplelink_board}-shell-example.out" + + sources = [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", + "main/AppTask.cpp", + "main/main.cpp", + ] + + deps = [ + ":sdk", + ":sysconfig", + "${chip_root}/examples/all-clusters-app/all-clusters-common", + "${chip_root}/examples/platform/cc13x4_26x4:cc13x4_26x4-attestation-credentials", + "${chip_root}/examples/shell/shell_common:shell_common", + "${chip_root}/src/lib", + "${chip_root}/src/lib/shell:shell", + "${chip_root}/src/setup_payload", + ] + + if (chip_openthread_ftd) { + deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-ftd" ] + } else { + deps += [ "${chip_root}/third_party/openthread/repo:libopenthread-mtd" ] + } + + include_dirs = [ + "include", + "main", + "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + ] + + cflags = [ + "-Wno-implicit-fallthrough", + "-Wno-sign-compare", + "-Wconversion", + ] + + output_dir = root_out_dir +} + +group("cc13x4_26x4") { + deps = [ ":shell_app" ] +} + +group("default") { + deps = [ ":cc13x4_26x4" ] +} diff --git a/examples/shell/cc13x4_26x4/README.md b/examples/shell/cc13x4_26x4/README.md new file mode 100644 index 00000000000000..9145e19f58ad07 --- /dev/null +++ b/examples/shell/cc13x4_26x4/README.md @@ -0,0 +1,183 @@ +# Matter Shell Application + +A [chip-shell](../README.md) project on the Texas Instruments CC13XX_26XX family +of Wireless MCUs. + +## Building + +### Preparation + +Some initial setup is necessary for preparing the build environment. This +section will need to be done when migrating to new versions of the SDK. This +guide assumes that the environment is linux based, and recommends Ubuntu 20.04. + +- Download and install [SysConfig][sysconfig]. This can be done simply with + the following commands. + + ``` + $ cd ~ + $ `wget https://dr-download.ti.com/software-development/ide-configuration-compiler-or-debugger/MD-nsUM6f7Vvb/1.15.0.2826/sysconfig-1.15.0_2826-setup.run` + $ chmod +x sysconfig-1.15.0_2826-setup.run + $ ./sysconfig-1.15.0_2826-setup.run + ``` + +- Run the bootstrap script to setup the build environment. + + ``` + $ cd ~/connectedhomeip + $ source ./scripts/bootstrap.sh + + ``` + +### Compilation + +It is necessary to activate the environment in every new shell. Then run GN and +Ninja to build the executable. + +- Activate the build environment with the repository activate script. + + ``` + $ cd ~/connectedhomeip + $ source ./scripts/activate.sh + + ``` + +- Run the build to produce a default executable. By default on Linux both the + TI SimpleLink SDK and Sysconfig are located in a `ti` folder in the user's + home directory, and you must provide the absolute path to them. For example + `/home/username/ti/sysconfig_1.15.0`. On Windows the default directory is + `C:\ti`. Take note of this install path, as it will be used in the next + step. + + ``` + $ cd ~/connectedhomeip/examples/shell/cc13x2x7_26x2x7 + OR + $ cd ~/connectedhomeip/examples/shell/cc13x4_26x4 + $ gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15" + $ ninja -C out/debug + + ``` + + If you would like to define arguments on the command line you may add them + to the GN call. + + ``` + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.15.0\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + ``` + +## Programming + +Loading the built image onto a LaunchPad is supported through two methods; +Uniflash and Code Composer Studio (CCS). UniFlash can be used to load the image. +Code Composer Studio can be used to load the image and debug the source code. + +### Code Composer Studio + +Programming with CCS will allow for a full debug environment within the IDE. +This is accomplished by creating a target connection to the XDS110 debugger and +starting a project-less debug session. The CCS IDE will attempt to find the +source files on the local machine based on the debug information embedded within +the ELF. CCS may prompt you to find the source code if the image was built on +another machine or the source code is located in a different location than is +recorded within the ELF. + +Download and install [Code Composer Studio][ccs]. + +First open CCS and create a new workspace. + +Create a target connection (sometimes called the CCXML) for your target SoC and +debugger as described in the [Manual Method][ccs_manual_method] section of the +CCS User's Guide. + +Next initiate a project-less debug session as described in the [Manual +Launch][ccs_manual_launch] section of the CCS User's Guide. + +CCS should switch to the debug view described in the [After +Launch][ccs_after_launch] section of the User's Guide. The SoC core will likely +be disconnected and symbols will not be loaded. Connect to the core as described +in the [Debug View][ccs_debug_view] section of the User's Guide. Once the core +is connected, use the `Load` button on the toolbar to load the ELF image. + +Note that the default configuration of the CCXML uses 2-wire cJTAG instead of +the full 4-wire JTAG connection to match the default jumper configuration of the +LaunchPad. + +### UniFlash + +Uniflash is Texas Instrument's uniform programming tool for embedded processors. +This will allow you to erase, flash, and inspect the SoC without setting up a +debugging environment. + +Download and install [UniFlash][uniflash]. + +First open UniFlash. Debug probes connected to the computer will usually be +displayed under the Detected Devices due to the automatic device detection +feature. If your device does not show up in this view it my be disconnected, or +you may have to create a New Configuration. If you already have a CCXML for your +SoC and debug connection you can use that in the section at the bottom. Once +your device is selected, click the `Start` button within the section to launch +the session. + +Select the ELF image to load on the device with the `Browse` button. This file +is placed in the `out/debug` folder by this guide and ends with the `*.out` file +extension. For OTA enabled applications, the standalone image will instead end +with the `*-bim.hex` file extension. This this is a combined image with +application and and `BIM` included. + +Finally click the `Load Image` button to load the executable image onto the +device. You should be able to see the log output over the XDS110 User UART. + +Note that programming the device through JTAG sets the Halt-in-Boot flag and may +cause issues when performing a software reset. This flag can be reset by +power-cycling the LaunchPad. + +## Running the Example + +By default the log output will be sent to the Application/User UART. Open a +terminal emulator to that port to see the output with the following options: + +| Parameter | Value | +| ------------ | -------- | +| Speed (baud) | `115200` | +| Data bits | `8` | +| Stop bits | `1` | +| Parity | `None` | +| Flow control | `None` | + +## Running the Example + +Once a device has been flashed with this example, it can now join and operate in +an existing Matter network. The following sections assume that a Matter network +is already active, and has at least one [OpenThread Border +Router][ot_border_router_setup]. + +For insight into what other components are needed to run this example, please +refer to our [Matter Getting Started Guide][matter-e2e-faq]. + +For help with the shell itself, refer to the +[shell example README](../README.md). + +## TI Support + +For technical support, please consider creating a post on TI's [E2E forum][e2e]. +Additionally, we welcome any feedback. + +[matter]: https://csa-iot.org/all-solutions/matter/ +[ccs]: https://www.ti.com/tool/CCSTUDIO +[ccs_after_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#after-launch +[ccs_debug_view]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#debug-view +[ccs_manual_launch]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-launch +[ccs_manual_method]: + https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html?configuration#manual-method +[e2e]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum +[matter-e2e-faq]: + https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/1082428/faq-cc2652r7-matter----getting-started-guide +[sysconfig]: https://www.ti.com/tool/SYSCONFIG +[ti_thread_dnd]: + https://www.ti.com/wireless-connectivity/thread/design-development.html +[ot_border_router_setup]: https://openthread.io/guides/border-router/build +[uniflash]: https://www.ti.com/tool/download/UNIFLASH diff --git a/examples/shell/cc13x4_26x4/args.gni b/examples/shell/cc13x4_26x4/args.gni new file mode 100644 index 00000000000000..9f1f28f24147df --- /dev/null +++ b/examples/shell/cc13x4_26x4/args.gni @@ -0,0 +1,51 @@ +# 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. + +import("//build_overrides/chip.gni") +import("${chip_root}/examples/platform/cc13x4_26x4/args.gni") + +ti_simplelink_sdk_target = get_label_info(":sdk", "label_no_toolchain") +ti_simplelink_sysconfig_target = + get_label_info(":sysconfig", "label_no_toolchain") + +ti_simplelink_board = "LP_EM_CC1354P10_6" + +# Size Optimizations +# use -Os instead of -Og, LWIP release build +is_debug = false + +chip_enable_ota_requestor = false + +# Disable FTD Build for all-clusters app to save Flash +chip_openthread_ftd = false +openthread_external_platform = "${chip_root}/third_party/openthread/platforms/cc13x4_26x4:libopenthread-cc13x4_cc26x4" + +# Disable CHIP Logging +chip_progress_logging = false +chip_detail_logging = false +chip_automation_logging = false + +# BLE options +chip_config_network_layer_ble = true + +chip_build_libshell = true + +# Disable lock tracking, since our FreeRTOS configuration does not set +# INCLUDE_xSemaphoreGetMutexHolder +chip_stack_lock_tracking = "none" + +matter_device_vid = "0xFFF1" +matter_device_pid = "0x8006" +matter_software_ver = "0x0001" +matter_software_ver_str = "1.0d1" diff --git a/examples/shell/cc13x4_26x4/build_overrides b/examples/shell/cc13x4_26x4/build_overrides new file mode 120000 index 00000000000000..e578e73312ebd1 --- /dev/null +++ b/examples/shell/cc13x4_26x4/build_overrides @@ -0,0 +1 @@ +../../build_overrides \ No newline at end of file diff --git a/examples/shell/cc13x4_26x4/chip.syscfg b/examples/shell/cc13x4_26x4/chip.syscfg new file mode 100644 index 00000000000000..1648cae0ac4239 --- /dev/null +++ b/examples/shell/cc13x4_26x4/chip.syscfg @@ -0,0 +1,242 @@ +/* + * + * Copyright (c) 2020 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. + */ + + +/* Modules */ +var AESCCM = scripting.addModule("/ti/drivers/AESCCM"); +var AESECB = scripting.addModule("/ti/drivers/AESECB"); +var Button = scripting.addModule("/ti/drivers/apps/Button"); +var LED = scripting.addModule("/ti/drivers/apps/LED"); +var NVS = scripting.addModule("/ti/drivers/NVS"); +var RF = scripting.addModule("/ti/drivers/RF"); +var RFDesign = scripting.addModule("ti/devices/radioconfig/rfdesign"); +var RFCustom = scripting.addModule("/ti/devices/radioconfig/custom"); +var TRNG = scripting.addModule("/ti/drivers/TRNG"); +var SHA2 = scripting.addModule("/ti/drivers/SHA2"); +var UART2 = scripting.addModule("/ti/drivers/UART2"); +var ble = scripting.addModule("/ti/ble5stack/ble"); +var dmm = scripting.addModule("/ti/dmm/dmm"); +var AESCTRDRBG = scripting.addModule("/ti/drivers/AESCTRDRBG"); +var ECDH = scripting.addModule("/ti/drivers/ECDH"); + +/* Instances */ +var AESCCM1 = AESCCM.addInstance(); +var AESECB1 = AESECB.addInstance(); +var AESECB2 = AESECB.addInstance(); +var Button1 = Button.addInstance(); +var Button2 = Button.addInstance(); +var NVS1 = NVS.addInstance(); +var NVS2 = NVS.addInstance(); +var SHA21 = SHA2.addInstance(); +var LED1 = LED.addInstance(); +var LED2 = LED.addInstance(); +var TRNG1 = TRNG.addInstance(); +var TRNG2 = TRNG.addInstance(); +var TRNG3 = TRNG.addInstance(); +var UART2 = UART2.addInstance(); +var AESCTRDRBG1 = AESCTRDRBG.addInstance(); +var ECDH1 = ECDH.addInstance(); + +AESCTRDRBG1.$name = "CONFIG_AESCTRDRBG_0"; + +AESCCM1.$name = "CONFIG_AESCCM0"; + +AESECB1.$name = "CONFIG_AESECB0"; +AESECB2.$name = "CONFIG_AESECB_1"; + +ECDH1.$name = "CONFIG_ECDH0"; + +/* Left Button */ +Button1.$name = "CONFIG_BTN_LEFT"; +Button1.$hardware = system.deviceData.board.components["BTN-1"]; +Button1.gpioPin.$name = "CONFIG_GPIO_BTN1"; +Button1.gpioPin.pull = "Pull Up"; +Button1.gpioPin.interruptTrigger = "Falling Edge"; + +/* Left Button */ +Button2.$name = "CONFIG_BTN_RIGHT"; +Button2.$hardware = system.deviceData.board.components["BTN-2"]; +Button2.gpioPin.$name = "CONFIG_GPIO_BTN2"; +Button2.gpioPin.pull = "Pull Up"; +Button2.gpioPin.interruptTrigger = "Falling Edge"; + +/* ======== CCFG ======== */ +var CCFG = scripting.addModule("/ti/devices/CCFG"); +const ccfgSettings = system.getScript("/ti/common/lprf_ccfg_settings.js").ccfgSettings; +for(var setting in ccfgSettings) +{ + CCFG[setting] = ccfgSettings[setting]; +} + +CCFG.enableCodeGeneration = true; + + +/* NVS */ +NVS1.$name = "CONFIG_NVSINTERNAL"; +NVS1.internalFlash.regionBase = 0xFB800; +NVS1.internalFlash.regionSize = 0x2800; + + +NVS2.$name = "CONFIG_NVSEXTERNAL"; +NVS2.nvsType = "External"; // NVS Region Type +NVS2.$hardware = system.deviceData.board.components.MX25R8035F; + +/* RF */ +/* if an antenna component exists, assign it to the rf instance */ +if (system.deviceData.board && system.deviceData.board.components.RF) { + RF.$hardware = system.deviceData.board.components.RF; +} + +const rfDesignSettings = system.getScript("/ti/common/lprf_rf_design_settings.js").rfDesignSettings; +for(var setting in rfDesignSettings) +{ + RFDesign[setting] = rfDesignSettings[setting]; +} + + + +/* Handling for RF frontend characterization */ +if(RFDesign.rfDesign.match(/LP_CC2652PSIP/)) +{ + RFCustom.ieee = ["ieee154p10"]; + var rfCodeExportConfig = RFCustom.radioConfigieee154p10.codeExportConfig +} +else +{ + RFCustom.ieee = ["ieee154"]; + var rfCodeExportConfig = RFCustom.radioConfigieee154.codeExportConfig +} + +var cmdList = [ + "cmdIeeeTx", + "cmdIeeeRx", + "cmdIeeeCsma", + "cmdIeeeEdScan", + "cmdIeeeRxAck", + "cmdTxTest" +]; + +rfCodeExportConfig.useConst = true; +rfCodeExportConfig.useMulti = true; +rfCodeExportConfig.symGenMethod = "Custom"; + +const deviceId = system.deviceData.deviceId; + +// Add high PA options if present +if(deviceId.match(/CC(265[12]R|2674R|1352R1|1354R)/)) +{ + cmdList.push("cmdRadioSetup"); + rfCodeExportConfig.cmdRadioSetup = "RF_cmdIeeeRadioSetup"; +} +else if(deviceId.match(/CC(265[12]P|2674P|1352P)/)) +{ + cmdList.push("cmdRadioSetupPa"); + rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; + rfCodeExportConfig.paExport = "combined"; +} +else if(deviceId.match(/CC(265[34]|1354)P/)) +{ + cmdList.push("cmdRadioSetupPa"); + rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; + // currently not characterized for high PA +} +else +{ + throw new Error("Could not match platform to any known platform types"); +} + +rfCodeExportConfig.cmdList_ieee_15_4 = cmdList; + +/* Red LED */ +LED1.$name = "CONFIG_LED_RED"; +LED1.$hardware = system.deviceData.board.components.LED_RED; +LED1.gpioPin.$name = "CONFIG_GPIO_RLED"; +LED1.gpioPin.mode = "Output"; +LED1.gpioPin.callbackFunction = ""; + +/* Green LED */ +LED2.$name = "CONFIG_LED_GREEN"; +LED2.$hardware = system.deviceData.board.components.LED_GREEN; +LED2.gpioPin.$name = "CONFIG_GPIO_GLED"; +LED2.gpioPin.mode = "Output"; +LED2.gpioPin.callbackFunction = ""; + +/* Debug UART */ +UART2.$hardware = system.deviceData.board.components.XDS110UART; +UART2.$name = "CONFIG_UART_STREAMER"; + +/* TRNG */ +TRNG1.$name = "CONFIG_TRNG_0"; +TRNG2.$name = "CONFIG_TRNG_THREAD"; +TRNG3.$name = "CONFIG_TRNG_APP"; + +/* BLE */ +ble.addressMode = "ADDRMODE_RP_WITH_PUBLIC_ID"; +ble.maxConnNum = 1; +ble.numOfAdvSets = 1; +ble.lockProject = true; +ble.oneLibSizeOpt = true; +ble.maxPDUSize = 255; +ble.radioConfig.codeExportConfig.$name = "ti_devices_radioconfig_code_export_param1"; +ble.connUpdateParamsPeripheral.$name = "ti_ble5stack_general_ble_conn_update_params0"; +ble.connUpdateParamsPeripheral.reqMinConnInt = 30; +ble.connUpdateParamsPeripheral.reqMaxConnInt = 50; + +ble.advSet1.$name = "ti_ble5stack_broadcaster_advertisement_set0"; +ble.advSet1.advParam1.$name = "ti_ble5stack_broadcaster_advertisement_params0"; + +ble.rfDesign = "LP_EM_CC1354P10_6"; + +ble.thorPg = 2; +/* DMM */ +dmm.project = "ti_thread_thermostat_remote_display"; +dmm.stackRoles = ["blePeripheral","threadFTD"]; +dmm.lockStackRoles = true; +dmm.numApplicationStates = 10; +dmm.applicationState0 = "ANY"; +dmm.applicationState1 = "DMMPOLICY_BLE_IDLE"; +dmm.applicationState2 = "DMMPOLICY_BLE_ADV"; +dmm.applicationState3 = "DMMPOLICY_BLE_CONNECTING"; +dmm.applicationState4 = "DMMPOLICY_BLE_HIGH_BANDWIDTH"; +dmm.applicationState5 = "DMMPOLICY_BLE_CONNECTED"; +dmm.applicationState6 = "DMMPOLICY_BLE_OAD"; +dmm.applicationState7 = "DMMPOLICY_THREAD_IDLE"; +dmm.applicationState8 = "DMMPOLICY_THREAD_LINK_EST"; +dmm.applicationState9 = "DMMPOLICY_THREAD_DATA"; +dmm.policyArray.create(4); +dmm.policyArray[0].$name = "ti_dmm_policy_dmm_policy0"; +dmm.policyArray[0].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble0"; +dmm.policyArray[0].blePeripheral.applicationStates = ["applicationState6"]; +dmm.policyArray[0].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread0"; +dmm.policyArray[0].threadFTD.pause = "DMMPOLICY_PAUSED"; +dmm.policyArray[1].$name = "ti_dmm_policy_dmm_policy1"; +dmm.policyArray[1].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble1"; +dmm.policyArray[1].blePeripheral.applicationStates = ["applicationState3","applicationState4"]; +dmm.policyArray[1].blePeripheral.weight = 25; +dmm.policyArray[1].blePeripheral.appliedActivity = ["DMMPOLICY_APPLIED_ACTIVITY_BLE_CONNECTION"]; +dmm.policyArray[1].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread1"; +dmm.policyArray[2].$name = "ti_dmm_policy_dmm_policy2"; +dmm.policyArray[2].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble2"; +dmm.policyArray[2].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread2"; +dmm.policyArray[2].threadFTD.weight = 30; +dmm.policyArray[2].threadFTD.applicationStates = ["applicationState8"]; +dmm.policyArray[2].threadFTD.appliedActivity = ["DMMPOLICY_APPLIED_ACTIVITY_ALL"]; +dmm.policyArray[3].$name = "ti_dmm_policy_dmm_policy3"; +dmm.policyArray[3].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble3"; +dmm.policyArray[3].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread3"; +dmm.policyArray[3].threadFTD.weight = 1; diff --git a/examples/shell/cc13x4_26x4/include/AppTask.h b/examples/shell/cc13x4_26x4/include/AppTask.h new file mode 100644 index 00000000000000..3fe4f972427717 --- /dev/null +++ b/examples/shell/cc13x4_26x4/include/AppTask.h @@ -0,0 +1,47 @@ +/* + * + * Copyright (c) 2022 Texas Instruments Incorporated + * 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 +#include + +#include "FreeRTOS.h" +#include "semphr.h" +#include "task.h" + +#include + +class AppTask +{ +public: + CHIP_ERROR StartAppTask(); + static void AppTaskMain(void * pvParameter); + +private: + friend AppTask & GetAppTask(void); + + CHIP_ERROR Init(); + + static AppTask sAppTask; +}; + +inline AppTask & GetAppTask(void) +{ + return AppTask::sAppTask; +} diff --git a/examples/shell/cc13x4_26x4/include/CHIPProjectConfig.h b/examples/shell/cc13x4_26x4/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..bec2bc08625272 --- /dev/null +++ b/examples/shell/cc13x4_26x4/include/CHIPProjectConfig.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2022 Texas Instruments Incorporated + * 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 + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" + +/** + * CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER + * + * Enables the use of a hard-coded default serial number if none + * is found in CHIP NV storage. + */ +#define CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER "TEST_SN" + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 1 +#endif + +/** + * Values set by args.gni: + * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION + */ + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + * + * Enable support for CHIP-over-BLE (CHIPOBLE). + */ +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote CHIP Time service + * using the CHIP Time Sync protocol. + */ +//#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 + +/** + * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE + * + * A size, in bytes, of the individual debug event logging buffer. + */ +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) + +#define MATTER_CC13XX_26XX_PLATFORM_LOG_ENABLED 0 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + * + * Enable the OpenThread SRP client to allow for CHIP device discovery. + */ +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT 1 + +/** + * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE + * + * For a development build, set the default importance of events to be logged as Debug. + * Since debug is the lowest importance level, this means all standard, critical, info and + * debug importance level vi events get logged. + */ +#if BUILD_RELEASE +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production +#else +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug +#endif // BUILD_RELEASE + +#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 + +/** + * @def CHIP_IM_MAX_NUM_COMMAND_HANDLER + * + * @brief Defines the maximum number of CommandHandler, limits the number of active commands transactions on server. + */ +#define CHIP_IM_MAX_NUM_COMMAND_HANDLER 2 + +/** + * @def CHIP_IM_MAX_NUM_WRITE_HANDLER + * + * @brief Defines the maximum number of WriteHandler, limits the number of active write transactions on server. + */ +#define CHIP_IM_MAX_NUM_WRITE_HANDLER 2 diff --git a/examples/shell/cc13x4_26x4/include/OpenThreadConfig.h b/examples/shell/cc13x4_26x4/include/OpenThreadConfig.h new file mode 100644 index 00000000000000..415c1e3d45e646 --- /dev/null +++ b/examples/shell/cc13x4_26x4/include/OpenThreadConfig.h @@ -0,0 +1,28 @@ +/* + * + * Copyright (c) 2022 Texas Instruments Incorporated + * 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 + * Overrides to default OpenThread configuration. + * + */ + +#pragma once + +// Use the TI-supplied default platform configuration for remainder +#include "openthread-core-cc13x4_26x4-config.h" diff --git a/examples/shell/cc13x4_26x4/main/AppTask.cpp b/examples/shell/cc13x4_26x4/main/AppTask.cpp new file mode 100644 index 00000000000000..302f8b8baf8c96 --- /dev/null +++ b/examples/shell/cc13x4_26x4/main/AppTask.cpp @@ -0,0 +1,181 @@ +/* + * + * 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 +#include + +#include "FreeRTOS.h" + +#include +#include +#include +#include +#include +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +#include +#include +#include +#include +#include +#endif +#include +#include +#include + +#include + +/* syscfg */ +#include + +#define APP_TASK_STACK_SIZE (4096) +#define APP_TASK_PRIORITY 4 + +using namespace ::chip; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; +using chip::Shell::Engine; + +AppTask AppTask::sAppTask; + +static TaskHandle_t sAppTaskHandle; + +// Logging +extern "C" { +int cc13xx_26xxLogInit(void); +} + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +static DefaultOTARequestor sRequestorCore; +static DefaultOTARequestorStorage sRequestorStorage; +static DefaultOTARequestorDriver sRequestorUser; +static BDXDownloader sDownloader; +static OTAImageProcessorImpl sImageProcessor; + +void InitializeOTARequestor(void) +{ + // Initialize and interconnect the Requestor and Image Processor objects + SetRequestorInstance(&sRequestorCore); + + sRequestorStorage.Init(Server::GetInstance().GetPersistentStorage()); + sRequestorCore.Init(Server::GetInstance(), sRequestorStorage, sRequestorUser, sDownloader); + sImageProcessor.SetOTADownloader(&sDownloader); + sDownloader.SetImageProcessorDelegate(&sImageProcessor); + sRequestorUser.Init(&sRequestorCore, &sImageProcessor); +} +#endif + +CHIP_ERROR AppTask::StartAppTask() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + // Start App task. + if (xTaskCreate(AppTaskMain, "APP", APP_TASK_STACK_SIZE / sizeof(StackType_t), NULL, APP_TASK_PRIORITY, &sAppTaskHandle) != + pdPASS) + { + while (true) + ; + } + + return err; +} + +CHIP_ERROR AppTask::Init() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + cc13xx_26xxLogInit(); + + // Init Chip memory management before the stack + Platform::MemoryInit(); + + Engine::Root().Init(); + + CHIP_ERROR ret = PlatformMgr().InitChipStack(); + if (ret != CHIP_NO_ERROR) + { + while (true) + ; + } + + ret = ThreadStackMgr().InitThreadStack(); + if (ret != CHIP_NO_ERROR) + { + while (true) + ; + } + +#ifdef CONFIG_OPENTHREAD_MTD_SED + ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); +#elif CONFIG_OPENTHREAD_MTD + ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); +#else + ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); +#endif + + if (ret != CHIP_NO_ERROR) + { + while (true) + ; + } + + ret = PlatformMgr().StartEventLoopTask(); + if (ret != CHIP_NO_ERROR) + { + while (true) + ; + } + + ret = ThreadStackMgrImpl().StartThreadTask(); + if (ret != CHIP_NO_ERROR) + { + while (true) + ; + } + + // Init ZCL Data Model and start server + static chip::CommonCaseDeviceServerInitParams initParams; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + chip::Server::GetInstance().Init(initParams); + + // Initialize device attestation config +#ifdef CC13X4_26X4_ATTESTATION_CREDENTIALS + SetDeviceAttestationCredentialsProvider(CC13X4_26X4::GetCC13X4_26X4DacProvider()); +#else + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + InitializeOTARequestor(); +#endif + return err; +} + +void AppTask::AppTaskMain(void * pvParameter) +{ + CHIP_ERROR err = sAppTask.Init(); + if (err != CHIP_NO_ERROR) + { + while (true) + ; + } + + Engine::Root().RunMainLoop(); +} diff --git a/examples/shell/cc13x4_26x4/main/main.cpp b/examples/shell/cc13x4_26x4/main/main.cpp new file mode 100644 index 00000000000000..93b5f9115428be --- /dev/null +++ b/examples/shell/cc13x4_26x4/main/main.cpp @@ -0,0 +1,108 @@ +/* + * + * 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. + */ + +#include +#include + +#include + +#include + +#include + +/* Driver Header files */ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#define TOTAL_ICALL_HEAP_SIZE (0xc700) + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::DeviceLayer; + +__attribute__((section(".heap"))) uint8_t GlobalHeapZoneBuffer[TOTAL_ICALL_HEAP_SIZE]; +uint32_t heapSize = TOTAL_ICALL_HEAP_SIZE; + +// ================================================================================ +// FreeRTOS Callbacks +// ================================================================================ +extern "C" void vApplicationStackOverflowHook(void) +{ + while (true) + { + ; + } +} + +/* Wrapper functions for using the queue registry regardless of whether it is enabled or disabled */ +extern "C" void vQueueAddToRegistryWrapper(QueueHandle_t xQueue, const char * pcQueueName) +{ + /* This function is intentionally left empty as the Queue Registry is disabled */ +} + +extern "C" void vQueueUnregisterQueueWrapper(QueueHandle_t xQueue) +{ + /* This function is intentionally left empty as the Queue Registry is disabled */ +} + +// ================================================================================ +// Main Code +// ================================================================================ +int main(void) +{ + CHIP_ERROR err; + + Board_init(); + bpool((void *) GlobalHeapZoneBuffer, TOTAL_ICALL_HEAP_SIZE); + + GPIO_init(); + + NVS_init(); + + ECDH_init(); + + ECDSA_init(); + + ECJPAKE_init(); + + AESECB_init(); + + SHA2_init(); + + err = GetAppTask().StartAppTask(); + if (err != CHIP_NO_ERROR) + { + // can't log until the kernel is started + // PLAT_LOG("GetAppTask().StartAppTask() failed"); + while (true) + ; + } + + vTaskStartScheduler(); + + // Should never get here. + while (true) + ; +} diff --git a/examples/shell/cc13x4_26x4/third_party/connectedhomeip b/examples/shell/cc13x4_26x4/third_party/connectedhomeip new file mode 120000 index 00000000000000..c866b86874994d --- /dev/null +++ b/examples/shell/cc13x4_26x4/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../.. \ No newline at end of file diff --git a/src/platform/cc13xx_26xx/Logging.cpp b/src/platform/cc13xx_26xx/Logging.cpp index b7ba49ba784dd8..b467a56909c0b0 100644 --- a/src/platform/cc13xx_26xx/Logging.cpp +++ b/src/platform/cc13xx_26xx/Logging.cpp @@ -27,7 +27,7 @@ extern "C" int cc13xx_26xxLogInit(void) // Most params can be default because we only send data, we don't receive uartParams.baudRate = 115200; - sDebugUartHandle = UART2_open(CONFIG_UART_DEBUG, &uartParams); + sDebugUartHandle = UART2_open(CONFIG_UART2_DEBUG, &uartParams); return 0; }