From 0b17bce8005fb155e78e243f31111cdaf2c92797 Mon Sep 17 00:00:00 2001 From: Alex Tsitsiura Date: Mon, 7 Nov 2022 09:43:39 +0200 Subject: [PATCH] [Telink] Add all clusters app & clusters minimal app (Cherry-pick #23383) (#23499) * [Telink] Add all clusters app & clusters minimal app (#23383) * [Telink] Add all-cluster-minimal-app & all-cluster-app * [Telink] update md files & set Teilink Light as FTD * [Telink] Restyled * [Telink] Add targets * [Telink] Fix pair cmd example * [Telink] restyled * [Telink] Add new apps for target linux * [Telink] Add note reg set up a valid Network Commissioning cluster; Remove ThreadStartButton from minimal app. * [Telink] Add targets --- .github/workflows/examples-telink.yaml | 33 +- .vscode/tasks.json | 2 + examples/all-clusters-app/telink/.gitignore | 1 + .../all-clusters-app/telink/CMakeLists.txt | 71 ++++ examples/all-clusters-app/telink/Readme.md | 159 ++++++++ .../telink/include/AppConfig.h | 34 ++ .../telink/include/AppEvent.h | 44 +++ .../all-clusters-app/telink/include/AppTask.h | 66 ++++ .../telink/include/CHIPProjectConfig.h | 48 +++ examples/all-clusters-app/telink/prj.conf | 54 +++ .../all-clusters-app/telink/src/AppTask.cpp | 357 ++++++++++++++++++ .../telink/src/ZclDoorLockCallbacks.cpp | 57 +++ examples/all-clusters-app/telink/src/main.cpp | 83 ++++ .../telink/third_party/connectedhomeip | 1 + .../telink/.gitignore | 1 + .../telink/CMakeLists.txt | 70 ++++ .../all-clusters-minimal-app/telink/Readme.md | 159 ++++++++ .../telink/include/AppConfig.h | 34 ++ .../telink/include/AppEvent.h | 44 +++ .../telink/include/AppTask.h | 64 ++++ .../telink/include/CHIPProjectConfig.h | 48 +++ .../all-clusters-minimal-app/telink/prj.conf | 54 +++ .../telink/src/AppTask.cpp | 288 ++++++++++++++ .../telink/src/main.cpp | 83 ++++ .../telink/third_party/connectedhomeip | 1 + examples/light-switch-app/telink/.gitignore | 1 + examples/light-switch-app/telink/Readme.md | 27 +- examples/lighting-app/telink/.gitignore | 1 + examples/lighting-app/telink/Readme.md | 25 +- examples/lighting-app/telink/prj.conf | 4 +- examples/ota-requestor-app/telink/.gitignore | 1 + .../ota-requestor-app/telink/src/AppTask.cpp | 2 + scripts/build/build/targets.py | 4 + scripts/build/builders/telink.py | 16 +- .../testdata/all_targets_except_host.txt | 2 + .../build/testdata/build_all_except_host.txt | 26 ++ .../glob_star_targets_except_host.txt | 2 + 37 files changed, 1936 insertions(+), 31 deletions(-) create mode 100644 examples/all-clusters-app/telink/.gitignore create mode 100644 examples/all-clusters-app/telink/CMakeLists.txt create mode 100644 examples/all-clusters-app/telink/Readme.md create mode 100644 examples/all-clusters-app/telink/include/AppConfig.h create mode 100644 examples/all-clusters-app/telink/include/AppEvent.h create mode 100644 examples/all-clusters-app/telink/include/AppTask.h create mode 100644 examples/all-clusters-app/telink/include/CHIPProjectConfig.h create mode 100644 examples/all-clusters-app/telink/prj.conf create mode 100644 examples/all-clusters-app/telink/src/AppTask.cpp create mode 100644 examples/all-clusters-app/telink/src/ZclDoorLockCallbacks.cpp create mode 100644 examples/all-clusters-app/telink/src/main.cpp create mode 120000 examples/all-clusters-app/telink/third_party/connectedhomeip create mode 100644 examples/all-clusters-minimal-app/telink/.gitignore create mode 100644 examples/all-clusters-minimal-app/telink/CMakeLists.txt create mode 100644 examples/all-clusters-minimal-app/telink/Readme.md create mode 100644 examples/all-clusters-minimal-app/telink/include/AppConfig.h create mode 100644 examples/all-clusters-minimal-app/telink/include/AppEvent.h create mode 100644 examples/all-clusters-minimal-app/telink/include/AppTask.h create mode 100644 examples/all-clusters-minimal-app/telink/include/CHIPProjectConfig.h create mode 100644 examples/all-clusters-minimal-app/telink/prj.conf create mode 100644 examples/all-clusters-minimal-app/telink/src/AppTask.cpp create mode 100644 examples/all-clusters-minimal-app/telink/src/main.cpp create mode 120000 examples/all-clusters-minimal-app/telink/third_party/connectedhomeip create mode 100644 examples/light-switch-app/telink/.gitignore create mode 100644 examples/lighting-app/telink/.gitignore create mode 100644 examples/ota-requestor-app/telink/.gitignore diff --git a/.github/workflows/examples-telink.yaml b/.github/workflows/examples-telink.yaml index dfb5fc75929f1c..1042ae8f7866fc 100644 --- a/.github/workflows/examples-telink.yaml +++ b/.github/workflows/examples-telink.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2020 Project CHIP Authors +# 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. @@ -54,37 +54,46 @@ jobs: GH_CONTEXT: ${{ toJson(github) }} run: scripts/tools/memory/gh_sizes_environment.py "${GH_CONTEXT}" - - name: Build example Telink Lighting App + - name: Build example Telink All Clusters App run: | ./scripts/run_in_build_env.sh \ - "./scripts/build/build_examples.py --no-log-timestamps --target 'telink-tlsr9518adk80d-light' build" + "./scripts/build/build_examples.py --no-log-timestamps --target 'telink-tlsr9518adk80d-all-clusters' build" + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + telink tlsr9518adk80d all-clusters-app \ + out/telink-tlsr9518adk80d-all-clusters/zephyr/zephyr.elf \ + /tmp/bloat_reports/ - - name: Build example Telink Light Switch App + - name: Build example Telink All Clusters Minimal App run: | ./scripts/run_in_build_env.sh \ - "./scripts/build/build_examples.py --no-log-timestamps --target 'telink-tlsr9518adk80d-light-switch' build" + "./scripts/build/build_examples.py --no-log-timestamps --target 'telink-tlsr9518adk80d-all-clusters-minimal' build" + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + telink tlsr9518adk80d all-clusters-minimal-app \ + out/telink-tlsr9518adk80d-all-clusters-minimal/zephyr/zephyr.elf \ + /tmp/bloat_reports/ - - name: Build example Telink OTA Requestor App + - name: Build example Telink Lighting App run: | ./scripts/run_in_build_env.sh \ - "./scripts/build/build_examples.py --no-log-timestamps --target 'telink-tlsr9518adk80d-ota-requestor' build" - - - name: Get Lighting size stats - run: | + "./scripts/build/build_examples.py --no-log-timestamps --target 'telink-tlsr9518adk80d-light' build" .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ telink tlsr9518adk80d lighting-app \ out/telink-tlsr9518adk80d-light/zephyr/zephyr.elf \ /tmp/bloat_reports/ - - name: Get Light Switch size stats + - name: Build example Telink Light Switch App run: | + ./scripts/run_in_build_env.sh \ + "./scripts/build/build_examples.py --no-log-timestamps --target 'telink-tlsr9518adk80d-light-switch' build" .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ telink tlsr9518adk80d light-switch-app \ out/telink-tlsr9518adk80d-light-switch/zephyr/zephyr.elf \ /tmp/bloat_reports/ - - name: Get OTA Requestor size stats + - name: Build example Telink OTA Requestor App run: | + ./scripts/run_in_build_env.sh \ + "./scripts/build/build_examples.py --no-log-timestamps --target 'telink-tlsr9518adk80d-ota-requestor' build" .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ telink tlsr9518adk80d ota-requestor-app \ out/telink-tlsr9518adk80d-ota-requestor/zephyr/zephyr.elf \ diff --git a/.vscode/tasks.json b/.vscode/tasks.json index d6fedb4eb102bd..e68b26b2b1cd08 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -441,6 +441,8 @@ "nrf-nrf5340-pump-controller", "nrf-nrf5340-shell", "qpg-qpg6100-lock", + "telink-tlsr9518adk80d-all-clusters", + "telink-tlsr9518adk80d-all-clusters-minimal", "telink-tlsr9518adk80d-light", "telink-tlsr9518adk80d-light-switch", "telink-tlsr9518adk80d-ota-requestor", diff --git a/examples/all-clusters-app/telink/.gitignore b/examples/all-clusters-app/telink/.gitignore new file mode 100644 index 00000000000000..84c048a73cc2e5 --- /dev/null +++ b/examples/all-clusters-app/telink/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/examples/all-clusters-app/telink/CMakeLists.txt b/examples/all-clusters-app/telink/CMakeLists.txt new file mode 100644 index 00000000000000..8d826aca784a26 --- /dev/null +++ b/examples/all-clusters-app/telink/CMakeLists.txt @@ -0,0 +1,71 @@ +# +# Copyright (c) 2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +cmake_minimum_required(VERSION 3.13.1) + +set(BOARD tlsr9518adk80d) + +get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/connectedhomeip REALPATH) +get_filename_component(NLIO_ROOT ${CHIP_ROOT}/third_party/nlio/repo/include REALPATH) +get_filename_component(TELINK_COMMON ${CHIP_ROOT}/examples/platform/telink REALPATH) +get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) +get_filename_component(ALL_CLUSTERS_COMMON_DIR ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) + +set(CONF_FILE ${CHIP_ROOT}/config/telink/app/zephyr.conf prj.conf) + +# Load NCS/Zephyr build system +list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/telink/chip-module) +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) + +project(chip-telink-all-clusters-app-example) + +include(${CHIP_ROOT}/config/telink/app/enable-gnu-std.cmake) +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) + +target_compile_options(app PRIVATE -fpermissive) + +target_include_directories(app PRIVATE + include + ${ALL_CLUSTERS_COMMON_DIR}/include + ${GEN_DIR}/app-common + ${GEN_DIR}/all-clusters-app + ${NLIO_ROOT} + ${TELINK_COMMON}/util/include) + +add_definitions( + "-DCHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER=" +) + +target_sources(app PRIVATE + src/AppTask.cpp + src/main.cpp + src/ZclDoorLockCallbacks.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-modes-manager.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/bridged-actions-stub.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/binding-handler.cpp + ${GEN_DIR}/all-clusters-app/zap-generated/callback-stub.cpp + ${GEN_DIR}/all-clusters-app/zap-generated/IMClusterCommandHandler.cpp + ${TELINK_COMMON}/util/src/LEDWidget.cpp + ${TELINK_COMMON}/util/src/ButtonManager.cpp + ${TELINK_COMMON}/util/src/ThreadUtil.cpp) + +chip_configure_data_model(app + INCLUDE_SERVER + ZAP_FILE ${ALL_CLUSTERS_COMMON_DIR}/all-clusters-app.zap +) + +if(CONFIG_CHIP_OTA_REQUESTOR) + target_sources(app PRIVATE ${TELINK_COMMON}/util/src/OTAUtil.cpp) +endif() diff --git a/examples/all-clusters-app/telink/Readme.md b/examples/all-clusters-app/telink/Readme.md new file mode 100644 index 00000000000000..f436507f9684b6 --- /dev/null +++ b/examples/all-clusters-app/telink/Readme.md @@ -0,0 +1,159 @@ +# Matter Telink All Clusters Example Application + +The Telink All Clusters Example Application implements various ZCL clusters +populated on three endpoints. You can use this example as a reference for +creating your own application. + +![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) + +## Build and flash + +1. Pull docker image from repository: + + ```bash + $ docker pull connectedhomeip/chip-build-telink:latest + ``` + +1. Run docker container: + + ```bash + $ docker run -it --rm -v ${CHIP_BASE}:/root/chip -v /dev/bus/usb:/dev/bus/usb --device-cgroup-rule "c 189:* rmw" connectedhomeip/chip-build-telink:latest + ``` + + here `${CHIP_BASE}` is directory which contains CHIP repo files **!!!Pay + attention that OUTPUT_DIR should contains ABSOLUTE path to output dir** + +1. Activate the build environment: + + ```bash + $ source ./scripts/activate.sh + ``` + +1. In the example dir run: + + ```bash + $ west build + ``` + +1. Flash binary: + + ``` + $ west flash --erase + ``` + +## Usage + +### UART + +To get output from device, connect UART to following pins: + +| Name | Pin | +| :--: | :---------------------------- | +| RX | PB3 (pin 17 of J34 connector) | +| TX | PB2 (pin 16 of J34 connector) | +| GND | GND | + +### Buttons + +The following buttons are available on **tlsr9518adk80d** board: + +| Name | Function | Description | +| :------- | :--------------------- | :----------------------------------------------------------------------------------------------------- | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommissioned state | +| Button 2 | Not used | Not used | +| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | +| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | + +### LEDs + +**Red** LED indicates current state of Thread network. It ables to be in +following states: + +| State | Description | +| :-------------------------- | :--------------------------------------------------------------------------- | +| Blinks with short pulses | Device is not commissioned to Thread, Thread is disabled | +| Blinls with frequent pulses | Device is commissioned, Thread enabled. Device trying to JOIN thread network | +| Blinks with whde pulses | Device commissioned and joined to thread network as CHILD | + +### CHIP tool commands + +1. Build + [chip-tool cli](https://github.com/project-chip/connectedhomeip/blob/master/examples/chip-tool/README.md) + +2. Pair with device + + ``` + ${CHIP_TOOL_DIR}/chip-tool pairing ble-thread ${NODE_ID} hex:${DATASET} ${PIN_CODE} ${DISCRIMINATOR} + ``` + + Example: + + ``` + ./chip-tool pairing ble-thread 1234 hex:0e080000000000010000000300000f35060004001fffe0020811111111222222220708fd61f77bd3df233e051000112233445566778899aabbccddeeff030e4f70656e54687265616444656d6f010212340410445f2b5ca6f2a93a55ce570a70efeecb0c0402a0fff8 20202021 3840 + ``` + +### OTA with Linux OTA Provider + +OTA feature enabled by default only for ota-requestor-app example. To enable OTA +feature for another Telink example: + +- set CONFIG_CHIP_OTA_REQUESTOR=y in corresponding "prj.conf" configuration + file. + +After build application with enabled OTA feature, use next binary files: + +- zephyr.bin - main binary to flash PCB (Use 2MB PCB). +- zephyr-ota.bin - binary for OTA Provider + +All binaries has the same SW version. To test OTA “zephyr-ota.bin” should have +higher SW version than base SW. Set CONFIG_CHIP_DEVICE_SOFTWARE_VERSION=2 in +corresponding “prj.conf” configuration file. + +Usage of OTA: + +- Build the [Linux OTA Provider](../../ota-provider-app/linux) + + ``` + ./scripts/examples/gn_build_example.sh examples/ota-provider-app/linux out/ota-provider-app chip_config_network_layer_ble=false + ``` + +- Run the Linux OTA Provider with OTA image. + + ``` + ./chip-ota-provider-app -f zephyr-ota.bin + ``` + +- Provision the Linux OTA Provider using chip-tool + + ``` + ./chip-tool pairing onnetwork ${OTA_PROVIDER_NODE_ID} 20202021 + ``` + + here: + + - \${OTA_PROVIDER_NODE_ID} is the node id of Linux OTA Provider + +- Configure the ACL of the ota-provider-app to allow access + + ``` + ./chip-tool accesscontrol write acl '[{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [112233], "targets": null}, {"fabricIndex": 1, "privilege": 3, "authMode": 2, "subjects": null, "targets": null}]' ${OTA_PROVIDER_NODE_ID} 0 + ``` + + here: + + - \${OTA_PROVIDER_NODE_ID} is the node id of Linux OTA Provider + +- Use the chip-tool to announce the ota-provider-app to start the OTA process + + ``` + ./chip-tool otasoftwareupdaterequestor announce-ota-provider ${OTA_PROVIDER_NODE_ID} 0 0 0 ${DEVICE_NODE_ID} 0 + ``` + + here: + + - \${OTA_PROVIDER_NODE_ID} is the node id of Linux OTA Provider + - \${DEVICE_NODE_ID} is the node id of paired device + +Once the transfer is complete, OTA requestor sends ApplyUpdateRequest command to +OTA provider for applying the image. Device will restart on successful +application of OTA image. diff --git a/examples/all-clusters-app/telink/include/AppConfig.h b/examples/all-clusters-app/telink/include/AppConfig.h new file mode 100644 index 00000000000000..27d2cc072c03fc --- /dev/null +++ b/examples/all-clusters-app/telink/include/AppConfig.h @@ -0,0 +1,34 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +// ---- All Clusters Application example config ---- + +// Buttons config +#define BUTTON_PORT DEVICE_DT_GET(DT_NODELABEL(gpioc)) + +#define BUTTON_PIN_1 2 +#define BUTTON_PIN_3 3 +#define BUTTON_PIN_4 1 +#define BUTTON_PIN_2 0 + +// LEDs config +// System led config +#define SYSTEM_STATE_LED_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) +#define SYSTEM_STATE_LED_PIN 7 diff --git a/examples/all-clusters-app/telink/include/AppEvent.h b/examples/all-clusters-app/telink/include/AppEvent.h new file mode 100644 index 00000000000000..000f3e8653d3ff --- /dev/null +++ b/examples/all-clusters-app/telink/include/AppEvent.h @@ -0,0 +1,44 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +struct AppEvent; +typedef void (*EventHandler)(AppEvent *); + +struct AppEvent +{ + enum AppEventTypes + { + kEventType_Button = 0, + }; + + uint16_t Type; + + union + { + struct + { + uint8_t Action; + } ButtonEvent; + }; + + EventHandler Handler; +}; diff --git a/examples/all-clusters-app/telink/include/AppTask.h b/examples/all-clusters-app/telink/include/AppTask.h new file mode 100644 index 00000000000000..d893794235fb47 --- /dev/null +++ b/examples/all-clusters-app/telink/include/AppTask.h @@ -0,0 +1,66 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "AppEvent.h" + +#include + +#include + +#include + +struct k_timer; + +class AppTask +{ +public: + CHIP_ERROR StartApp(); + + void PostEvent(AppEvent * event); + +private: + friend AppTask & GetAppTask(void); + + CHIP_ERROR Init(); + + void DispatchEvent(AppEvent * event); + + static void UpdateStatusLED(); + static void FactoryResetButtonEventHandler(void); + static void StartThreadButtonEventHandler(void); + static void StartBleAdvButtonEventHandler(void); + + static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + + static void FactoryResetHandler(AppEvent * aEvent); + static void StartThreadHandler(AppEvent * aEvent); + static void StartBleAdvHandler(AppEvent * aEvent); + + static void InitButtons(void); + + static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + + static AppTask sAppTask; +}; + +inline AppTask & GetAppTask(void) +{ + return AppTask::sAppTask; +} diff --git a/examples/all-clusters-app/telink/include/CHIPProjectConfig.h b/examples/all-clusters-app/telink/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..9cfa65977d1717 --- /dev/null +++ b/examples/all-clusters-app/telink/include/CHIPProjectConfig.h @@ -0,0 +1,48 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + * + * Enable support for Chip-over-BLE (CHIPoBLE). + */ +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 + +/** + * CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE + * + * Reduce packet buffer pool size to 8 (default 15) to reduce ram consumption + */ +#define CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE 8 + +#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 diff --git a/examples/all-clusters-app/telink/prj.conf b/examples/all-clusters-app/telink/prj.conf new file mode 100644 index 00000000000000..01b93d52feba2c --- /dev/null +++ b/examples/all-clusters-app/telink/prj.conf @@ -0,0 +1,54 @@ +# +# Copyright (c) 2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This sample uses sample-defaults.conf to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# enable GPIO +CONFIG_GPIO=y + +# OpenThread configs +CONFIG_OPENTHREAD_MTD=y +CONFIG_OPENTHREAD_FTD=n + +# Default OpenThread network settings +CONFIG_OPENTHREAD_PANID=4660 +CONFIG_OPENTHREAD_CHANNEL=15 +CONFIG_OPENTHREAD_NETWORK_NAME="OpenThreadDemo" +CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" +CONFIG_NET_CONFIG_IEEE802154_DEV_NAME="IEEE802154_b91" + +# Disable Matter OTA DFU +CONFIG_CHIP_OTA_REQUESTOR=n + +# CHIP configuration +CONFIG_CHIP_PROJECT_CONFIG="include/CHIPProjectConfig.h" +CONFIG_CHIP_OPENTHREAD_CONFIG="../../platform/telink/project_include/OpenThreadConfig.h" + +CONFIG_CHIP_DEVICE_VENDOR_ID=65521 +# CHIP PID: 32769 == 0x8001 (all-clusters-app) +CONFIG_CHIP_DEVICE_PRODUCT_ID=32769 +CONFIG_CHIP_DEVICE_TYPE=65535 + +CONFIG_CHIP_DEVICE_SOFTWARE_VERSION=1 +CONFIG_CHIP_DEVICE_SOFTWARE_VERSION_STRING="2022" + +# Enable CHIP pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# CHIP shell +CONFIG_CHIP_LIB_SHELL=n \ No newline at end of file diff --git a/examples/all-clusters-app/telink/src/AppTask.cpp b/examples/all-clusters-app/telink/src/AppTask.cpp new file mode 100644 index 00000000000000..f0daf281889d5f --- /dev/null +++ b/examples/all-clusters-app/telink/src/AppTask.cpp @@ -0,0 +1,357 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTask.h" + +#include "AppConfig.h" +#include "AppEvent.h" +#include "ButtonManager.h" +#include "LEDWidget.h" +#include "binding-handler.h" +#include +#include + +#include + +#include "ThreadUtil.h" + +#include +#include +#include +#include +#include + +#include +#include + +#if CONFIG_CHIP_OTA_REQUESTOR +#include "OTAUtil.h" +#endif + +#include +#include + +LOG_MODULE_DECLARE(app); + +namespace { + +constexpr int kAppEventQueueSize = 10; +constexpr uint8_t kButtonPushEvent = 1; +constexpr uint8_t kButtonReleaseEvent = 0; + +K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); + +LEDWidget sStatusLED; + +Button sFactoryResetButton; +Button sThreadStartButton; +Button sBleAdvStartButton; + +bool sIsThreadProvisioned = false; +bool sIsThreadEnabled = false; +bool sIsThreadAttached = false; +bool sHaveBLEConnections = false; + +chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; + +void OnIdentifyTriggerEffect(Identify * identify) +{ + switch (identify->mCurrentEffectIdentifier) + { + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); + break; + default: + ChipLogProgress(Zcl, "No identifier effect"); + break; + } + return; +} + +Identify sIdentify = { + chip::EndpointId{ 1 }, + [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, + [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, + EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, + OnIdentifyTriggerEffect, +}; + +} // namespace + +using namespace ::chip; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; +using namespace ::chip::DeviceLayer::Internal; + +AppTask AppTask::sAppTask; + +constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE; + +CHIP_ERROR AppTask::Init() +{ + CHIP_ERROR ret; + + LOG_INF("Current Software Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, + CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); + + // Initialize status LED + LEDWidget::InitGpio(SYSTEM_STATE_LED_PORT); + sStatusLED.Init(SYSTEM_STATE_LED_PIN); + + UpdateStatusLED(); + + InitButtons(); + + // Init ZCL Data Model and start server + static chip::CommonCaseDeviceServerInitParams initParams; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + chip::Server::GetInstance().Init(initParams); + + // Initialize device attestation config + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); + + gExampleDeviceInfoProvider.SetStorageDelegate(&chip::Server::GetInstance().GetPersistentStorage()); + chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); + +#if CONFIG_CHIP_OTA_REQUESTOR + InitBasicOTARequestor(); +#endif + + // We only have network commissioning on endpoint 0. + // Set up a valid Network Commissioning cluster on endpoint 0 is done in + // src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp + emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false); + + ConfigurationMgr().LogDeviceConfig(); + + // Configure Bindings + ret = InitBindingHandlers(); + if (ret != CHIP_NO_ERROR) + { + LOG_ERR("InitBindingHandlers() failed"); + return ret; + } + + PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); + + // Add CHIP event handler and start CHIP thread. + // Note that all the initialization code should happen prior to this point to avoid data races + // between the main and the CHIP threads. + PlatformMgr().AddEventHandler(ChipEventHandler, 0); + + ret = ConnectivityMgr().SetBLEDeviceName("TelinkApp"); + if (ret != CHIP_NO_ERROR) + { + LOG_ERR("Fail to set BLE device name"); + return ret; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR AppTask::StartApp() +{ + CHIP_ERROR err = Init(); + + if (err != CHIP_NO_ERROR) + { + LOG_ERR("AppTask.Init() failed"); + return err; + } + + AppEvent event = {}; + + while (true) + { + int ret = k_msgq_get(&sAppEventQueue, &event, K_MSEC(10)); + + while (!ret) + { + DispatchEvent(&event); + ret = k_msgq_get(&sAppEventQueue, &event, K_NO_WAIT); + } + + sStatusLED.Animate(); + } +} + +void AppTask::FactoryResetButtonEventHandler(void) +{ + AppEvent event; + + event.Type = AppEvent::kEventType_Button; + event.ButtonEvent.Action = kButtonPushEvent; + event.Handler = FactoryResetHandler; + sAppTask.PostEvent(&event); +} + +void AppTask::FactoryResetHandler(AppEvent * aEvent) +{ + LOG_INF("Factory Reset triggered."); + chip::Server::GetInstance().ScheduleFactoryReset(); +} + +void AppTask::StartThreadButtonEventHandler(void) +{ + AppEvent event; + + event.Type = AppEvent::kEventType_Button; + event.ButtonEvent.Action = kButtonPushEvent; + event.Handler = StartThreadHandler; + sAppTask.PostEvent(&event); +} + +void AppTask::StartThreadHandler(AppEvent * aEvent) +{ + + if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned()) + { + // Switch context from BLE to Thread + BLEManagerImpl sInstance; + sInstance.SwitchToIeee802154(); + StartDefaultThreadNetwork(); + LOG_INF("Device is not commissioned to a Thread network. Starting with the default configuration."); + } + else + { + LOG_INF("Device is commissioned to a Thread network."); + } +} + +void AppTask::StartBleAdvButtonEventHandler(void) +{ + AppEvent event; + + event.Type = AppEvent::kEventType_Button; + event.ButtonEvent.Action = kButtonPushEvent; + event.Handler = StartBleAdvHandler; + sAppTask.PostEvent(&event); +} + +void AppTask::StartBleAdvHandler(AppEvent * aEvent) +{ + LOG_INF("BLE advertising start button pressed"); + + // Don't allow on starting Matter service BLE advertising after Thread provisioning. + if (ConnectivityMgr().IsThreadProvisioned()) + { + LOG_INF("Matter service BLE advertising not started - device is commissioned to a Thread network."); + return; + } + + if (ConnectivityMgr().IsBLEAdvertisingEnabled()) + { + LOG_INF("BLE advertising is already enabled"); + return; + } + + if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) + { + LOG_ERR("OpenBasicCommissioningWindow() failed"); + } +} + +void AppTask::UpdateStatusLED() +{ + if (sIsThreadProvisioned && sIsThreadEnabled) + { + if (sIsThreadAttached) + { + sStatusLED.Blink(950, 50); + } + else + { + sStatusLED.Blink(100, 100); + } + } + else + { + sStatusLED.Blink(50, 950); + } +} + +void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) +{ + switch (event->Type) + { + case DeviceEventType::kCHIPoBLEAdvertisingChange: + sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; + UpdateStatusLED(); + break; + case DeviceEventType::kThreadStateChange: + sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); + sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); + sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); + UpdateStatusLED(); + break; + case DeviceEventType::kThreadConnectivityChange: +#if CONFIG_CHIP_OTA_REQUESTOR + if (event->ThreadConnectivityChange.Result == kConnectivity_Established) + { + InitBasicOTARequestor(); + } +#endif + break; + default: + break; + } +} + +void AppTask::PostEvent(AppEvent * aEvent) +{ + if (!aEvent) + return; + if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) + { + LOG_INF("Failed to post event to app task event queue"); + } +} + +void AppTask::DispatchEvent(AppEvent * aEvent) +{ + if (!aEvent) + return; + if (aEvent->Handler) + { + aEvent->Handler(aEvent); + } + else + { + LOG_INF("Event received with no handler. Dropping event."); + } +} + +void AppTask::InitButtons(void) +{ + sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, FactoryResetButtonEventHandler); + sThreadStartButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_2, StartThreadButtonEventHandler); + sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, StartBleAdvButtonEventHandler); + + ButtonManagerInst().AddButton(sFactoryResetButton); + ButtonManagerInst().AddButton(sThreadStartButton); + ButtonManagerInst().AddButton(sBleAdvStartButton); +} diff --git a/examples/all-clusters-app/telink/src/ZclDoorLockCallbacks.cpp b/examples/all-clusters-app/telink/src/ZclDoorLockCallbacks.cpp new file mode 100644 index 00000000000000..edaa86e44d5125 --- /dev/null +++ b/examples/all-clusters-app/telink/src/ZclDoorLockCallbacks.cpp @@ -0,0 +1,57 @@ +/* + * + * 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 +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::app::Clusters; +using namespace ::chip::app::Clusters::DoorLock; + +LOG_MODULE_DECLARE(app, CONFIG_MATTER_LOG_LEVEL); + +// Provided some empty callbacks and replaced feature map +// to simulate DoorLock endpoint for All-Clusters-App example +// without using kUsersManagement|kAccessSchedules|kRFIDCredentials|kPINCredentials + +bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const Optional & pinCode, DlOperationError & err) +{ + return true; +} + +bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const Optional & pinCode, + DlOperationError & err) +{ + return true; +} + +void emberAfDoorLockClusterInitCallback(EndpointId endpoint) +{ + DoorLockServer::Instance().InitServer(endpoint); + + // Set FeatureMap to 0, default is: + // (kUsersManagement|kAccessSchedules|kRFIDCredentials|kPINCredentials) 0x113 + EmberAfStatus status = DoorLock::Attributes::FeatureMap::Set(endpoint, 0); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + LOG_ERR("Updating feature map %x", status); + } +} diff --git a/examples/all-clusters-app/telink/src/main.cpp b/examples/all-clusters-app/telink/src/main.cpp new file mode 100644 index 00000000000000..48adaee45a5115 --- /dev/null +++ b/examples/all-clusters-app/telink/src/main.cpp @@ -0,0 +1,83 @@ +/* + * + * 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 + +LOG_MODULE_REGISTER(app); + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::DeviceLayer; + +int main(void) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + err = chip::Platform::MemoryInit(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("Platform::MemoryInit() failed"); + goto exit; + } + + LOG_INF("Init CHIP stack"); + err = PlatformMgr().InitChipStack(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("PlatformMgr().InitChipStack() failed"); + goto exit; + } + + LOG_INF("Starting CHIP task"); + err = PlatformMgr().StartEventLoopTask(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("PlatformMgr().StartEventLoopTask() failed"); + goto exit; + } + + LOG_INF("Init Thread stack"); + err = ThreadStackMgr().InitThreadStack(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("ThreadStackMgr().InitThreadStack() failed"); + goto exit; + } + +#ifdef CONFIG_OPENTHREAD_MTD + err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); +#else + err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); +#endif + if (err != CHIP_NO_ERROR) + { + LOG_ERR("ConnectivityMgr().SetThreadDeviceType() failed"); + goto exit; + } + + err = GetAppTask().StartApp(); + +exit: + LOG_ERR("Exited with code %" CHIP_ERROR_FORMAT, err.Format()); + return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/all-clusters-app/telink/third_party/connectedhomeip b/examples/all-clusters-app/telink/third_party/connectedhomeip new file mode 120000 index 00000000000000..c866b86874994d --- /dev/null +++ b/examples/all-clusters-app/telink/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../.. \ No newline at end of file diff --git a/examples/all-clusters-minimal-app/telink/.gitignore b/examples/all-clusters-minimal-app/telink/.gitignore new file mode 100644 index 00000000000000..84c048a73cc2e5 --- /dev/null +++ b/examples/all-clusters-minimal-app/telink/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/examples/all-clusters-minimal-app/telink/CMakeLists.txt b/examples/all-clusters-minimal-app/telink/CMakeLists.txt new file mode 100644 index 00000000000000..6b90b624398547 --- /dev/null +++ b/examples/all-clusters-minimal-app/telink/CMakeLists.txt @@ -0,0 +1,70 @@ +# +# Copyright (c) 2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +cmake_minimum_required(VERSION 3.13.1) + +set(BOARD tlsr9518adk80d) + +get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/connectedhomeip REALPATH) +get_filename_component(NLIO_ROOT ${CHIP_ROOT}/third_party/nlio/repo/include REALPATH) +get_filename_component(TELINK_COMMON ${CHIP_ROOT}/examples/platform/telink REALPATH) +get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) +get_filename_component(ALL_CLUSTERS_COMMON_DIR ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) + +set(CONF_FILE ${CHIP_ROOT}/config/telink/app/zephyr.conf prj.conf) + +# Load NCS/Zephyr build system +list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/telink/chip-module) +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) + +project(chip-telink-all-clusters-minimal-app-example) + +include(${CHIP_ROOT}/config/telink/app/enable-gnu-std.cmake) +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) + +target_compile_options(app PRIVATE -fpermissive) + +target_include_directories(app PRIVATE + include + ${ALL_CLUSTERS_COMMON_DIR}/include + ${GEN_DIR}/app-common + ${GEN_DIR}/all-clusters-minimal-app + ${NLIO_ROOT} + ${TELINK_COMMON}/util/include) + +add_definitions( + "-DCHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER=" +) + +target_sources(app PRIVATE + src/AppTask.cpp + src/main.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-modes-manager.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/bridged-actions-stub.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/binding-handler.cpp + ${GEN_DIR}/all-clusters-minimal-app/zap-generated/callback-stub.cpp + ${GEN_DIR}/all-clusters-minimal-app/zap-generated/IMClusterCommandHandler.cpp + ${TELINK_COMMON}/util/src/LEDWidget.cpp + ${TELINK_COMMON}/util/src/ButtonManager.cpp + ${TELINK_COMMON}/util/src/ThreadUtil.cpp) + +chip_configure_data_model(app + INCLUDE_SERVER + ZAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../all-clusters-common/all-clusters-minimal-app.zap +) + +if(CONFIG_CHIP_OTA_REQUESTOR) + target_sources(app PRIVATE ${TELINK_COMMON}/util/src/OTAUtil.cpp) +endif() diff --git a/examples/all-clusters-minimal-app/telink/Readme.md b/examples/all-clusters-minimal-app/telink/Readme.md new file mode 100644 index 00000000000000..f2fc7f4d0518ee --- /dev/null +++ b/examples/all-clusters-minimal-app/telink/Readme.md @@ -0,0 +1,159 @@ +# Matter Telink All Clusters Minimal Example Application + +The Telink All Clusters Minimal Example Application implements various ZCL +clusters populated on three endpoints. You can use this example as a reference +for creating your own application. + +![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) + +## Build and flash + +1. Pull docker image from repository: + + ```bash + $ docker pull connectedhomeip/chip-build-telink:latest + ``` + +1. Run docker container: + + ```bash + $ docker run -it --rm -v ${CHIP_BASE}:/root/chip -v /dev/bus/usb:/dev/bus/usb --device-cgroup-rule "c 189:* rmw" connectedhomeip/chip-build-telink:latest + ``` + + here `${CHIP_BASE}` is directory which contains CHIP repo files **!!!Pay + attention that OUTPUT_DIR should contains ABSOLUTE path to output dir** + +1. Activate the build environment: + + ```bash + $ source ./scripts/activate.sh + ``` + +1. In the example dir run: + + ```bash + $ west build + ``` + +1. Flash binary: + + ``` + $ west flash --erase + ``` + +## Usage + +### UART + +To get output from device, connect UART to following pins: + +| Name | Pin | +| :--: | :---------------------------- | +| RX | PB3 (pin 17 of J34 connector) | +| TX | PB2 (pin 16 of J34 connector) | +| GND | GND | + +### Buttons + +The following buttons are available on **tlsr9518adk80d** board: + +| Name | Function | Description | +| :------- | :--------------------- | :----------------------------------------------------------------------------------------------------- | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommissioned state | +| Button 2 | Not used | Not used | +| Button 2 | Not used | Not used | +| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | + +### LEDs + +**Red** LED indicates current state of Thread network. It ables to be in +following states: + +| State | Description | +| :-------------------------- | :--------------------------------------------------------------------------- | +| Blinks with short pulses | Device is not commissioned to Thread, Thread is disabled | +| Blinls with frequent pulses | Device is commissioned, Thread enabled. Device trying to JOIN thread network | +| Blinks with whde pulses | Device commissioned and joined to thread network as CHILD | + +### CHIP tool commands + +1. Build + [chip-tool cli](https://github.com/project-chip/connectedhomeip/blob/master/examples/chip-tool/README.md) + +2. Pair with device + + ``` + ${CHIP_TOOL_DIR}/chip-tool pairing ble-thread ${NODE_ID} hex:${DATASET} ${PIN_CODE} ${DISCRIMINATOR} + ``` + + Example: + + ``` + ./chip-tool pairing ble-thread 1234 hex:0e080000000000010000000300000f35060004001fffe0020811111111222222220708fd61f77bd3df233e051000112233445566778899aabbccddeeff030e4f70656e54687265616444656d6f010212340410445f2b5ca6f2a93a55ce570a70efeecb0c0402a0fff8 20202021 3840 + ``` + +### OTA with Linux OTA Provider + +OTA feature enabled by default only for ota-requestor-app example. To enable OTA +feature for another Telink example: + +- set CONFIG_CHIP_OTA_REQUESTOR=y in corresponding "prj.conf" configuration + file. + +After build application with enabled OTA feature, use next binary files: + +- zephyr.bin - main binary to flash PCB (Use 2MB PCB). +- zephyr-ota.bin - binary for OTA Provider + +All binaries has the same SW version. To test OTA “zephyr-ota.bin” should have +higher SW version than base SW. Set CONFIG_CHIP_DEVICE_SOFTWARE_VERSION=2 in +corresponding “prj.conf” configuration file. + +Usage of OTA: + +- Build the [Linux OTA Provider](../../ota-provider-app/linux) + + ``` + ./scripts/examples/gn_build_example.sh examples/ota-provider-app/linux out/ota-provider-app chip_config_network_layer_ble=false + ``` + +- Run the Linux OTA Provider with OTA image. + + ``` + ./chip-ota-provider-app -f zephyr-ota.bin + ``` + +- Provision the Linux OTA Provider using chip-tool + + ``` + ./chip-tool pairing onnetwork ${OTA_PROVIDER_NODE_ID} 20202021 + ``` + + here: + + - \${OTA_PROVIDER_NODE_ID} is the node id of Linux OTA Provider + +- Configure the ACL of the ota-provider-app to allow access + + ``` + ./chip-tool accesscontrol write acl '[{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [112233], "targets": null}, {"fabricIndex": 1, "privilege": 3, "authMode": 2, "subjects": null, "targets": null}]' ${OTA_PROVIDER_NODE_ID} 0 + ``` + + here: + + - \${OTA_PROVIDER_NODE_ID} is the node id of Linux OTA Provider + +- Use the chip-tool to announce the ota-provider-app to start the OTA process + + ``` + ./chip-tool otasoftwareupdaterequestor announce-ota-provider ${OTA_PROVIDER_NODE_ID} 0 0 0 ${DEVICE_NODE_ID} 0 + ``` + + here: + + - \${OTA_PROVIDER_NODE_ID} is the node id of Linux OTA Provider + - \${DEVICE_NODE_ID} is the node id of paired device + +Once the transfer is complete, OTA requestor sends ApplyUpdateRequest command to +OTA provider for applying the image. Device will restart on successful +application of OTA image. diff --git a/examples/all-clusters-minimal-app/telink/include/AppConfig.h b/examples/all-clusters-minimal-app/telink/include/AppConfig.h new file mode 100644 index 00000000000000..27d2cc072c03fc --- /dev/null +++ b/examples/all-clusters-minimal-app/telink/include/AppConfig.h @@ -0,0 +1,34 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +// ---- All Clusters Application example config ---- + +// Buttons config +#define BUTTON_PORT DEVICE_DT_GET(DT_NODELABEL(gpioc)) + +#define BUTTON_PIN_1 2 +#define BUTTON_PIN_3 3 +#define BUTTON_PIN_4 1 +#define BUTTON_PIN_2 0 + +// LEDs config +// System led config +#define SYSTEM_STATE_LED_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) +#define SYSTEM_STATE_LED_PIN 7 diff --git a/examples/all-clusters-minimal-app/telink/include/AppEvent.h b/examples/all-clusters-minimal-app/telink/include/AppEvent.h new file mode 100644 index 00000000000000..000f3e8653d3ff --- /dev/null +++ b/examples/all-clusters-minimal-app/telink/include/AppEvent.h @@ -0,0 +1,44 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +struct AppEvent; +typedef void (*EventHandler)(AppEvent *); + +struct AppEvent +{ + enum AppEventTypes + { + kEventType_Button = 0, + }; + + uint16_t Type; + + union + { + struct + { + uint8_t Action; + } ButtonEvent; + }; + + EventHandler Handler; +}; diff --git a/examples/all-clusters-minimal-app/telink/include/AppTask.h b/examples/all-clusters-minimal-app/telink/include/AppTask.h new file mode 100644 index 00000000000000..d6a02734a40e74 --- /dev/null +++ b/examples/all-clusters-minimal-app/telink/include/AppTask.h @@ -0,0 +1,64 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "AppEvent.h" + +#include + +#include + +#include + +struct k_timer; + +class AppTask +{ +public: + CHIP_ERROR StartApp(); + + void PostEvent(AppEvent * event); + +private: + friend AppTask & GetAppTask(void); + + CHIP_ERROR Init(); + + void DispatchEvent(AppEvent * event); + + static void UpdateStatusLED(); + static void FactoryResetButtonEventHandler(void); + static void StartBleAdvButtonEventHandler(void); + + static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + + static void FactoryResetHandler(AppEvent * aEvent); + static void StartBleAdvHandler(AppEvent * aEvent); + + static void InitButtons(void); + + static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + + static AppTask sAppTask; +}; + +inline AppTask & GetAppTask(void) +{ + return AppTask::sAppTask; +} diff --git a/examples/all-clusters-minimal-app/telink/include/CHIPProjectConfig.h b/examples/all-clusters-minimal-app/telink/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..9cfa65977d1717 --- /dev/null +++ b/examples/all-clusters-minimal-app/telink/include/CHIPProjectConfig.h @@ -0,0 +1,48 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + * + * Enable support for Chip-over-BLE (CHIPoBLE). + */ +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 + +/** + * CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE + * + * Reduce packet buffer pool size to 8 (default 15) to reduce ram consumption + */ +#define CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE 8 + +#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 diff --git a/examples/all-clusters-minimal-app/telink/prj.conf b/examples/all-clusters-minimal-app/telink/prj.conf new file mode 100644 index 00000000000000..791807a463a9e0 --- /dev/null +++ b/examples/all-clusters-minimal-app/telink/prj.conf @@ -0,0 +1,54 @@ +# +# Copyright (c) 2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This sample uses sample-defaults.conf to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# enable GPIO +CONFIG_GPIO=y + +# OpenThread configs +CONFIG_OPENTHREAD_MTD=y +CONFIG_OPENTHREAD_FTD=n + +# Default OpenThread network settings +CONFIG_OPENTHREAD_PANID=4660 +CONFIG_OPENTHREAD_CHANNEL=15 +CONFIG_OPENTHREAD_NETWORK_NAME="OpenThreadDemo" +CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" +CONFIG_NET_CONFIG_IEEE802154_DEV_NAME="IEEE802154_b91" + +# Disable Matter OTA DFU +CONFIG_CHIP_OTA_REQUESTOR=n + +# CHIP configuration +CONFIG_CHIP_PROJECT_CONFIG="include/CHIPProjectConfig.h" +CONFIG_CHIP_OPENTHREAD_CONFIG="../../platform/telink/project_include/OpenThreadConfig.h" + +CONFIG_CHIP_DEVICE_VENDOR_ID=65521 +# CHIP PID: 32769 == 0x8001 (all-clusters-minimal-app) +CONFIG_CHIP_DEVICE_PRODUCT_ID=32769 +CONFIG_CHIP_DEVICE_TYPE=65535 + +CONFIG_CHIP_DEVICE_SOFTWARE_VERSION=1 +CONFIG_CHIP_DEVICE_SOFTWARE_VERSION_STRING="2022" + +# Enable CHIP pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# CHIP shell +CONFIG_CHIP_LIB_SHELL=n \ No newline at end of file diff --git a/examples/all-clusters-minimal-app/telink/src/AppTask.cpp b/examples/all-clusters-minimal-app/telink/src/AppTask.cpp new file mode 100644 index 00000000000000..a08d81bf5b1a39 --- /dev/null +++ b/examples/all-clusters-minimal-app/telink/src/AppTask.cpp @@ -0,0 +1,288 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTask.h" + +#include "AppConfig.h" +#include "AppEvent.h" +#include "ButtonManager.h" +#include "LEDWidget.h" +#include "binding-handler.h" +#include +#include + +#include "ThreadUtil.h" + +#include +#include +#include +#include + +#include +#include + +#if CONFIG_CHIP_OTA_REQUESTOR +#include "OTAUtil.h" +#endif + +#include +#include + +LOG_MODULE_DECLARE(app); + +namespace { + +constexpr int kAppEventQueueSize = 10; +constexpr uint8_t kButtonPushEvent = 1; +constexpr uint8_t kButtonReleaseEvent = 0; + +K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); + +LEDWidget sStatusLED; + +Button sFactoryResetButton; +Button sBleAdvStartButton; + +bool sIsThreadProvisioned = false; +bool sIsThreadEnabled = false; +bool sIsThreadAttached = false; +bool sHaveBLEConnections = false; + +} // namespace + +using namespace ::chip; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; +using namespace ::chip::DeviceLayer::Internal; + +AppTask AppTask::sAppTask; + +constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE; + +CHIP_ERROR AppTask::Init() +{ + CHIP_ERROR ret; + + LOG_INF("Current Software Version: %u, %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION, + CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); + + // Initialize status LED + LEDWidget::InitGpio(SYSTEM_STATE_LED_PORT); + sStatusLED.Init(SYSTEM_STATE_LED_PIN); + + UpdateStatusLED(); + + InitButtons(); + + // Init ZCL Data Model and start server + static chip::CommonCaseDeviceServerInitParams initParams; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + chip::Server::GetInstance().Init(initParams); + + // Initialize device attestation config + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); + +#if CONFIG_CHIP_OTA_REQUESTOR + InitBasicOTARequestor(); +#endif + + // We only have network commissioning on endpoint 0. + // Set up a valid Network Commissioning cluster on endpoint 0 is done in + // src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp + emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false); + + ConfigurationMgr().LogDeviceConfig(); + + // Configure Bindings + ret = InitBindingHandlers(); + if (ret != CHIP_NO_ERROR) + { + LOG_ERR("InitBindingHandlers() failed"); + return ret; + } + + PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); + + // Add CHIP event handler and start CHIP thread. + // Note that all the initialization code should happen prior to this point to avoid data races + // between the main and the CHIP threads. + PlatformMgr().AddEventHandler(ChipEventHandler, 0); + + ret = ConnectivityMgr().SetBLEDeviceName("TelinkMinApp"); + if (ret != CHIP_NO_ERROR) + { + LOG_ERR("Fail to set BLE device name"); + return ret; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR AppTask::StartApp() +{ + CHIP_ERROR err = Init(); + + if (err != CHIP_NO_ERROR) + { + LOG_ERR("AppTask.Init() failed"); + return err; + } + + AppEvent event = {}; + + while (true) + { + int ret = k_msgq_get(&sAppEventQueue, &event, K_MSEC(10)); + + while (!ret) + { + DispatchEvent(&event); + ret = k_msgq_get(&sAppEventQueue, &event, K_NO_WAIT); + } + + sStatusLED.Animate(); + } +} + +void AppTask::FactoryResetButtonEventHandler(void) +{ + AppEvent event; + + event.Type = AppEvent::kEventType_Button; + event.ButtonEvent.Action = kButtonPushEvent; + event.Handler = FactoryResetHandler; + sAppTask.PostEvent(&event); +} + +void AppTask::FactoryResetHandler(AppEvent * aEvent) +{ + LOG_INF("Factory Reset triggered."); + chip::Server::GetInstance().ScheduleFactoryReset(); +} + +void AppTask::StartBleAdvButtonEventHandler(void) +{ + AppEvent event; + + event.Type = AppEvent::kEventType_Button; + event.ButtonEvent.Action = kButtonPushEvent; + event.Handler = StartBleAdvHandler; + sAppTask.PostEvent(&event); +} + +void AppTask::StartBleAdvHandler(AppEvent * aEvent) +{ + LOG_INF("BLE advertising start button pressed"); + + // Don't allow on starting Matter service BLE advertising after Thread provisioning. + if (ConnectivityMgr().IsThreadProvisioned()) + { + LOG_INF("Matter service BLE advertising not started - device is commissioned to a Thread network."); + return; + } + + if (ConnectivityMgr().IsBLEAdvertisingEnabled()) + { + LOG_INF("BLE advertising is already enabled"); + return; + } + + if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) + { + LOG_ERR("OpenBasicCommissioningWindow() failed"); + } +} + +void AppTask::UpdateStatusLED() +{ + if (sIsThreadProvisioned && sIsThreadEnabled) + { + if (sIsThreadAttached) + { + sStatusLED.Blink(950, 50); + } + else + { + sStatusLED.Blink(100, 100); + } + } + else + { + sStatusLED.Blink(50, 950); + } +} + +void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) +{ + switch (event->Type) + { + case DeviceEventType::kCHIPoBLEAdvertisingChange: + sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; + UpdateStatusLED(); + break; + case DeviceEventType::kThreadStateChange: + sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned(); + sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled(); + sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); + UpdateStatusLED(); + break; + case DeviceEventType::kThreadConnectivityChange: +#if CONFIG_CHIP_OTA_REQUESTOR + if (event->ThreadConnectivityChange.Result == kConnectivity_Established) + { + InitBasicOTARequestor(); + } +#endif + break; + default: + break; + } +} + +void AppTask::PostEvent(AppEvent * aEvent) +{ + if (!aEvent) + return; + if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) + { + LOG_INF("Failed to post event to app task event queue"); + } +} + +void AppTask::DispatchEvent(AppEvent * aEvent) +{ + if (!aEvent) + return; + if (aEvent->Handler) + { + aEvent->Handler(aEvent); + } + else + { + LOG_INF("Event received with no handler. Dropping event."); + } +} + +void AppTask::InitButtons(void) +{ + sFactoryResetButton.Configure(BUTTON_PORT, BUTTON_PIN_3, BUTTON_PIN_1, FactoryResetButtonEventHandler); + sBleAdvStartButton.Configure(BUTTON_PORT, BUTTON_PIN_4, BUTTON_PIN_2, StartBleAdvButtonEventHandler); + + ButtonManagerInst().AddButton(sFactoryResetButton); + ButtonManagerInst().AddButton(sBleAdvStartButton); +} diff --git a/examples/all-clusters-minimal-app/telink/src/main.cpp b/examples/all-clusters-minimal-app/telink/src/main.cpp new file mode 100644 index 00000000000000..48adaee45a5115 --- /dev/null +++ b/examples/all-clusters-minimal-app/telink/src/main.cpp @@ -0,0 +1,83 @@ +/* + * + * 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 + +LOG_MODULE_REGISTER(app); + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::DeviceLayer; + +int main(void) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + err = chip::Platform::MemoryInit(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("Platform::MemoryInit() failed"); + goto exit; + } + + LOG_INF("Init CHIP stack"); + err = PlatformMgr().InitChipStack(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("PlatformMgr().InitChipStack() failed"); + goto exit; + } + + LOG_INF("Starting CHIP task"); + err = PlatformMgr().StartEventLoopTask(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("PlatformMgr().StartEventLoopTask() failed"); + goto exit; + } + + LOG_INF("Init Thread stack"); + err = ThreadStackMgr().InitThreadStack(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("ThreadStackMgr().InitThreadStack() failed"); + goto exit; + } + +#ifdef CONFIG_OPENTHREAD_MTD + err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); +#else + err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); +#endif + if (err != CHIP_NO_ERROR) + { + LOG_ERR("ConnectivityMgr().SetThreadDeviceType() failed"); + goto exit; + } + + err = GetAppTask().StartApp(); + +exit: + LOG_ERR("Exited with code %" CHIP_ERROR_FORMAT, err.Format()); + return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/all-clusters-minimal-app/telink/third_party/connectedhomeip b/examples/all-clusters-minimal-app/telink/third_party/connectedhomeip new file mode 120000 index 00000000000000..c866b86874994d --- /dev/null +++ b/examples/all-clusters-minimal-app/telink/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../.. \ No newline at end of file diff --git a/examples/light-switch-app/telink/.gitignore b/examples/light-switch-app/telink/.gitignore new file mode 100644 index 00000000000000..84c048a73cc2e5 --- /dev/null +++ b/examples/light-switch-app/telink/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/examples/light-switch-app/telink/Readme.md b/examples/light-switch-app/telink/Readme.md index 6f8782bac0122d..2c5aa4a940f687 100755 --- a/examples/light-switch-app/telink/Readme.md +++ b/examples/light-switch-app/telink/Readme.md @@ -1,3 +1,12 @@ +# Matter Telink Light Switch Example Application + +The Telink Light Switch Example demonstrates how to remotely control a lighting +devices such as light bulbs or LEDs. The application should be used together +with the [lighting app example](../../lighting-app/telink/README.md). The light +switch uses buttons to test changing the lighting application example LED state +and works as a brightness dimmer. You can use this example as a reference for +creating your own application. + ![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) ## Build and flash @@ -73,15 +82,18 @@ following states: 1. Build [chip-tool cli](https://github.com/project-chip/connectedhomeip/blob/master/examples/chip-tool/README.md) + 2. Pair with device ``` - ${CHIP_TOOL_DIR}/chip-tool pairing code ${NODE_ID_TO_ASSIGN} MT:D8XA0CQM00KA0648G00 + ${CHIP_TOOL_DIR}/chip-tool pairing ble-thread ${NODE_ID} hex:${DATASET} ${PIN_CODE} ${DISCRIMINATOR} ``` - here: + Example: - - \${NODE_ID_TO_ASSIGN} is the node id to assign to the light switch + ``` + ./chip-tool pairing ble-thread 1234 hex:0e080000000000010000000300000f35060004001fffe0020811111111222222220708fd61f77bd3df233e051000112233445566778899aabbccddeeff030e4f70656e54687265616444656d6f010212340410445f2b5ca6f2a93a55ce570a70efeecb0c0402a0fff8 20202021 3840 + ``` ### Binding cluster and endpoints @@ -210,14 +222,15 @@ feature for another Telink example: - set CONFIG_CHIP_OTA_REQUESTOR=y in corresponding "prj.conf" configuration file. -- remove "boards/tlsr9518adk80d.overlay" file to enable 2MB flash storage. After build application with enabled OTA feature, use next binary files: -- zephyr_final.bin - main binary to flash PCB (Use 2MB PCB). +- zephyr.bin - main binary to flash PCB (Use 2MB PCB). - zephyr-ota.bin - binary for OTA Provider -- zephyr.bin - ignore this file. -- zephyr.signed.bin - ignore this file. + +All binaries has the same SW version. To test OTA “zephyr-ota.bin” should have +higher SW version than base SW. Set CONFIG_CHIP_DEVICE_SOFTWARE_VERSION=2 in +corresponding “prj.conf” configuration file. Usage of OTA: diff --git a/examples/lighting-app/telink/.gitignore b/examples/lighting-app/telink/.gitignore new file mode 100644 index 00000000000000..84c048a73cc2e5 --- /dev/null +++ b/examples/lighting-app/telink/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/examples/lighting-app/telink/Readme.md b/examples/lighting-app/telink/Readme.md index b173d2cb0ddeb8..018fdd386dc898 100644 --- a/examples/lighting-app/telink/Readme.md +++ b/examples/lighting-app/telink/Readme.md @@ -1,3 +1,10 @@ +# Matter Telink Lighting Example Application + +The Telink Lighting Example demonstrates how to remotely control a white +dimmable light bulb. It uses buttons to test changing the lighting and device +states and LEDs to show the state of these changes. You can use this example as +a reference for creating your own application. + ![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) ## Build and flash @@ -75,15 +82,18 @@ following states: 1. Build [chip-tool cli](https://github.com/project-chip/connectedhomeip/blob/master/examples/chip-tool/README.md) + 2. Pair with device ``` - ${CHIP_TOOL_DIR}/chip-tool pairing code ${NODE_ID_TO_ASSIGN} MT:D8XA0CQM00KA0648G00 + ${CHIP_TOOL_DIR}/chip-tool pairing ble-thread ${NODE_ID} hex:${DATASET} ${PIN_CODE} ${DISCRIMINATOR} ``` - here: + Example: - - \${NODE_ID_TO_ASSIGN} is the node id to assign to the lightbulb + ``` + ./chip-tool pairing ble-thread 1234 hex:0e080000000000010000000300000f35060004001fffe0020811111111222222220708fd61f77bd3df233e051000112233445566778899aabbccddeeff030e4f70656e54687265616444656d6f010212340410445f2b5ca6f2a93a55ce570a70efeecb0c0402a0fff8 20202021 3840 + ``` 3. Switch on the light: @@ -155,14 +165,15 @@ feature for another Telink example: - set CONFIG_CHIP_OTA_REQUESTOR=y in corresponding "prj.conf" configuration file. -- remove "boards/tlsr9518adk80d.overlay" file to enable 2MB flash storage. After build application with enabled OTA feature, use next binary files: -- zephyr_final.bin - main binary to flash PCB (Use 2MB PCB). +- zephyr.bin - main binary to flash PCB (Use 2MB PCB). - zephyr-ota.bin - binary for OTA Provider -- zephyr.bin - ignore this file. -- zephyr.signed.bin - ignore this file. + +All binaries has the same SW version. To test OTA “zephyr-ota.bin” should have +higher SW version than base SW. Set CONFIG_CHIP_DEVICE_SOFTWARE_VERSION=2 in +corresponding “prj.conf” configuration file. Usage of OTA: diff --git a/examples/lighting-app/telink/prj.conf b/examples/lighting-app/telink/prj.conf index 8c2317982e35b4..3e94168f31df3d 100644 --- a/examples/lighting-app/telink/prj.conf +++ b/examples/lighting-app/telink/prj.conf @@ -25,8 +25,8 @@ CONFIG_GPIO=y CONFIG_PWM=y # OpenThread configs -CONFIG_OPENTHREAD_MTD=y -CONFIG_OPENTHREAD_FTD=n +CONFIG_OPENTHREAD_MTD=n +CONFIG_OPENTHREAD_FTD=y # Default OpenThread network settings CONFIG_OPENTHREAD_PANID=4660 diff --git a/examples/ota-requestor-app/telink/.gitignore b/examples/ota-requestor-app/telink/.gitignore new file mode 100644 index 00000000000000..84c048a73cc2e5 --- /dev/null +++ b/examples/ota-requestor-app/telink/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/examples/ota-requestor-app/telink/src/AppTask.cpp b/examples/ota-requestor-app/telink/src/AppTask.cpp index 182f5732d0ec59..314e228772899b 100644 --- a/examples/ota-requestor-app/telink/src/AppTask.cpp +++ b/examples/ota-requestor-app/telink/src/AppTask.cpp @@ -140,6 +140,8 @@ CHIP_ERROR AppTask::Init() chip::Server::GetInstance().Init(initParams); // We only have network commissioning on endpoint 0. + // Set up a valid Network Commissioning cluster on endpoint 0 is done in + // src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.cpp emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false); // Initialize device attestation config diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index f86b5a8270032a..99be77b3ad7c3c 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -686,6 +686,10 @@ def GenioTargets(): ALL.append(target) # Simple targets added one by one +ALL.append(Target('telink-tlsr9518adk80d-all-clusters', TelinkBuilder, + board=TelinkBoard.TLSR9518ADK80D, app=TelinkApp.ALL_CLUSTERS)) +ALL.append(Target('telink-tlsr9518adk80d-all-clusters-minimal', TelinkBuilder, + board=TelinkBoard.TLSR9518ADK80D, app=TelinkApp.ALL_CLUSTERS_MINIMAL)) ALL.append(Target('telink-tlsr9518adk80d-light', TelinkBuilder, board=TelinkBoard.TLSR9518ADK80D, app=TelinkApp.LIGHT)) ALL.append(Target('telink-tlsr9518adk80d-light-switch', TelinkBuilder, diff --git a/scripts/build/builders/telink.py b/scripts/build/builders/telink.py index 8ec841285175f1..9b448e5b3f9023 100644 --- a/scripts/build/builders/telink.py +++ b/scripts/build/builders/telink.py @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Project CHIP Authors +# 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. @@ -21,12 +21,18 @@ class TelinkApp(Enum): + ALL_CLUSTERS = auto() + ALL_CLUSTERS_MINIMAL = auto() LIGHT = auto() SWITCH = auto() OTA_REQUESTOR = auto() def ExampleName(self): - if self == TelinkApp.LIGHT: + if self == TelinkApp.ALL_CLUSTERS: + return 'all-clusters-app' + elif self == TelinkApp.ALL_CLUSTERS_MINIMAL: + return 'all-clusters-minimal-app' + elif self == TelinkApp.LIGHT: return 'lighting-app' elif self == TelinkApp.SWITCH: return 'light-switch-app' @@ -36,7 +42,11 @@ def ExampleName(self): raise Exception('Unknown app type: %r' % self) def AppNamePrefix(self): - if self == TelinkApp.LIGHT: + if self == TelinkApp.ALL_CLUSTERS: + return 'chip-telink-all-clusters-example' + elif self == TelinkApp.ALL_CLUSTERS_MINIMAL: + return 'chip-telink-all-clusters-minimal-example' + elif self == TelinkApp.LIGHT: return 'chip-telink-lighting-example' elif self == TelinkApp.SWITCH: return 'chip-telink-light-switch-example' diff --git a/scripts/build/testdata/all_targets_except_host.txt b/scripts/build/testdata/all_targets_except_host.txt index fb0a11a0bf87ee..039d833eb36fcf 100644 --- a/scripts/build/testdata/all_targets_except_host.txt +++ b/scripts/build/testdata/all_targets_except_host.txt @@ -249,6 +249,8 @@ qpg-light qpg-lock qpg-persistent-storage qpg-shell +telink-tlsr9518adk80d-all-clusters +telink-tlsr9518adk80d-all-clusters-minimal telink-tlsr9518adk80d-light telink-tlsr9518adk80d-light-switch telink-tlsr9518adk80d-ota-requestor diff --git a/scripts/build/testdata/build_all_except_host.txt b/scripts/build/testdata/build_all_except_host.txt index 66a5e926823921..401f68cedf0f17 100644 --- a/scripts/build/testdata/build_all_except_host.txt +++ b/scripts/build/testdata/build_all_except_host.txt @@ -1172,6 +1172,20 @@ gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/exa # Generating qpg-shell gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/examples/shell/qpg '--args=qpg_target_ic="qpg6105"' {out}/qpg-shell +# Generating telink-tlsr9518adk80d-all-clusters +bash -c 'export ZEPHYR_TOOLCHAIN_VARIANT=zephyr +export ZEPHYR_BASE="$TELINK_ZEPHYR_BASE" +export ZEPHYR_SDK_INSTALL_DIR="$TELINK_ZEPHYR_SDK_DIR" +source "$ZEPHYR_BASE/zephyr-env.sh"; +west build --cmake-only -d {out}/telink-tlsr9518adk80d-all-clusters -b tlsr9518adk80d {root}/examples/all-clusters-app/telink' + +# Generating telink-tlsr9518adk80d-all-clusters-minimal +bash -c 'export ZEPHYR_TOOLCHAIN_VARIANT=zephyr +export ZEPHYR_BASE="$TELINK_ZEPHYR_BASE" +export ZEPHYR_SDK_INSTALL_DIR="$TELINK_ZEPHYR_SDK_DIR" +source "$ZEPHYR_BASE/zephyr-env.sh"; +west build --cmake-only -d {out}/telink-tlsr9518adk80d-all-clusters-minimal -b tlsr9518adk80d {root}/examples/all-clusters-minimal-app/telink' + # Generating telink-tlsr9518adk80d-light bash -c 'export ZEPHYR_TOOLCHAIN_VARIANT=zephyr export ZEPHYR_BASE="$TELINK_ZEPHYR_BASE" @@ -2417,6 +2431,18 @@ ninja -C {out}/qpg-persistent-storage # Building qpg-shell ninja -C {out}/qpg-shell +# Building telink-tlsr9518adk80d-all-clusters +bash -c 'export ZEPHYR_TOOLCHAIN_VARIANT=zephyr +export ZEPHYR_BASE="$TELINK_ZEPHYR_BASE" +export ZEPHYR_SDK_INSTALL_DIR="$TELINK_ZEPHYR_SDK_DIR" +ninja -C {out}/telink-tlsr9518adk80d-all-clusters' + +# Building telink-tlsr9518adk80d-all-clusters-minimal +bash -c 'export ZEPHYR_TOOLCHAIN_VARIANT=zephyr +export ZEPHYR_BASE="$TELINK_ZEPHYR_BASE" +export ZEPHYR_SDK_INSTALL_DIR="$TELINK_ZEPHYR_SDK_DIR" +ninja -C {out}/telink-tlsr9518adk80d-all-clusters-minimal' + # Building telink-tlsr9518adk80d-light bash -c 'export ZEPHYR_TOOLCHAIN_VARIANT=zephyr export ZEPHYR_BASE="$TELINK_ZEPHYR_BASE" diff --git a/scripts/build/testdata/glob_star_targets_except_host.txt b/scripts/build/testdata/glob_star_targets_except_host.txt index bc2806b54bcc4e..c5db6a27cb177c 100644 --- a/scripts/build/testdata/glob_star_targets_except_host.txt +++ b/scripts/build/testdata/glob_star_targets_except_host.txt @@ -114,6 +114,8 @@ qpg-light qpg-lock qpg-persistent-storage qpg-shell +telink-tlsr9518adk80d-all-clusters +telink-tlsr9518adk80d-all-clusters-minimal telink-tlsr9518adk80d-light telink-tlsr9518adk80d-light-switch telink-tlsr9518adk80d-ota-requestor