From 8edcecd7a47da7cd95f49fddcc14ecfa979b3136 Mon Sep 17 00:00:00 2001 From: Sid Hsu Date: Wed, 8 May 2024 22:09:33 +0800 Subject: [PATCH] [Infineon] Add an example of thermostat for CYW30739. (#33357) --- .github/workflows/examples-infineon.yaml | 26 +++ examples/thermostat/infineon/cyw30739/.gn | 28 +++ .../thermostat/infineon/cyw30739/BUILD.gn | 63 ++++++ .../thermostat/infineon/cyw30739/README.md | 194 ++++++++++++++++++ .../thermostat/infineon/cyw30739/args.gni | 33 +++ .../infineon/cyw30739/build_overrides | 1 + .../infineon/cyw30739/include/AppTask.h | 24 +++ .../cyw30739/include/CHIPProjectConfig.h | 38 ++++ .../infineon/cyw30739/include/SensorManager.h | 41 ++++ .../cyw30739/include/TemperatureManager.h | 56 +++++ .../infineon/cyw30739/include/ThermostatUI.h | 33 +++ .../infineon/cyw30739/src/AppTask.cpp | 90 ++++++++ .../infineon/cyw30739/src/SensorManager.cpp | 84 ++++++++ .../cyw30739/src/TemperatureManager.cpp | 154 ++++++++++++++ .../infineon/cyw30739/src/ThermostatUI.cpp | 63 ++++++ .../infineon/cyw30739/src/ZclCallbacks.cpp | 49 +++++ .../cyw30739/third_party/connectedhomeip | 1 + scripts/build/build/targets.py | 1 + scripts/build/builders/cyw30739.py | 3 + .../build/testdata/all_targets_linux_x64.txt | 2 +- 20 files changed, 983 insertions(+), 1 deletion(-) create mode 100644 examples/thermostat/infineon/cyw30739/.gn create mode 100644 examples/thermostat/infineon/cyw30739/BUILD.gn create mode 100644 examples/thermostat/infineon/cyw30739/README.md create mode 100644 examples/thermostat/infineon/cyw30739/args.gni create mode 120000 examples/thermostat/infineon/cyw30739/build_overrides create mode 100644 examples/thermostat/infineon/cyw30739/include/AppTask.h create mode 100644 examples/thermostat/infineon/cyw30739/include/CHIPProjectConfig.h create mode 100644 examples/thermostat/infineon/cyw30739/include/SensorManager.h create mode 100644 examples/thermostat/infineon/cyw30739/include/TemperatureManager.h create mode 100644 examples/thermostat/infineon/cyw30739/include/ThermostatUI.h create mode 100644 examples/thermostat/infineon/cyw30739/src/AppTask.cpp create mode 100644 examples/thermostat/infineon/cyw30739/src/SensorManager.cpp create mode 100644 examples/thermostat/infineon/cyw30739/src/TemperatureManager.cpp create mode 100644 examples/thermostat/infineon/cyw30739/src/ThermostatUI.cpp create mode 100644 examples/thermostat/infineon/cyw30739/src/ZclCallbacks.cpp create mode 120000 examples/thermostat/infineon/cyw30739/third_party/connectedhomeip diff --git a/.github/workflows/examples-infineon.yaml b/.github/workflows/examples-infineon.yaml index 071905d62f0417..68b868c8816305 100644 --- a/.github/workflows/examples-infineon.yaml +++ b/.github/workflows/examples-infineon.yaml @@ -190,6 +190,32 @@ jobs: /tmp/bloat_reports/ - name: Clean out build output run: rm -rf ./out + - name: Build CYW30739 Thermostat App + run: | + ./scripts/run_in_build_env.sh \ + "./scripts/build/build_examples.py \ + --target cyw30739-cyw30739b2_p5_evk_01-thermostat \ + --target cyw30739-cyw30739b2_p5_evk_02-thermostat \ + --target cyw30739-cyw30739b2_p5_evk_03-thermostat \ + build \ + --copy-artifacts-to out/artifacts \ + " + - name: Get thermostat size stats + run: | + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + cyw30739 CYW30739B2-P5-EVK-01 thermostat \ + out/artifacts/cyw30739-cyw30739b2_p5_evk_01-thermostat/thermostat-CYW30739B2-P5-EVK-01.elf \ + /tmp/bloat_reports/ + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + cyw30739 CYW30739B2-P5-EVK-02 thermostat \ + out/artifacts/cyw30739-cyw30739b2_p5_evk_02-thermostat/thermostat-CYW30739B2-P5-EVK-02.elf \ + /tmp/bloat_reports/ + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + cyw30739 CYW30739B2-P5-EVK-03 thermostat \ + out/artifacts/cyw30739-cyw30739b2_p5_evk_03-thermostat/thermostat-CYW30739B2-P5-EVK-03.elf \ + /tmp/bloat_reports/ + - name: Clean out build output + run: rm -rf ./out - name: Uploading Size Reports uses: ./.github/actions/upload-size-reports if: ${{ !env.ACT }} diff --git a/examples/thermostat/infineon/cyw30739/.gn b/examples/thermostat/infineon/cyw30739/.gn new file mode 100644 index 00000000000000..90115e4209947e --- /dev/null +++ b/examples/thermostat/infineon/cyw30739/.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 = "cyw30739" + + import("//args.gni") +} diff --git a/examples/thermostat/infineon/cyw30739/BUILD.gn b/examples/thermostat/infineon/cyw30739/BUILD.gn new file mode 100644 index 00000000000000..b7fae768f08bb0 --- /dev/null +++ b/examples/thermostat/infineon/cyw30739/BUILD.gn @@ -0,0 +1,63 @@ +# 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("//build_overrides/cyw30739_sdk.gni") + +import("${chip_root}/examples/platform/infineon/cyw30739/args.gni") +import("${matter_wpan_sdk_build_root}/matter_wpan_executable.gni") + +app_name = "thermostat" +cyw30739_project_dir = "${chip_root}/examples/thermostat/infineon/cyw30739" + +matter_wpan_example("wpan_example") { + sources = [ "${cyw30739_project_dir}/include/CHIPProjectConfig.h" ] + + include_dirs = [ "${cyw30739_project_dir}/include" ] +} + +template("matter_wpan_app") { + forward_variables_from(invoker, [ "board" ]) + + import("${matter_wpan_sdk_build_root}/boards/${board}/args.gni") + + matter_wpan_executable(target_name) { + sources = [ + "src/AppTask.cpp", + "src/SensorManager.cpp", + "src/TemperatureManager.cpp", + "src/ZclCallbacks.cpp", + ] + + if (board_enable_display) { + sources += [ "src/ThermostatUI.cpp" ] + } + + deps = [ app_data_model ] + + include_dirs = [ "include" ] + } +} + +foreach(board, matter_wpan_sdk_board_list) { + matter_wpan_app("${app_name}-${board}") { + } +} + +group("default") { + deps = [] + foreach(board, matter_wpan_sdk_board_list) { + deps += [ ":${app_name}-${board}" ] + } +} diff --git a/examples/thermostat/infineon/cyw30739/README.md b/examples/thermostat/infineon/cyw30739/README.md new file mode 100644 index 00000000000000..44052add4d0ed4 --- /dev/null +++ b/examples/thermostat/infineon/cyw30739/README.md @@ -0,0 +1,194 @@ +# Matter CYW30739 Thermostat Example + +An example showing the use of Matter on the Infineon CYW30739 platform. + +--- + +## Table of Contents + +- [Matter CYW30739 Thermostat Example](#matter-cyw30739-thermostat-example) + - [Table of Contents](#table-of-contents) + - [Introduction](#introduction) + - [Installing ModusToolbox™ Software](#installing-modustoolbox-software) + - [ModusToolbox™ tools package](#modustoolbox-tools-package) + - [Note for WSL (Windows Subsystem for Linux)](#note-for-wsl-windows-subsystem-for-linux) + - [Checkout Submodules](#checkout-submodules) + - [Building](#building) + - [Factory Data](#factory-data) + - [Commissionable Data](#commissionable-data) + - [Device Information](#device-information) + - [DAC / DAC Key / PAI Certificate / Certificate Declaration](#dac--dac-key--pai-certificate--certificate-declaration) + - [Flashing the Application](#flashing-the-application) + - [Enter Recovery Mode](#enter-recovery-mode) + - [Run Flash Script](#run-flash-script) + - [Running the Complete Example](#running-the-complete-example) + +--- + +## Introduction + +The CYW30739 thermostat example provides a baseline demonstration of a +thermostat device, built using Matter and the Infineon Modustoolbox SDK. It can +be controlled by a Matter controller over Openthread network. + +The CYW30739 device can be commissioned over Bluetooth Low Energy where the +device and the Matter controller will exchange security information with the +Rendez-vous procedure. Target Thread Network information including the active +dataset and CASE credentials are then provided. + +## Installing [ModusToolbox™ Software](https://www.infineon.com/cms/en/design-support/tools/sdk/modustoolbox-software) + +Follow the +[Installation Guide](https://www.infineon.com/ModusToolboxInstallguide) to +download and install the ModusToolbox™ Software. + +### ModusToolbox™ tools package + +ModusToolbox™ tools package should be automatically installed in the default +location if you followed the +[Installation Guide](https://www.infineon.com/ModusToolboxInstallguide). Please +refer to the Installation Guide for the default location for different operating +systems. + +If you need to install the ModusToolbox™ tools package in a custom location, you +must set the environment variable `CY_TOOLS_PATHS` to the +`/path/to/ModusToolbox/tools_x.x` to specify the location of tools. + +```bash +export CY_TOOLS_PATHS="/path/to/ModusToolbox/tools_x.x" +``` + +#### Note for WSL (Windows Subsystem for Linux) + +If you are using WSL, please ensure you have installed the ModusToolbox™ +Software for Linux. Running Windows tools directly from the WSL command line +would cause path resolution failure in the build process. + +### Checkout Submodules + +Before building the example, check out the Matter repository and sync submodules +using the following command: + +```bash +$ cd ~/connectedhomeip +$ scripts/checkout_submodules.py --platform infineon +``` + +## Building + +- Build the example application: + + ```bash + $ cd ~/connectedhomeip + $ scripts/examples/gn_build_example.sh examples/thermostat/infineon/cyw30739 out/cyw30739-thermostat + ``` + +- OR use GN/Ninja directly + + ```bash + $ cd ~/connectedhomeip + $ source scripts/activate.sh + $ gn gen --root=examples/thermostat/infineon/cyw30739 out/cyw30739-thermostat + $ ninja -C out/cyw30739-thermostat [thermostat-BOARD_NAME] + ``` + +- To delete generated executable, libraries and object files use: + + ```bash + $ cd ~/connectedhomeip + $ rm -rf out/cyw30739-thermostat + ``` + +## Factory Data + +### Commissionable Data + +Infineon CYW30739 examples use test passcode, discriminator and PAKE parameters +by default. For a production build, manufacturers should override commissionable +data by the following arguments: + +- `matter_passcode`, `matter_discriminator`, `matter_pake_iteration_count`, + `matter_pake_salt` + + ```bash + $ cd ~/connectedhomeip + $ scripts/examples/gn_build_example.sh examples/thermostat/infineon/cyw30739 out/cyw30739-thermostat \ + 'matter_passcode=20202021' \ + 'matter_discriminator=3840' \ + 'matter_pake_iteration_count=1000' \ + 'matter_pake_salt="U1BBS0UyUCBLZXkgU2FsdA=="' + ``` + +### Device Information + +Infineon CYW30739 examples support overriding the default device information by +the following arguments: + +- matter_vendor_name +- matter_vendor_id +- matter_product_name +- matter_product_id +- matter_serial_number +- matter_hardware_version +- matter_hardware_version_string + +To override the default device information, pass the desired values to the +`gn_build_example.sh` script as arguments. + + ```bash + $ cd ~/connectedhomeip + $ scripts/examples/gn_build_example.sh examples/thermostat/infineon/cyw30739 out/cyw30739-thermostat \ + 'matter_vendor_name="Infineon"' \ + 'matter_vendor_id="0x1388"' \ + 'matter_product_name="TEST_PRODUCT"' \ + 'matter_product_id="0x0001"' \ + 'matter_serial_number="TEST_SN"' \ + 'matter_hardware_version=30739' \ + 'matter_hardware_version_string="30739"' + ``` + +### DAC / DAC Key / PAI Certificate / Certificate Declaration + +Infineon CYW30739 examples use development certifications, keys, and CD by +default. For a production build, manufacturers can provision certifications, +keys, and CD by the following arguments: + +- `matter_att_cert`, `matter_att_cert_password`, `matter_cd` + + ```bash + $ cd ~/connectedhomeip + $ scripts/examples/gn_build_example.sh examples/thermostat/infineon/cyw30739 out/cyw30739-thermostat \ + 'matter_att_cert="/path/to/att_cert.p12"' \ + 'matter_att_cert_password="password"' \ + 'matter_cd="/path/to/cd.der"' + ``` + +## Flashing the Application + +### Enter Recovery Mode + +Put the CYW30739 in to the recovery mode before running the flash script. + +1. Press and hold the `RECOVERY` button on the board. +2. Press and hold the `RESET` button on the board. +3. Release the `RESET` button. +4. After one second, release the `RECOVERY` button. + +### Run Flash Script + +- On the command line: + + ```bash + $ cd ~/connectedhomeip + $ out/cyw30739-thermostat/thermostat-BOARD_NAME.flash.py --port + ``` + +## Running the Complete Example + +- It is assumed here that you already have an OpenThread border router + configured and running. If not see the following guide + [Openthread_border_router](https://github.com/project-chip/connectedhomeip/blob/master/docs/guides/openthread_border_router_pi.md) + for more information on how to setup a border router on a raspberryPi. + +- For this example to work, it is necessary to have a second CYW30739 device + running the thermostat example commissioned on the same OpenThread network diff --git a/examples/thermostat/infineon/cyw30739/args.gni b/examples/thermostat/infineon/cyw30739/args.gni new file mode 100644 index 00000000000000..88c48b5b1a1f5e --- /dev/null +++ b/examples/thermostat/infineon/cyw30739/args.gni @@ -0,0 +1,33 @@ +# 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}/src/platform/Infineon/CYW30739/args.gni") + +app_data_model = "${chip_root}/examples/thermostat/thermostat-common" + +chip_openthread_ftd = false +chip_enable_icd_server = true +chip_enable_ota_requestor = true + +matter_product_id = "0x0006" +matter_product_name = "CYW30739 Thermostat App" +matter_att_cert = "${chip_root}/examples/platform/infineon/credentials/development/attestation/Matter-Development-DAC-1388-0006.p12" + +matter_wpan_sdk_board_list = [ + "CYW30739B2-P5-EVK-01", + "CYW30739B2-P5-EVK-02", + "CYW30739B2-P5-EVK-03", +] diff --git a/examples/thermostat/infineon/cyw30739/build_overrides b/examples/thermostat/infineon/cyw30739/build_overrides new file mode 120000 index 00000000000000..995884e6163eb5 --- /dev/null +++ b/examples/thermostat/infineon/cyw30739/build_overrides @@ -0,0 +1 @@ +../../../build_overrides \ No newline at end of file diff --git a/examples/thermostat/infineon/cyw30739/include/AppTask.h b/examples/thermostat/infineon/cyw30739/include/AppTask.h new file mode 100644 index 00000000000000..d71018ffb07cba --- /dev/null +++ b/examples/thermostat/infineon/cyw30739/include/AppTask.h @@ -0,0 +1,24 @@ +/* + * + * 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 + +void AppTaskMain(intptr_t args); +void UpdateThermoStatUI(intptr_t aArg); diff --git a/examples/thermostat/infineon/cyw30739/include/CHIPProjectConfig.h b/examples/thermostat/infineon/cyw30739/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..d0e3c7dce66c9a --- /dev/null +++ b/examples/thermostat/infineon/cyw30739/include/CHIPProjectConfig.h @@ -0,0 +1,38 @@ +/* + * + * 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 + +// -------------------- Device Identification Configuration -------------------- +/* The SoftwareVersionString attribute of the Basic cluster. */ +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.3.1.327" + +/* The SoftwareVersion attribute of the Basic cluster. */ +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x00130547 + +// -------------------- Test Configuration -------------------- +#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 diff --git a/examples/thermostat/infineon/cyw30739/include/SensorManager.h b/examples/thermostat/infineon/cyw30739/include/SensorManager.h new file mode 100644 index 00000000000000..fad73f7661935c --- /dev/null +++ b/examples/thermostat/infineon/cyw30739/include/SensorManager.h @@ -0,0 +1,41 @@ +/* + * + * 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 + +using namespace chip::DeviceLayer; + +class SensorManager +{ +public: + void Init(AsyncWorkFunct interruptHandler); + +private: + static void InterruptHandler(void * data, uint8_t port_pin); + + friend SensorManager & SensorMgr(); + static SensorManager sSensorManager; + static AsyncWorkFunct sAppInterruptHandler; +}; + +inline SensorManager & SensorMgr() +{ + return SensorManager::sSensorManager; +} diff --git a/examples/thermostat/infineon/cyw30739/include/TemperatureManager.h b/examples/thermostat/infineon/cyw30739/include/TemperatureManager.h new file mode 100644 index 00000000000000..cd82f2c80f6c7f --- /dev/null +++ b/examples/thermostat/infineon/cyw30739/include/TemperatureManager.h @@ -0,0 +1,56 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include + +using namespace chip; +using namespace ::chip::app::Clusters::Thermostat; + +class TemperatureManager +{ +public: + CHIP_ERROR Init(); + void SensorInterruptHandler(); + void AttributeChangeHandler(EndpointId endpointId, AttributeId attributeId, uint8_t * value, uint16_t size); + SystemModeEnum GetMode(); + int16_t GetCurrentTemp(); + uint8_t GetCurrentHumidity(); + int8_t GetHeatingSetPoint(); + int8_t GetCoolingSetPoint(); + +private: + friend TemperatureManager & TempMgr(); + + int8_t mCurrentTempCelsius; + uint8_t mCurrentHumidity; + int8_t mCoolingCelsiusSetPoint; + int8_t mHeatingCelsiusSetPoint; + SystemModeEnum mThermMode; + + int8_t ConvertToPrintableTemp(int16_t temperature); + static TemperatureManager sTempMgr; +}; + +inline TemperatureManager & TempMgr() +{ + return TemperatureManager::sTempMgr; +} diff --git a/examples/thermostat/infineon/cyw30739/include/ThermostatUI.h b/examples/thermostat/infineon/cyw30739/include/ThermostatUI.h new file mode 100644 index 00000000000000..1da4f7f831e176 --- /dev/null +++ b/examples/thermostat/infineon/cyw30739/include/ThermostatUI.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. + */ + +#pragma once + +#include + +class ThermostatUI +{ +public: + static void DrawUI(); + static void SetCurrentTemp(int8_t temp); + static void SetCurrentHumidity(uint8_t humidity); + +private: + static void DrawCurrentTemp(int8_t temp); + static void DrawCurrentHumidity(uint8_t humidity); +}; diff --git a/examples/thermostat/infineon/cyw30739/src/AppTask.cpp b/examples/thermostat/infineon/cyw30739/src/AppTask.cpp new file mode 100644 index 00000000000000..050c72c62f7b18 --- /dev/null +++ b/examples/thermostat/infineon/cyw30739/src/AppTask.cpp @@ -0,0 +1,90 @@ +/* + * + * 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 "SensorManager.h" +#include "TemperatureManager.h" +#ifdef BOARD_ENABLE_DISPLAY +#include "ThermostatUI.h" +#endif +#include +#include +#include + +using namespace chip::app; + +static void SensorInterruptHandler(intptr_t aArg); + +void AppTaskMain(intptr_t args) +{ + SensorMgr().Init(SensorInterruptHandler); + if (TempMgr().Init() != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "TempMgr Init fail"); + } + + CYW30739MatterConfig::InitApp(); +} + +void UpdateThermoStatUI(intptr_t aArg) +{ +#ifdef BOARD_ENABLE_DISPLAY + ThermostatUI::SetCurrentTemp(TempMgr().GetCurrentTemp()); + ThermostatUI::SetCurrentHumidity(TempMgr().GetCurrentHumidity()); + ThermostatUI::DrawUI(); +#endif + ChipLogDetail(Zcl, "Thermostat Status - M:%d Temp:%d'C Humidity:%d'C H:%d'C C:%d'C", to_underlying(TempMgr().GetMode()), + TempMgr().GetCurrentTemp(), TempMgr().GetCurrentHumidity(), TempMgr().GetHeatingSetPoint(), + TempMgr().GetCoolingSetPoint()); +} + +void SensorInterruptHandler(intptr_t aArg) +{ + TempMgr().SensorInterruptHandler(); + UpdateThermoStatUI(aArg); +} + +void OnIdentifyTriggerEffect(Identify * identify) +{ + switch (identify->mCurrentEffectIdentifier) + { + case Clusters::Identify::EffectIdentifierEnum::kBlink: + ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kBlink"); + break; + case Clusters::Identify::EffectIdentifierEnum::kBreathe: + ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kBreathe"); + break; + case Clusters::Identify::EffectIdentifierEnum::kOkay: + ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kOkay"); + break; + case Clusters::Identify::EffectIdentifierEnum::kChannelChange: + ChipLogProgress(Zcl, "Clusters::Identify::EffectIdentifierEnum::kChannelChange"); + break; + default: + ChipLogProgress(Zcl, "No identifier effect"); + break; + } +} + +static Identify gIdentify = { + chip::EndpointId{ 1 }, + [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStart"); }, + [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStop"); }, + Clusters::Identify::IdentifyTypeEnum::kNone, + OnIdentifyTriggerEffect, +}; diff --git a/examples/thermostat/infineon/cyw30739/src/SensorManager.cpp b/examples/thermostat/infineon/cyw30739/src/SensorManager.cpp new file mode 100644 index 00000000000000..6e81016beb86b5 --- /dev/null +++ b/examples/thermostat/infineon/cyw30739/src/SensorManager.cpp @@ -0,0 +1,84 @@ +/* + * + * 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. + */ + +/********************************************************** + * Includes + *********************************************************/ + +#include "SensorManager.h" +#include "AppTask.h" +#include "hdc2010.h" +#include "wiced_hal_gpio.h" +#include +#include + +#define HDC2010_ADDR 0x40 + +/* Calibration */ +#define TEMPERATURE_CALIBRATION 0xEA +#define HUMIDITY_CALIBRATION 0x0B + +/********************************************************** + * Defines and Constants + *********************************************************/ + +using namespace chip; +using namespace ::chip::DeviceLayer; + +/********************************************************** + * Variable declarations + *********************************************************/ + +SensorManager SensorManager::sSensorManager; +AsyncWorkFunct SensorManager::sAppInterruptHandler = nullptr; + +void SensorManager::Init(AsyncWorkFunct interruptHandler) +{ + wiced_hdc2010_address(HDC2010_ADDR); + + // Begin with a device reset + wiced_hdc2010_reset(); + + // Configure interrupt pin + wiced_hdc2010_enable_interrupt(); // Enable the Interrupt/DRDY pin + wiced_hdc2010_set_interrupt_polarity(WICED_HDC2010_ACTIVE_HIGH); // Set Interrupt pin to Active High + wiced_hdc2010_set_interrupt_mode(WICED_HDC2010_LEVEL_MODE); // Set Interrupt to return to inactive state when in bounds + wiced_hdc2010_enable_DRDY_interrupt(); + + // Configure Measurements + wiced_hdc2010_set_measurement_mode(WICED_HDC2010_TEMP_AND_HUMID); // Set measurements to temperature and humidity + wiced_hdc2010_set_rate(WICED_HDC2010_TEN_SECONDS); + wiced_hdc2010_set_temp_res(WICED_HDC2010_FOURTEEN_BIT); + wiced_hdc2010_set_humid_res(WICED_HDC2010_FOURTEEN_BIT); + wiced_hdc2010_temp_adjust(TEMPERATURE_CALIBRATION); + wiced_hdc2010_humidity_adjust(HUMIDITY_CALIBRATION); + + wiced_hal_gpio_register_pin_for_interrupt(PLATFORM_SENSOR_INT, InterruptHandler, NULL); + // begin measuring + wiced_hdc2010_trigger_measurement(); + + sAppInterruptHandler = interruptHandler; +} + +void SensorManager::InterruptHandler(void * data, uint8_t port_pin) +{ + if (sAppInterruptHandler != nullptr) + { + PlatformMgr().ScheduleWork(sAppInterruptHandler); + } +} diff --git a/examples/thermostat/infineon/cyw30739/src/TemperatureManager.cpp b/examples/thermostat/infineon/cyw30739/src/TemperatureManager.cpp new file mode 100644 index 00000000000000..57d0e02d3d777c --- /dev/null +++ b/examples/thermostat/infineon/cyw30739/src/TemperatureManager.cpp @@ -0,0 +1,154 @@ +/* + * + * 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. + */ + +/********************************************************** + * Includes + *********************************************************/ + +#include "TemperatureManager.h" +#include "AppTask.h" +#include "hdc2010.h" +#include "platform/CHIPDeviceLayer.h" + +/********************************************************** + * Defines and Constants + *********************************************************/ + +using namespace chip; +using namespace ::chip::DeviceLayer; + +constexpr EndpointId kThermostatEndpoint = 1; + +using namespace ::chip::app::Clusters::Thermostat; +namespace ThermAttr = chip::app::Clusters::Thermostat::Attributes; +/********************************************************** + * Variable declarations + *********************************************************/ + +TemperatureManager TemperatureManager::sTempMgr; + +CHIP_ERROR TemperatureManager::Init() +{ + app::DataModel::Nullable temp; + int16_t heatingSetpoint, coolingSetpoint; + + ThermAttr::LocalTemperature::Get(kThermostatEndpoint, temp); + ThermAttr::OccupiedCoolingSetpoint::Get(kThermostatEndpoint, &coolingSetpoint); + ThermAttr::OccupiedHeatingSetpoint::Get(kThermostatEndpoint, &heatingSetpoint); + ThermAttr::SystemMode::Get(kThermostatEndpoint, &mThermMode); + + mCurrentTempCelsius = 0; + mCurrentHumidity = 0; + mHeatingCelsiusSetPoint = ConvertToPrintableTemp(coolingSetpoint); + mCoolingCelsiusSetPoint = ConvertToPrintableTemp(heatingSetpoint); + + return CHIP_NO_ERROR; +} + +void TemperatureManager::SensorInterruptHandler() +{ + ThermAttr::LocalTemperature::Set(kThermostatEndpoint, wiced_hdc2010_read_temp() * 100); + + mCurrentHumidity = wiced_hdc2010_read_humidity(); +} + +int8_t TemperatureManager::ConvertToPrintableTemp(int16_t temperature) +{ + constexpr uint8_t kRoundUpValue = 50; + + // Round up the temperature as we won't print decimals on LCD + // Is it a negative temperature + if (temperature < 0) + { + temperature -= kRoundUpValue; + } + else + { + temperature += kRoundUpValue; + } + + return static_cast(temperature / 100); +} + +void TemperatureManager::AttributeChangeHandler(EndpointId endpointId, AttributeId attributeId, uint8_t * value, uint16_t size) +{ + switch (attributeId) + { + case ThermAttr::LocalTemperature::Id: { + int8_t Temp = ConvertToPrintableTemp(*((int16_t *) value)); + ChipLogDetail(Zcl, "Local temp %d", Temp); + mCurrentTempCelsius = Temp; + } + break; + + case ThermAttr::OccupiedCoolingSetpoint::Id: { + int8_t coolingTemp = ConvertToPrintableTemp(*((int16_t *) value)); + ChipLogDetail(Zcl, "CoolingSetpoint %d", coolingTemp); + mCoolingCelsiusSetPoint = coolingTemp; + } + break; + + case ThermAttr::OccupiedHeatingSetpoint::Id: { + int8_t heatingTemp = ConvertToPrintableTemp(*((int16_t *) value)); + ChipLogDetail(Zcl, "HeatingSetpoint %d", heatingTemp); + mHeatingCelsiusSetPoint = heatingTemp; + } + break; + + case ThermAttr::SystemMode::Id: { + ChipLogDetail(Zcl, "SystemMode %d", static_cast(*value)); + SystemModeEnum mode = static_cast(*value); + if (mThermMode != mode) + { + mThermMode = mode; + } + } + break; + + default: { + ChipLogDetail(Zcl, "Unhandled thermostat attribute %lx", attributeId); + return; + } + break; + } +} + +SystemModeEnum TemperatureManager::GetMode() +{ + return mThermMode; +} + +int16_t TemperatureManager::GetCurrentTemp() +{ + return mCurrentTempCelsius; +} + +uint8_t TemperatureManager::GetCurrentHumidity() +{ + return mCurrentHumidity; +} + +int8_t TemperatureManager::GetHeatingSetPoint() +{ + return mHeatingCelsiusSetPoint; +} + +int8_t TemperatureManager::GetCoolingSetPoint() +{ + return mCoolingCelsiusSetPoint; +} diff --git a/examples/thermostat/infineon/cyw30739/src/ThermostatUI.cpp b/examples/thermostat/infineon/cyw30739/src/ThermostatUI.cpp new file mode 100644 index 00000000000000..420b261641014c --- /dev/null +++ b/examples/thermostat/infineon/cyw30739/src/ThermostatUI.cpp @@ -0,0 +1,63 @@ +/* + * + * 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 "ThermostatUI.h" +#include "GUI.h" +#include + +static int8_t mCurrentTempCelsius; +static uint8_t mCurrentHumidity; + +void ThermostatUI::DrawUI() +{ + GUI_SetBkColor(GUI_BLACK); + GUI_Clear(); + DrawCurrentTemp(mCurrentTempCelsius); + DrawCurrentHumidity(mCurrentHumidity); +} + +void ThermostatUI::SetCurrentTemp(int8_t temp) +{ + mCurrentTempCelsius = temp; +} + +void ThermostatUI::SetCurrentHumidity(uint8_t humidity) +{ + mCurrentHumidity = humidity; +} + +void ThermostatUI::DrawCurrentTemp(int8_t temp) +{ + char buffer[8]; + sprintf(buffer, "%d", temp); + GUI_DrawCircle(31, 31, 31); + GUI_SetFont(&GUI_Font24B_1); + GUI_DispStringAt(buffer, 10, 22); + GUI_DispChar(176); // degree + GUI_DispChar('C'); +} + +void ThermostatUI::DrawCurrentHumidity(uint8_t humidity) +{ + char buffer[8]; + sprintf(buffer, "%d", humidity); + GUI_DrawCircle(96, 31, 31); + GUI_SetFont(&GUI_Font24B_1); + GUI_DispStringAt(buffer, 78, 22); + GUI_DispChar('%'); +} diff --git a/examples/thermostat/infineon/cyw30739/src/ZclCallbacks.cpp b/examples/thermostat/infineon/cyw30739/src/ZclCallbacks.cpp new file mode 100644 index 00000000000000..5965eadf631176 --- /dev/null +++ b/examples/thermostat/infineon/cyw30739/src/ZclCallbacks.cpp @@ -0,0 +1,49 @@ +/* + * + * 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 + * This file implements the handler for data model messages. + */ + +#include "TemperatureManager.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 == Identify::Id) + { + ChipLogProgress(Zcl, "Identify attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u", + ChipLogValueMEI(attributeId), type, *value, size); + } + else if (clusterId == Thermostat::Id) + { + TempMgr().AttributeChangeHandler(attributePath.mEndpointId, attributeId, value, size); + } +} diff --git a/examples/thermostat/infineon/cyw30739/third_party/connectedhomeip b/examples/thermostat/infineon/cyw30739/third_party/connectedhomeip new file mode 120000 index 00000000000000..59307833b4fee9 --- /dev/null +++ b/examples/thermostat/infineon/cyw30739/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../.. \ No newline at end of file diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index bf797220032b15..aff2fac037d52b 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -551,6 +551,7 @@ def BuildCyw30739Target(): TargetPart('light', app=Cyw30739App.LIGHT), TargetPart('light-switch', app=Cyw30739App.LIGHT_SWITCH), TargetPart('lock', app=Cyw30739App.LOCK), + TargetPart('thermostat', app=Cyw30739App.THERMOSTAT), ]) return target diff --git a/scripts/build/builders/cyw30739.py b/scripts/build/builders/cyw30739.py index 41bfecc10fd789..4c03edca3151ef 100644 --- a/scripts/build/builders/cyw30739.py +++ b/scripts/build/builders/cyw30739.py @@ -22,6 +22,7 @@ class Cyw30739App(Enum): LIGHT = auto() LIGHT_SWITCH = auto() LOCK = auto() + THERMOSTAT = auto() def ExampleName(self): if self == Cyw30739App.LIGHT: @@ -30,6 +31,8 @@ def ExampleName(self): return "light-switch-app" elif self == Cyw30739App.LOCK: return "lock-app" + elif self == Cyw30739App.THERMOSTAT: + return "thermostat" else: raise Exception("Unknown app type: %r" % self) diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index aff956fa31edc2..de45fdb9d8ba77 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -4,7 +4,7 @@ android-{arm,arm64,x86,x64,androidstudio-arm,androidstudio-arm64,androidstudio-x bouffalolab-{bl602-iot-matter-v1,bl602-night-light,xt-zb6-devkit,bl706-night-light,bl706dk,bl704ldk}-light[-shell][-115200][-rpc][-cdc][-resetcnt][-rotating_device_id][-mfd][-mfdtest][-ethernet][-wifi][-thread][-fp][-memmonitor][-mot] cc32xx-{lock,air-purifier} ti-cc13x4_26x4-{all-clusters,lighting,lock,pump,pump-controller}[-mtd][-ftd] -cyw30739-{cyw30739b2_p5_evk_01,cyw30739b2_p5_evk_02,cyw30739b2_p5_evk_03,cyw930739m2evb_01,cyw930739m2evb_02}-{light,light-switch,lock} +cyw30739-{cyw30739b2_p5_evk_01,cyw30739b2_p5_evk_02,cyw30739b2_p5_evk_03,cyw930739m2evb_01,cyw930739m2evb_02}-{light,light-switch,lock,thermostat} efr32-{brd4161a,brd4187c,brd4186c,brd4163a,brd4164a,brd4166a,brd4170a,brd4186a,brd4187a,brd4304a,brd4338a}-{window-covering,switch,unit-test,light,lock,thermostat,pump}[-rpc][-with-ota-requestor][-icd][-low-power][-shell][-no-logging][-openthread-mtd][-heap-monitoring][-no-openthread-cli][-show-qr-code][-wifi][-rs9116][-wf200][-siwx917][-ipv4][-additional-data-advertising][-use-ot-lib][-use-ot-coap-lib][-no-version][-skip-rps-generation] esp32-{m5stack,c3devkit,devkitc,qemu}-{all-clusters,all-clusters-minimal,energy-management,ota-provider,ota-requestor,shell,light,lock,bridge,temperature-measurement,ota-requestor,tests}[-rpc][-ipv6only][-tracing] genio-lighting-app