diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index aecc5372bcc41c..838e19e75a5c64 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -17,7 +17,7 @@ "build": { "dockerfile": "Dockerfile", "args": { - "BUILD_VERSION": "0.6.30" + "BUILD_VERSION": "0.6.35" } }, "remoteUser": "vscode", diff --git a/.github/workflows/bloat_check.yaml b/.github/workflows/bloat_check.yaml index 3da3bd42811efb..494a0f42ec2acf 100644 --- a/.github/workflows/bloat_check.yaml +++ b/.github/workflows/bloat_check.yaml @@ -33,7 +33,7 @@ jobs: runs-on: ubuntu-latest container: - image: connectedhomeip/chip-build:0.6.34 + image: connectedhomeip/chip-build:0.6.35 steps: - uses: Wandalen/wretry.action@v1.0.36 diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 66f2035df7f874..628abbbf5aba72 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.34 + image: connectedhomeip/chip-build:0.6.35 volumes: - "/tmp/log_output:/tmp/test_logs" options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 @@ -138,7 +138,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.34 + image: connectedhomeip/chip-build:0.6.35 volumes: - "/tmp/log_output:/tmp/test_logs" options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 @@ -298,7 +298,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.34 + image: connectedhomeip/chip-build:0.6.35 volumes: - "/tmp/log_output:/tmp/test_logs" options: --sysctl "net.ipv6.conf.all.disable_ipv6=0 @@ -471,7 +471,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.34 + image: connectedhomeip/chip-build:0.6.35 volumes: - "/tmp/log_output:/tmp/test_logs" options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 diff --git a/.github/workflows/chef.yaml b/.github/workflows/chef.yaml index 40a11908b4b072..e3f9709180380a 100644 --- a/.github/workflows/chef.yaml +++ b/.github/workflows/chef.yaml @@ -29,7 +29,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.34 + image: connectedhomeip/chip-build:0.6.35 options: --user root steps: @@ -57,7 +57,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-esp32:0.6.34 + image: connectedhomeip/chip-build-esp32:0.6.35 options: --user root steps: @@ -85,7 +85,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-nrf-platform:0.6.34 + image: connectedhomeip/chip-build-nrf-platform:0.6.35 options: --user root steps: diff --git a/.github/workflows/cirque.yaml b/.github/workflows/cirque.yaml index 5cc48487c6ae97..ec999e2170b7e8 100644 --- a/.github/workflows/cirque.yaml +++ b/.github/workflows/cirque.yaml @@ -29,7 +29,7 @@ jobs: timeout-minutes: 90 env: - DOCKER_RUN_VERSION: 0.6.34 + DOCKER_RUN_VERSION: 0.6.35 GITHUB_CACHE_PATH: /tmp/cirque-cache/ runs-on: ubuntu-latest @@ -38,7 +38,7 @@ jobs: # need to run with privilege, which isn't supported by job.XXX.contaner # https://github.com/actions/container-action/issues/2 # container: - # image: connectedhomeip/chip-build-cirque:0.6.34 + # image: connectedhomeip/chip-build-cirque:0.6.35 # volumes: # - "/tmp:/tmp" # - "/dev/pts:/dev/pts" diff --git a/.github/workflows/doxygen.yaml b/.github/workflows/doxygen.yaml index 9ac5d34d6f8504..53975923422d84 100644 --- a/.github/workflows/doxygen.yaml +++ b/.github/workflows/doxygen.yaml @@ -82,7 +82,7 @@ jobs: runs-on: ubuntu-20.04 container: - image: connectedhomeip/chip-build-doxygen:0.6.34 + image: connectedhomeip/chip-build-doxygen:0.6.35 if: github.actor != 'restyled-io[bot]' diff --git a/.github/workflows/examples-ameba.yaml b/.github/workflows/examples-ameba.yaml index 422c1819472cd7..23c52d94fe0bf6 100644 --- a/.github/workflows/examples-ameba.yaml +++ b/.github/workflows/examples-ameba.yaml @@ -35,7 +35,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-ameba:0.6.34 + image: connectedhomeip/chip-build-ameba:0.6.35 options: --user root steps: diff --git a/.github/workflows/examples-bouffalolab.yaml b/.github/workflows/examples-bouffalolab.yaml index 1453b4d4d4bf40..f18f9b933b310e 100644 --- a/.github/workflows/examples-bouffalolab.yaml +++ b/.github/workflows/examples-bouffalolab.yaml @@ -35,7 +35,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-bouffalolab:0.6.34 + image: connectedhomeip/chip-build-bouffalolab:0.6.35 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-cc13x2x7_26x2x7.yaml b/.github/workflows/examples-cc13x2x7_26x2x7.yaml index 91ccd55f848360..c95d076834e0c9 100644 --- a/.github/workflows/examples-cc13x2x7_26x2x7.yaml +++ b/.github/workflows/examples-cc13x2x7_26x2x7.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-ti:0.6.34 + image: connectedhomeip/chip-build-ti:0.6.35 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-efr32.yaml b/.github/workflows/examples-efr32.yaml index 105e75ad731f30..10344c5c099151 100644 --- a/.github/workflows/examples-efr32.yaml +++ b/.github/workflows/examples-efr32.yaml @@ -38,7 +38,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-efr32:0.6.34 + image: connectedhomeip/chip-build-efr32:0.6.35 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-esp32.yaml b/.github/workflows/examples-esp32.yaml index f621be81617cc6..d28ba2d1c4657e 100644 --- a/.github/workflows/examples-esp32.yaml +++ b/.github/workflows/examples-esp32.yaml @@ -34,7 +34,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-esp32:0.6.34 + image: connectedhomeip/chip-build-esp32:0.6.35 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" @@ -148,7 +148,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-esp32:0.6.34 + image: connectedhomeip/chip-build-esp32:0.6.35 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-infineon.yaml b/.github/workflows/examples-infineon.yaml index e0b745fdd27365..503312465b9d56 100644 --- a/.github/workflows/examples-infineon.yaml +++ b/.github/workflows/examples-infineon.yaml @@ -35,7 +35,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-infineon:0.6.34 + image: connectedhomeip/chip-build-infineon:0.6.35 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-k32w.yaml b/.github/workflows/examples-k32w.yaml index 03867d3afd39e8..43d72b2f26cef7 100644 --- a/.github/workflows/examples-k32w.yaml +++ b/.github/workflows/examples-k32w.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-k32w:0.6.34 + image: connectedhomeip/chip-build-k32w:0.6.35 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-linux-arm.yaml b/.github/workflows/examples-linux-arm.yaml index efe0e8191bc2fa..0d3c6af18258e7 100644 --- a/.github/workflows/examples-linux-arm.yaml +++ b/.github/workflows/examples-linux-arm.yaml @@ -34,7 +34,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-crosscompile:0.6.34 + image: connectedhomeip/chip-build-crosscompile:0.6.35 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-linux-imx.yaml b/.github/workflows/examples-linux-imx.yaml index 9bda08530bf2df..5fb3d8a17a35ff 100644 --- a/.github/workflows/examples-linux-imx.yaml +++ b/.github/workflows/examples-linux-imx.yaml @@ -34,7 +34,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-imx:0.6.34 + image: connectedhomeip/chip-build-imx:0.6.35 steps: - uses: Wandalen/wretry.action@v1.0.36 diff --git a/.github/workflows/examples-linux-standalone.yaml b/.github/workflows/examples-linux-standalone.yaml index 2e7016880da510..9cb447501b9c18 100644 --- a/.github/workflows/examples-linux-standalone.yaml +++ b/.github/workflows/examples-linux-standalone.yaml @@ -34,7 +34,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.34 + image: connectedhomeip/chip-build:0.6.35 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-mbed.yaml b/.github/workflows/examples-mbed.yaml index a5b6c2e299b9b1..6f24da71558367 100644 --- a/.github/workflows/examples-mbed.yaml +++ b/.github/workflows/examples-mbed.yaml @@ -40,7 +40,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-mbed-os:0.6.34 + image: connectedhomeip/chip-build-mbed-os:0.6.35 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-mw320.yaml b/.github/workflows/examples-mw320.yaml index 0d646e0442a7be..69f6e23ae06b85 100755 --- a/.github/workflows/examples-mw320.yaml +++ b/.github/workflows/examples-mw320.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.34 + image: connectedhomeip/chip-build:0.6.35 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-nrfconnect.yaml b/.github/workflows/examples-nrfconnect.yaml index a88c4ac01702a3..1d84e4629db0b8 100644 --- a/.github/workflows/examples-nrfconnect.yaml +++ b/.github/workflows/examples-nrfconnect.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-nrf-platform:0.6.34 + image: connectedhomeip/chip-build-nrf-platform:0.6.35 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-openiotsdk.yaml b/.github/workflows/examples-openiotsdk.yaml index c3fb39cf441bf8..975ebce2e9510b 100644 --- a/.github/workflows/examples-openiotsdk.yaml +++ b/.github/workflows/examples-openiotsdk.yaml @@ -35,7 +35,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-openiotsdk:0.6.34 + image: connectedhomeip/chip-build-openiotsdk:0.6.35 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" options: --privileged diff --git a/.github/workflows/examples-qpg.yaml b/.github/workflows/examples-qpg.yaml index 2e45bc73131d01..67f4db03565fbc 100644 --- a/.github/workflows/examples-qpg.yaml +++ b/.github/workflows/examples-qpg.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.34 + image: connectedhomeip/chip-build:0.6.35 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-telink.yaml b/.github/workflows/examples-telink.yaml index 6aca1ff4caddf4..4e025b0917f900 100644 --- a/.github/workflows/examples-telink.yaml +++ b/.github/workflows/examples-telink.yaml @@ -35,7 +35,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-telink:0.6.34 + image: connectedhomeip/chip-build-telink:0.6.35 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-tizen.yaml b/.github/workflows/examples-tizen.yaml index fab5e7ddc07e5b..a4ed8444b01c90 100644 --- a/.github/workflows/examples-tizen.yaml +++ b/.github/workflows/examples-tizen.yaml @@ -33,7 +33,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-tizen:0.6.34 + image: connectedhomeip/chip-build-tizen:0.6.35 options: --user root volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/full-android.yaml b/.github/workflows/full-android.yaml index ff7c0c6983ddd2..d8a5a13396c386 100644 --- a/.github/workflows/full-android.yaml +++ b/.github/workflows/full-android.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-android:0.6.34 + image: connectedhomeip/chip-build-android:0.6.35 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/fuzzing-build.yaml b/.github/workflows/fuzzing-build.yaml index c947ff5807a581..0ffb8d982d13dd 100644 --- a/.github/workflows/fuzzing-build.yaml +++ b/.github/workflows/fuzzing-build.yaml @@ -34,7 +34,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.34 + image: connectedhomeip/chip-build:0.6.35 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 85e1110431a181..dc6ceed574b3a4 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -28,7 +28,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.34 + image: connectedhomeip/chip-build:0.6.35 steps: - uses: Wandalen/wretry.action@v1.0.36 diff --git a/.github/workflows/qemu.yaml b/.github/workflows/qemu.yaml index 66c3b6a576088e..293ee31f955c64 100644 --- a/.github/workflows/qemu.yaml +++ b/.github/workflows/qemu.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-esp32-qemu:0.6.34 + image: connectedhomeip/chip-build-esp32-qemu:0.6.35 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/release_artifacts.yaml b/.github/workflows/release_artifacts.yaml index f53931717c01ea..1b773d8c28d52c 100644 --- a/.github/workflows/release_artifacts.yaml +++ b/.github/workflows/release_artifacts.yaml @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-latest container: - image: connectedhomeip/chip-build-esp32:0.6.34 + image: connectedhomeip/chip-build-esp32:0.6.35 steps: - uses: Wandalen/wretry.action@v1.0.36 @@ -75,7 +75,7 @@ jobs: runs-on: ubuntu-latest container: - image: connectedhomeip/chip-build-efr32:0.6.34 + image: connectedhomeip/chip-build-efr32:0.6.35 steps: - uses: Wandalen/wretry.action@v1.0.36 name: Checkout diff --git a/.github/workflows/smoketest-android.yaml b/.github/workflows/smoketest-android.yaml index 44f1defff5cf11..1007d93e99f7ea 100644 --- a/.github/workflows/smoketest-android.yaml +++ b/.github/workflows/smoketest-android.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build-android:0.6.34 + image: connectedhomeip/chip-build-android:0.6.35 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index b6b698bb2da748..b90dfef7713a58 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -47,7 +47,7 @@ jobs: runs-on: ubuntu-latest container: - image: connectedhomeip/chip-build:0.6.34 + image: connectedhomeip/chip-build:0.6.35 options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" @@ -383,7 +383,7 @@ jobs: runs-on: ubuntu-latest container: - image: connectedhomeip/chip-build:0.6.34 + image: connectedhomeip/chip-build:0.6.35 options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=0 net.ipv6.conf.all.forwarding=0" @@ -458,7 +458,7 @@ jobs: runs-on: ubuntu-latest container: - image: connectedhomeip/chip-build:0.6.34 + image: connectedhomeip/chip-build:0.6.35 options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=0 net.ipv6.conf.all.forwarding=0" diff --git a/.github/workflows/unit_integration_test.yaml b/.github/workflows/unit_integration_test.yaml index c339a84510921c..d01552761f847e 100644 --- a/.github/workflows/unit_integration_test.yaml +++ b/.github/workflows/unit_integration_test.yaml @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest container: - image: connectedhomeip/chip-build:0.6.34 + image: connectedhomeip/chip-build:0.6.35 volumes: - "/tmp/log_output:/tmp/test_logs" options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" diff --git a/.github/workflows/zap_regeneration.yaml b/.github/workflows/zap_regeneration.yaml index 740dc62b49d0a8..35a48203405047 100644 --- a/.github/workflows/zap_regeneration.yaml +++ b/.github/workflows/zap_regeneration.yaml @@ -28,7 +28,7 @@ jobs: runs-on: ubuntu-20.04 container: - image: connectedhomeip/chip-build:0.6.34 + image: connectedhomeip/chip-build:0.6.35 defaults: run: shell: sh diff --git a/.github/workflows/zap_templates.yaml b/.github/workflows/zap_templates.yaml index dadb560e0a29fd..7a49bde308a9ad 100644 --- a/.github/workflows/zap_templates.yaml +++ b/.github/workflows/zap_templates.yaml @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-20.04 container: - image: connectedhomeip/chip-build:0.6.34 + image: connectedhomeip/chip-build:0.6.35 defaults: run: shell: sh diff --git a/examples/all-clusters-app/telink/CMakeLists.txt b/examples/all-clusters-app/telink/CMakeLists.txt index 9b981dfc1766f9..afe18d1cb7c95d 100644 --- a/examples/all-clusters-app/telink/CMakeLists.txt +++ b/examples/all-clusters-app/telink/CMakeLists.txt @@ -55,7 +55,8 @@ target_sources(app PRIVATE ${ALL_CLUSTERS_COMMON_DIR}/src/binding-handler.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp - ${TELINK_COMMON}/util/src/ThreadUtil.cpp) + ${TELINK_COMMON}/util/src/ThreadUtil.cpp + ${TELINK_COMMON}/util/src/PWMDevice.cpp) chip_configure_data_model(app INCLUDE_SERVER diff --git a/examples/all-clusters-app/telink/Readme.md b/examples/all-clusters-app/telink/Readme.md index f436507f9684b6..719656cbcb8484 100644 --- a/examples/all-clusters-app/telink/Readme.md +++ b/examples/all-clusters-app/telink/Readme.md @@ -66,14 +66,31 @@ The following buttons are available on **tlsr9518adk80d** board: ### LEDs -**Red** LED indicates current state of Thread network. It ables to be in +#### Indicate current state of Thread network + +**Red** LED indicates current state of Thread network. It is able 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 | +| Blinks with frequent pulses | Device is commissioned, Thread enabled. Device trying to JOIN thread network | +| Blinks with wide pulses | Device commissioned and joined to thread network as CHILD | + +#### Indicate identify of device + +**Green** LED used to identify the device. The LED starts blinking when the +Identify command of the Identify cluster is received. The command's argument can +be used to specify the the effect. It is able to be in following effects: + +| Effect | Description | +| :------------------------------ | :------------------------------------------------------------------- | +| Blinks (200 ms on/200 ms off) | Blink (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK) | +| Breathe (during 1000 ms) | Breathe (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE) | +| Blinks (50 ms on/950 ms off) | Okay (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY) | +| Blinks (1000 ms on/1000 ms off) | Channel Change (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE) | +| Blinks (950 ms on/50 ms off) | Finish (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT) | +| LED off | Stop (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT) | ### CHIP tool commands diff --git a/examples/all-clusters-app/telink/include/AppConfig.h b/examples/all-clusters-app/telink/include/AppConfig.h index 27d2cc072c03fc..8eb990230520e6 100644 --- a/examples/all-clusters-app/telink/include/AppConfig.h +++ b/examples/all-clusters-app/telink/include/AppConfig.h @@ -29,6 +29,6 @@ #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 +#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) +#define SYSTEM_STATE_LED 7 +#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) diff --git a/examples/all-clusters-app/telink/include/AppEvent.h b/examples/all-clusters-app/telink/include/AppEvent.h index 54250995e06ca8..b6e45d7d1526c8 100644 --- a/examples/all-clusters-app/telink/include/AppEvent.h +++ b/examples/all-clusters-app/telink/include/AppEvent.h @@ -32,6 +32,8 @@ struct AppEvent kEventType_Button = 0, kEventType_Timer, kEventType_UpdateLedState, + kEventType_IdentifyStart, + kEventType_IdentifyStop, }; uint16_t Type; diff --git a/examples/all-clusters-app/telink/include/AppTask.h b/examples/all-clusters-app/telink/include/AppTask.h index 7787968458b867..69e5d61669752b 100644 --- a/examples/all-clusters-app/telink/include/AppTask.h +++ b/examples/all-clusters-app/telink/include/AppTask.h @@ -20,6 +20,7 @@ #include "AppEvent.h" #include "LEDWidget.h" +#include "PWMDevice.h" #include @@ -28,22 +29,25 @@ #include struct k_timer; +struct Identify; class AppTask { public: - CHIP_ERROR StartApp(); + CHIP_ERROR StartApp(void); void PostEvent(AppEvent * event); + static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); private: friend AppTask & GetAppTask(void); + CHIP_ERROR Init(void); - CHIP_ERROR Init(); + static void ActionIdentifyStateUpdateHandler(k_timer * timer); void DispatchEvent(AppEvent * event); - static void UpdateStatusLED(); + static void UpdateStatusLED(void); static void LEDStateUpdateHandler(LEDWidget * ledWidget); static void FactoryResetButtonEventHandler(void); static void StartThreadButtonEventHandler(void); @@ -58,12 +62,14 @@ class AppTask static void StartThreadHandler(AppEvent * aEvent); static void StartBleAdvHandler(AppEvent * aEvent); static void UpdateLedStateEventHandler(AppEvent * aEvent); + static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); static void InitButtons(void); static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); static AppTask sAppTask; + PWMDevice mPwmIdentifyLed; }; inline AppTask & GetAppTask(void) diff --git a/examples/all-clusters-app/telink/prj.conf b/examples/all-clusters-app/telink/prj.conf index 6c7821f2c87ec7..be2598cb6ade52 100644 --- a/examples/all-clusters-app/telink/prj.conf +++ b/examples/all-clusters-app/telink/prj.conf @@ -21,6 +21,9 @@ # enable GPIO CONFIG_GPIO=y +# enable PWM +CONFIG_PWM=y + # OpenThread configs CONFIG_OPENTHREAD_MTD=y CONFIG_OPENTHREAD_FTD=n diff --git a/examples/all-clusters-app/telink/src/AppTask.cpp b/examples/all-clusters-app/telink/src/AppTask.cpp index bc05a343618354..ff8cb6f7af4569 100644 --- a/examples/all-clusters-app/telink/src/AppTask.cpp +++ b/examples/all-clusters-app/telink/src/AppTask.cpp @@ -63,11 +63,28 @@ SHELL_CMD_REGISTER(telink, &sub_telink, "Telink commands", NULL); LOG_MODULE_DECLARE(app); +using namespace ::chip; +using namespace ::chip::app; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; + namespace { -constexpr int kFactoryResetTriggerTimeout = 2000; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; +constexpr int kFactoryResetTriggerTimeout = 2000; +constexpr int kAppEventQueueSize = 10; +constexpr uint8_t kButtonPushEvent = 1; +constexpr uint8_t kButtonReleaseEvent = 0; +constexpr EndpointId kEndpointId = 1; +constexpr uint8_t kDefaultMinLevel = 0; +constexpr uint8_t kDefaultMaxLevel = 254; +constexpr uint32_t kIdentifyBlinkRateMs = 200; +constexpr uint32_t kIdentifyOkayOnRateMs = 50; +constexpr uint32_t kIdentifyOkayOffRateMs = 950; +constexpr uint32_t kIdentifyFinishOnRateMs = 950; +constexpr uint32_t kIdentifyFinishOffRateMs = 50; +constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; +constexpr uint32_t kIdentifyBreatheRateMs = 1000; + +const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); k_timer sFactoryResetTimer; @@ -88,29 +105,11 @@ 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; + AppTask::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); } Identify sIdentify = { - chip::EndpointId{ 1 }, + kEndpointId, [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, @@ -119,11 +118,6 @@ Identify sIdentify = { } // namespace -using namespace ::chip; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; -using namespace ::chip::DeviceLayer::Internal; - AppTask AppTask::sAppTask; class AppFabricTableDelegate : public FabricTable::Delegate @@ -139,16 +133,14 @@ class AppFabricTableDelegate : public FabricTable::Delegate constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE; -CHIP_ERROR AppTask::Init() +CHIP_ERROR AppTask::Init(void) { - CHIP_ERROR ret; - LOG_INF("SW 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); + LEDWidget::InitGpio(LEDS_PORT); LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - sStatusLED.Init(SYSTEM_STATE_LED_PIN); + sStatusLED.Init(SYSTEM_STATE_LED); UpdateStatusLED(); @@ -163,6 +155,16 @@ CHIP_ERROR AppTask::Init() (void) initParams.InitializeStaticResourcesBeforeServerInit(); chip::Server::GetInstance().Init(initParams); + // Initialize PWM Identify led + CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("Green IDENTIFY PWM Device Init fail"); + return err; + } + + sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); + // Initialize device attestation config SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -181,11 +183,11 @@ CHIP_ERROR AppTask::Init() ConfigurationMgr().LogDeviceConfig(); // Configure Bindings - ret = InitBindingHandlers(); - if (ret != CHIP_NO_ERROR) + err = InitBindingHandlers(); + if (err != CHIP_NO_ERROR) { LOG_ERR("InitBindingHandlers fail"); - return ret; + return err; } PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); @@ -195,24 +197,24 @@ CHIP_ERROR AppTask::Init() // between the main and the CHIP threads. PlatformMgr().AddEventHandler(ChipEventHandler, 0); - ret = ConnectivityMgr().SetBLEDeviceName("TelinkApp"); - if (ret != CHIP_NO_ERROR) + err = ConnectivityMgr().SetBLEDeviceName("TelinkApp"); + if (err != CHIP_NO_ERROR) { LOG_ERR("SetBLEDeviceName fail"); - return ret; + return err; } - ret = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); - if (ret != CHIP_NO_ERROR) + err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); + if (err != CHIP_NO_ERROR) { LOG_ERR("AppFabricTableDelegate fail"); - return ret; + return err; } return CHIP_NO_ERROR; } -CHIP_ERROR AppTask::StartApp() +CHIP_ERROR AppTask::StartApp(void) { CHIP_ERROR err = Init(); @@ -236,6 +238,56 @@ CHIP_ERROR AppTask::StartApp() } } +void AppTask::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) +{ + AppEvent event; + event.Type = AppEvent::kEventType_IdentifyStart; + + switch (aEffect) + { + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); + event.Handler = [](AppEvent *) { sAppTask.mPwmIdentifyLed.StopAction(); }; + event.Type = AppEvent::kEventType_IdentifyStop; + break; + default: + ChipLogProgress(Zcl, "No identifier effect"); + return; + } + + sAppTask.PostEvent(&event); +} + void AppTask::FactoryResetButtonEventHandler(void) { AppEvent event; @@ -276,7 +328,7 @@ void AppTask::StartThreadHandler(AppEvent * aEvent) if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned()) { // Switch context from BLE to Thread - BLEManagerImpl sInstance; + Internal::BLEManagerImpl sInstance; sInstance.SwitchToIeee802154(); StartDefaultThreadNetwork(); } @@ -336,7 +388,7 @@ void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) sAppTask.PostEvent(&event); } -void AppTask::UpdateStatusLED() +void AppTask::UpdateStatusLED(void) { if (sIsThreadProvisioned && sIsThreadEnabled) { @@ -382,10 +434,21 @@ void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */ } } +void AppTask::ActionIdentifyStateUpdateHandler(k_timer * timer) +{ + AppEvent event; + event.Type = AppEvent::kEventType_UpdateLedState; + event.Handler = UpdateIdentifyStateEventHandler; + sAppTask.PostEvent(&event); +} + +void AppTask::UpdateIdentifyStateEventHandler(AppEvent * aEvent) +{ + sAppTask.mPwmIdentifyLed.UpdateAction(); +} + void AppTask::PostEvent(AppEvent * aEvent) { - if (!aEvent) - return; if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) { LOG_INF("PostEvent fail"); @@ -394,8 +457,6 @@ void AppTask::PostEvent(AppEvent * aEvent) void AppTask::DispatchEvent(AppEvent * aEvent) { - if (!aEvent) - return; if (aEvent->Handler) { aEvent->Handler(aEvent); diff --git a/examples/contact-sensor-app/telink/CMakeLists.txt b/examples/contact-sensor-app/telink/CMakeLists.txt index a2ddd3d332163f..144d1eaab34f88 100755 --- a/examples/contact-sensor-app/telink/CMakeLists.txt +++ b/examples/contact-sensor-app/telink/CMakeLists.txt @@ -51,7 +51,8 @@ target_sources(app PRIVATE src/ZclCallbacks.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp - ${TELINK_COMMON}/util/src/ThreadUtil.cpp) + ${TELINK_COMMON}/util/src/ThreadUtil.cpp + ${TELINK_COMMON}/util/src/PWMDevice.cpp) chip_configure_data_model(app INCLUDE_SERVER diff --git a/examples/contact-sensor-app/telink/README.md b/examples/contact-sensor-app/telink/README.md index 31b004dd7aaa5b..a41fadcc3bacb8 100755 --- a/examples/contact-sensor-app/telink/README.md +++ b/examples/contact-sensor-app/telink/README.md @@ -64,14 +64,33 @@ The following buttons are available on **tlsr9518adk80d** board: ### LEDs -**Red** LED indicates current state of Thread network. It ables to be in +#### Indicate current state of Thread network + +**Red** LED indicates current state of Thread network. It is able 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 | +| Blinks with frequent pulses | Device is commissioned, Thread enabled. Device trying to JOIN thread network | +| Blinks with wide pulses | Device commissioned and joined to thread network as CHILD | + +#### Indicate identify of device + +**Green** LED used to identify the device. The LED starts blinking when the +Identify command of the Identify cluster is received. The command's argument can +be used to specify the the effect. It is able to be in following effects: + +| Effect | Description | +| :------------------------------ | :------------------------------------------------------------------- | +| Blinks (200 ms on/200 ms off) | Blink (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK) | +| Breathe (during 1000 ms) | Breathe (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE) | +| Blinks (50 ms on/950 ms off) | Okay (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY) | +| Blinks (1000 ms on/1000 ms off) | Channel Change (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE) | +| Blinks (950 ms on/50 ms off) | Finish (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT) | +| LED off | Stop (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT) | + +#### Indicate current state of Contact Sensor **Blue** LED shows current state of Contact Sensor diff --git a/examples/contact-sensor-app/telink/include/AppConfig.h b/examples/contact-sensor-app/telink/include/AppConfig.h index 01128b76e4d929..4e4f556036bcfa 100755 --- a/examples/contact-sensor-app/telink/include/AppConfig.h +++ b/examples/contact-sensor-app/telink/include/AppConfig.h @@ -29,9 +29,7 @@ #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 - -// Contact state led -#define CONTACT_STATE_LED_PIN 4 +#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) +#define SYSTEM_STATE_LED 7 +#define CONTACT_STATE_LED 4 +#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) diff --git a/examples/contact-sensor-app/telink/include/AppEvent.h b/examples/contact-sensor-app/telink/include/AppEvent.h index 4051ba31cbb465..5306a8076d0804 100755 --- a/examples/contact-sensor-app/telink/include/AppEvent.h +++ b/examples/contact-sensor-app/telink/include/AppEvent.h @@ -32,6 +32,8 @@ struct AppEvent kEventType_Button = 0, kEventType_Timer, kEventType_UpdateLedState, + kEventType_IdentifyStart, + kEventType_IdentifyStop, kEventType_Contact, }; diff --git a/examples/contact-sensor-app/telink/include/AppTask.h b/examples/contact-sensor-app/telink/include/AppTask.h index ad6f98c7c2cf66..0cf75d63696004 100644 --- a/examples/contact-sensor-app/telink/include/AppTask.h +++ b/examples/contact-sensor-app/telink/include/AppTask.h @@ -21,6 +21,7 @@ #include "AppEvent.h" #include "ContactSensorManager.h" #include "LEDWidget.h" +#include "PWMDevice.h" #include @@ -36,14 +37,17 @@ #define APP_ERROR_UNHANDLED_EVENT CHIP_APPLICATION_ERROR(0x03) struct k_timer; +struct Identify; class AppTask { public: CHIP_ERROR StartApp(void); - void PostContactActionRequest(ContactSensorManager::Action aAction); void PostEvent(AppEvent * event); + static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); + + void PostContactActionRequest(ContactSensorManager::Action aAction); void UpdateClusterState(void); void UpdateDeviceState(void); @@ -54,6 +58,8 @@ class AppTask friend AppTask & GetAppTask(void); CHIP_ERROR Init(void); + static void ActionIdentifyStateUpdateHandler(k_timer * timer); + void DispatchEvent(AppEvent * event); static void OnStateChanged(ContactSensorManager::State aState); @@ -76,6 +82,7 @@ class AppTask static void StartBleAdvHandler(AppEvent * aEvent); static void ContactActionEventHandler(AppEvent * aEvent); static void UpdateLedStateEventHandler(AppEvent * aEvent); + static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); static void InitButtons(void); @@ -84,6 +91,7 @@ class AppTask bool mSyncClusterToButtonAction = false; static AppTask sAppTask; + PWMDevice mPwmIdentifyLed; #if CONFIG_CHIP_FACTORY_DATA // chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; diff --git a/examples/contact-sensor-app/telink/prj.conf b/examples/contact-sensor-app/telink/prj.conf index 6c4ad9d8975f05..3c582145b38a29 100755 --- a/examples/contact-sensor-app/telink/prj.conf +++ b/examples/contact-sensor-app/telink/prj.conf @@ -21,6 +21,9 @@ # enable GPIO CONFIG_GPIO=y +# enable PWM +CONFIG_PWM=y + # OpenThread configs CONFIG_OPENTHREAD_MTD=y CONFIG_OPENTHREAD_FTD=n diff --git a/examples/contact-sensor-app/telink/src/AppTask.cpp b/examples/contact-sensor-app/telink/src/AppTask.cpp index 598bed97832585..86f4ec96c3459d 100644 --- a/examples/contact-sensor-app/telink/src/AppTask.cpp +++ b/examples/contact-sensor-app/telink/src/AppTask.cpp @@ -50,16 +50,28 @@ using namespace ::chip::Credentials; using namespace ::chip::DeviceLayer; namespace { +constexpr int kFactoryResetTriggerTimeout = 2000; +constexpr int kAppEventQueueSize = 10; +constexpr uint8_t kButtonPushEvent = 1; +constexpr uint8_t kButtonReleaseEvent = 0; +constexpr EndpointId kEndpointId = 1; +constexpr uint8_t kDefaultMinLevel = 0; +constexpr uint8_t kDefaultMaxLevel = 254; +constexpr uint32_t kIdentifyBlinkRateMs = 200; +constexpr uint32_t kIdentifyOkayOnRateMs = 50; +constexpr uint32_t kIdentifyOkayOffRateMs = 950; +constexpr uint32_t kIdentifyFinishOnRateMs = 950; +constexpr uint32_t kIdentifyFinishOffRateMs = 50; +constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; +constexpr uint32_t kIdentifyBreatheRateMs = 1000; + +const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; -constexpr int kFactoryResetTriggerTimeout = 2000; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; - +#if CONFIG_CHIP_FACTORY_DATA // NOTE! This key is for test/certification only and should not be available in production devices! -// If CONFIG_CHIP_FACTORY_DATA is enabled, this value is read from the factory data. uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; +#endif K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); k_timer sFactoryResetTimer; @@ -81,29 +93,11 @@ 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; + AppTask::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); } Identify sIdentify = { - chip::EndpointId{ 1 }, + kEndpointId, [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, @@ -125,20 +119,18 @@ class AppFabricTableDelegate : public FabricTable::Delegate } }; -CHIP_ERROR AppTask::Init() +CHIP_ERROR AppTask::Init(void) { - CHIP_ERROR err; - LOG_INF("SW 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); + LEDWidget::InitGpio(LEDS_PORT); LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - sStatusLED.Init(SYSTEM_STATE_LED_PIN); + sStatusLED.Init(SYSTEM_STATE_LED); UpdateStatusLED(); - sContactSensorLED.Init(CONTACT_STATE_LED_PIN); + sContactSensorLED.Init(CONTACT_STATE_LED); sContactSensorLED.Set(ContactSensorMgr().IsContactClosed()); UpdateDeviceState(); @@ -149,6 +141,16 @@ CHIP_ERROR AppTask::Init() k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); k_timer_user_data_set(&sFactoryResetTimer, this); + // Initialize PWM Identify led + CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("Green IDENTIFY PWM Device Init fail"); + return err; + } + + sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); + // Initialize CHIP server #if CONFIG_CHIP_FACTORY_DATA ReturnErrorOnFailure(mFactoryDataProvider.Init()); @@ -253,6 +255,56 @@ CHIP_ERROR AppTask::StartApp(void) } } +void AppTask::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) +{ + AppEvent event; + event.Type = AppEvent::kEventType_IdentifyStart; + + switch (aEffect) + { + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); + event.Handler = [](AppEvent *) { sAppTask.mPwmIdentifyLed.StopAction(); }; + event.Type = AppEvent::kEventType_IdentifyStop; + break; + default: + ChipLogProgress(Zcl, "No identifier effect"); + return; + } + + sAppTask.PostEvent(&event); +} + void AppTask::PostContactActionRequest(ContactSensorManager::Action aAction) { AppEvent event; @@ -445,6 +497,19 @@ void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */ } } +void AppTask::ActionIdentifyStateUpdateHandler(k_timer * timer) +{ + AppEvent event; + event.Type = AppEvent::kEventType_UpdateLedState; + event.Handler = UpdateIdentifyStateEventHandler; + sAppTask.PostEvent(&event); +} + +void AppTask::UpdateIdentifyStateEventHandler(AppEvent * aEvent) +{ + sAppTask.mPwmIdentifyLed.UpdateAction(); +} + void AppTask::PostEvent(AppEvent * aEvent) { if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) diff --git a/examples/light-switch-app/telink/CMakeLists.txt b/examples/light-switch-app/telink/CMakeLists.txt index 3f67e533375932..af48b2eb688c3e 100755 --- a/examples/light-switch-app/telink/CMakeLists.txt +++ b/examples/light-switch-app/telink/CMakeLists.txt @@ -52,7 +52,8 @@ target_sources(app PRIVATE src/binding-handler.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp - ${TELINK_COMMON}/util/src/ThreadUtil.cpp) + ${TELINK_COMMON}/util/src/ThreadUtil.cpp + ${TELINK_COMMON}/util/src/PWMDevice.cpp) chip_configure_data_model(app INCLUDE_SERVER diff --git a/examples/light-switch-app/telink/README.md b/examples/light-switch-app/telink/README.md index 2c5aa4a940f687..a150047a5ec4d0 100755 --- a/examples/light-switch-app/telink/README.md +++ b/examples/light-switch-app/telink/README.md @@ -69,14 +69,31 @@ The following buttons are available on **tlsr9518adk80d** board: ### LEDs -**Red** LED indicates current state of Thread network. It ables to be in +#### Indicate current state of Thread network + +**Red** LED indicates current state of Thread network. It is able 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 | +| Blinks with frequent pulses | Device is commissioned, Thread enabled. Device trying to JOIN thread network | +| Blinks with wide pulses | Device commissioned and joined to thread network as CHILD | + +#### Indicate identify of device + +**Green** LED used to identify the device. The LED starts blinking when the +Identify command of the Identify cluster is received. The command's argument can +be used to specify the the effect. It is able to be in following effects: + +| Effect | Description | +| :------------------------------ | :------------------------------------------------------------------- | +| Blinks (200 ms on/200 ms off) | Blink (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK) | +| Breathe (during 1000 ms) | Breathe (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE) | +| Blinks (50 ms on/950 ms off) | Okay (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY) | +| Blinks (1000 ms on/1000 ms off) | Channel Change (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE) | +| Blinks (950 ms on/50 ms off) | Finish (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT) | +| LED off | Stop (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT) | ### CHIP tool commands diff --git a/examples/light-switch-app/telink/include/AppConfig.h b/examples/light-switch-app/telink/include/AppConfig.h index 6155133e1d0278..688d848ea520ae 100755 --- a/examples/light-switch-app/telink/include/AppConfig.h +++ b/examples/light-switch-app/telink/include/AppConfig.h @@ -29,10 +29,6 @@ #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 - -// Lighting LED config -#define LIGHTING_PWM_DEVICE DEVICE_DT_GET(DT_PWMS_CTLR(DT_ALIAS(pwm_led0))) -#define LIGHTING_PWM_CHANNEL DT_PWMS_CHANNEL(DT_ALIAS(pwm_led0)) +#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) +#define SYSTEM_STATE_LED 7 +#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) diff --git a/examples/light-switch-app/telink/include/AppEvent.h b/examples/light-switch-app/telink/include/AppEvent.h index 9a6fd3060c1685..72554b4bb54b5a 100755 --- a/examples/light-switch-app/telink/include/AppEvent.h +++ b/examples/light-switch-app/telink/include/AppEvent.h @@ -32,6 +32,8 @@ struct AppEvent kEventType_Button = 0, kEventType_Timer, kEventType_UpdateLedState, + kEventType_IdentifyStart, + kEventType_IdentifyStop, kEventType_Lighting, kEventType_Install, }; diff --git a/examples/light-switch-app/telink/include/AppTask.h b/examples/light-switch-app/telink/include/AppTask.h old mode 100755 new mode 100644 index 6509613e3741b8..8226505fcc2ccc --- a/examples/light-switch-app/telink/include/AppTask.h +++ b/examples/light-switch-app/telink/include/AppTask.h @@ -20,6 +20,7 @@ #include "AppEvent.h" #include "LEDWidget.h" +#include "PWMDevice.h" #include @@ -32,6 +33,7 @@ #include struct k_timer; +struct Identify; class AppTask { @@ -50,13 +52,16 @@ class AppTask void PostLightingActionRequest(Action_t aAction); void PostEvent(AppEvent * event); void UpdateClusterState(); + static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); private: friend AppTask & GetAppTask(void); - CHIP_ERROR Init(); + + CHIP_ERROR Init(void); static void ActionInitiated(AppTask::Action_t aAction, int32_t aActor); static void ActionCompleted(AppTask::Action_t aAction, int32_t aActor); + static void ActionIdentifyStateUpdateHandler(k_timer * timer); void DispatchEvent(AppEvent * event); @@ -77,12 +82,14 @@ class AppTask static void SwitchActionEventHandler(AppEvent * aEvent); static void StartBleAdvHandler(AppEvent * aEvent); static void UpdateLedStateEventHandler(AppEvent * aEvent); + static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); static void InitButtons(void); static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); static AppTask sAppTask; + PWMDevice mPwmIdentifyLed; #if CONFIG_CHIP_FACTORY_DATA // chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; diff --git a/examples/light-switch-app/telink/src/AppTask.cpp b/examples/light-switch-app/telink/src/AppTask.cpp index 0c8013067fc9d7..2bdc1f6125cc2c 100644 --- a/examples/light-switch-app/telink/src/AppTask.cpp +++ b/examples/light-switch-app/telink/src/AppTask.cpp @@ -71,15 +71,28 @@ using namespace ::chip::Credentials; using namespace ::chip::DeviceLayer; namespace { -constexpr int kFactoryResetTriggerTimeout = 2000; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; +constexpr int kFactoryResetTriggerTimeout = 2000; +constexpr int kAppEventQueueSize = 10; +constexpr uint8_t kButtonPushEvent = 1; +constexpr uint8_t kButtonReleaseEvent = 0; +constexpr EndpointId kEndpointId = 1; +constexpr uint8_t kDefaultMinLevel = 0; +constexpr uint8_t kDefaultMaxLevel = 254; +constexpr uint32_t kIdentifyBlinkRateMs = 200; +constexpr uint32_t kIdentifyOkayOnRateMs = 50; +constexpr uint32_t kIdentifyOkayOffRateMs = 950; +constexpr uint32_t kIdentifyFinishOnRateMs = 950; +constexpr uint32_t kIdentifyFinishOffRateMs = 50; +constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; +constexpr uint32_t kIdentifyBreatheRateMs = 1000; + +const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; +#if CONFIG_CHIP_FACTORY_DATA // NOTE! This key is for test/certification only and should not be available in production devices! -// If CONFIG_CHIP_FACTORY_DATA is enabled, this value is read from the factory data. uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; +#endif K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); k_timer sFactoryResetTimer; @@ -101,29 +114,11 @@ 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; + AppTask::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); } Identify sIdentify = { - chip::EndpointId{ 1 }, + kEndpointId, [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, @@ -145,16 +140,14 @@ class AppFabricTableDelegate : public FabricTable::Delegate } }; -CHIP_ERROR AppTask::Init() +CHIP_ERROR AppTask::Init(void) { - CHIP_ERROR err; - LOG_INF("SW 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); + LEDWidget::InitGpio(LEDS_PORT); LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - sStatusLED.Init(SYSTEM_STATE_LED_PIN); + sStatusLED.Init(SYSTEM_STATE_LED); UpdateStatusLED(); @@ -164,6 +157,16 @@ CHIP_ERROR AppTask::Init() k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); k_timer_user_data_set(&sFactoryResetTimer, this); + // Initialize PWM Identify led + CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("Green IDENTIFY PWM Device Init fail"); + return err; + } + + sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); + // Initialize CHIP server #if CONFIG_CHIP_FACTORY_DATA ReturnErrorOnFailure(mFactoryDataProvider.Init()); @@ -228,7 +231,7 @@ CHIP_ERROR AppTask::Init() return CHIP_NO_ERROR; } -CHIP_ERROR AppTask::StartApp() +CHIP_ERROR AppTask::StartApp(void) { CHIP_ERROR err = Init(); @@ -252,6 +255,56 @@ CHIP_ERROR AppTask::StartApp() } } +void AppTask::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) +{ + AppEvent event; + event.Type = AppEvent::kEventType_IdentifyStart; + + switch (aEffect) + { + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); + event.Handler = [](AppEvent *) { sAppTask.mPwmIdentifyLed.StopAction(); }; + event.Type = AppEvent::kEventType_IdentifyStop; + break; + default: + ChipLogProgress(Zcl, "No identifier effect"); + return; + } + + sAppTask.PostEvent(&event); +} + void AppTask::SwitchActionButtonEventHandler(void) { AppEvent event; @@ -374,7 +427,7 @@ void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) sAppTask.PostEvent(&event); } -void AppTask::UpdateStatusLED() +void AppTask::UpdateStatusLED(void) { if (sIsThreadProvisioned && sIsThreadEnabled) { @@ -420,6 +473,19 @@ void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */ } } +void AppTask::ActionIdentifyStateUpdateHandler(k_timer * timer) +{ + AppEvent event; + event.Type = AppEvent::kEventType_UpdateLedState; + event.Handler = UpdateIdentifyStateEventHandler; + sAppTask.PostEvent(&event); +} + +void AppTask::UpdateIdentifyStateEventHandler(AppEvent * aEvent) +{ + sAppTask.mPwmIdentifyLed.UpdateAction(); +} + void AppTask::ActionInitiated(AppTask::Action_t aAction, int32_t aActor) {} void AppTask::ActionCompleted(AppTask::Action_t aAction, int32_t aActor) diff --git a/examples/lighting-app/telink/README.md b/examples/lighting-app/telink/README.md index d6ace813c0df75..11594c9091855e 100644 --- a/examples/lighting-app/telink/README.md +++ b/examples/lighting-app/telink/README.md @@ -67,16 +67,55 @@ The following buttons are available on **tlsr9518adk80d** board: ### LEDs -**Red** LED indicates current state of Thread network. It ables to be in +#### Indicate current state of Thread network + +**Red** LED indicates current state of Thread network. It is able 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 | +| Blinks with frequent pulses | Device is commissioned, Thread enabled. Device trying to JOIN thread network | +| Blinks with wide pulses | Device commissioned and joined to thread network as CHILD | + +#### Indicate identify of device + +**Green** LED used to identify the device. The LED starts blinking when the +Identify command of the Identify cluster is received. The command's argument can +be used to specify the the effect. It is able to be in following effects: + +| Effect | Description | +| :------------------------------ | :------------------------------------------------------------------- | +| Blinks (200 ms on/200 ms off) | Blink (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK) | +| Breathe (during 1000 ms) | Breathe (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE) | +| Blinks (50 ms on/950 ms off) | Okay (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY) | +| Blinks (1000 ms on/1000 ms off) | Channel Change (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE) | +| Blinks (950 ms on/50 ms off) | Finish (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT) | +| LED off | Stop (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT) | + +#### Indicate current state of lightbulb + +By default, only **Blue** LED is used to show current state of lightbulb (only +for lightning-app). + +To enable RGB functionality in Your application set this config: + +In Matter examples/lighting-app/telink/include/**AppConfig.h**, set the define +`USE_RGB_PWM`: + +```bash + define USE_RGB_PWM 1 +``` + +To get current state of lightbulb in RGB mode, connect 3-color LED module to +following pins: -**Blue** LED shows current state of lightbulb +| Name | Pin | +| :---: | :-----------------: | +| Red | PE2 (pin 8 of J34) | +| Green | PE0 (pin 5 of J34) | +| Blue | PB4 (pin 20 of J34) | +| GND | GND (pin 24 of J50) | ### CHIP tool commands diff --git a/examples/lighting-app/telink/include/AppConfig.h b/examples/lighting-app/telink/include/AppConfig.h index 3c2430643eb2ee..531cca82215120 100644 --- a/examples/lighting-app/telink/include/AppConfig.h +++ b/examples/lighting-app/telink/include/AppConfig.h @@ -29,15 +29,15 @@ #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 +#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) +#define SYSTEM_STATE_LED 7 // Lighting LED config #define USE_RGB_PWM 0 -#define LIGHTING_PWM_SPEC_BLUE PWM_DT_SPEC_GET(DT_ALIAS(pwm_led0)) +#define LIGHTING_PWM_SPEC_RGB_BLUE PWM_DT_SPEC_GET(DT_ALIAS(pwm_led0)) #if USE_RGB_PWM -#define LIGHTING_PWM_SPEC_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led1)) -#define LIGHTING_PWM_SPEC_RED PWM_DT_SPEC_GET(DT_ALIAS(pwm_led2)) +#define LIGHTING_PWM_SPEC_RGB_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led1)) +#define LIGHTING_PWM_SPEC_RGB_RED PWM_DT_SPEC_GET(DT_ALIAS(pwm_led2)) #endif +#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) diff --git a/examples/lighting-app/telink/include/AppEvent.h b/examples/lighting-app/telink/include/AppEvent.h index 1766b5d77577a1..72554b4bb54b5a 100644 --- a/examples/lighting-app/telink/include/AppEvent.h +++ b/examples/lighting-app/telink/include/AppEvent.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2022 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -32,6 +32,8 @@ struct AppEvent kEventType_Button = 0, kEventType_Timer, kEventType_UpdateLedState, + kEventType_IdentifyStart, + kEventType_IdentifyStop, kEventType_Lighting, kEventType_Install, }; diff --git a/examples/lighting-app/telink/include/AppTask.h b/examples/lighting-app/telink/include/AppTask.h index e0b37739915d4e..f0a175a4d9f9c1 100644 --- a/examples/lighting-app/telink/include/AppTask.h +++ b/examples/lighting-app/telink/include/AppTask.h @@ -18,6 +18,7 @@ #pragma once +#include "AppConfig.h" #include "AppEvent.h" #include "LEDWidget.h" #include "PWMDevice.h" @@ -34,16 +35,17 @@ #include struct k_timer; +struct Identify; class AppTask { public: - CHIP_ERROR StartApp(); + CHIP_ERROR StartApp(void); void SetInitiateAction(PWMDevice::Action_t aAction, int32_t aActor, uint8_t * value); void PostEvent(AppEvent * aEvent); - void UpdateClusterState(); - PWMDevice & GetPWMDevice() { return mBluePwmLed; } + void UpdateClusterState(void); + PWMDevice & GetPWMDevice(void) { return mPwmRgbBlueLed; } enum ButtonId_t { @@ -53,19 +55,22 @@ class AppTask kButtonId_StartBleAdv } ButtonId; + static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); + private: #ifdef CONFIG_CHIP_PW_RPC friend class chip::rpc::TelinkButton; #endif friend AppTask & GetAppTask(void); - CHIP_ERROR Init(); + CHIP_ERROR Init(void); static void ActionInitiated(PWMDevice::Action_t aAction, int32_t aActor); static void ActionCompleted(PWMDevice::Action_t aAction, int32_t aActor); + static void ActionIdentifyStateUpdateHandler(k_timer * timer); void DispatchEvent(AppEvent * event); - static void UpdateStatusLED(); + static void UpdateStatusLED(void); static void LEDStateUpdateHandler(LEDWidget * ledWidget); static void LightingActionButtonEventHandler(void); static void FactoryResetButtonEventHandler(void); @@ -82,6 +87,7 @@ class AppTask static void LightingActionEventHandler(AppEvent * aEvent); static void StartBleAdvHandler(AppEvent * aEvent); static void UpdateLedStateEventHandler(AppEvent * aEvent); + static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); static void ButtonEventHandler(ButtonId_t btnId, bool btnPressed); static void InitButtons(void); @@ -89,11 +95,12 @@ class AppTask static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); static AppTask sAppTask; - PWMDevice mBluePwmLed; + PWMDevice mPwmRgbBlueLed; #if USE_RGB_PWM - PWMDevice mGreenPwmLed; - PWMDevice mRedPwmLed; + PWMDevice mPwmRgbGreenLed; + PWMDevice mPwmRgbRedLed; #endif + PWMDevice mPwmIdentifyLed; #if CONFIG_CHIP_FACTORY_DATA // chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; diff --git a/examples/lighting-app/telink/src/AppTask.cpp b/examples/lighting-app/telink/src/AppTask.cpp index 0dd80c267c668e..f05f0f9c7affab 100644 --- a/examples/lighting-app/telink/src/AppTask.cpp +++ b/examples/lighting-app/telink/src/AppTask.cpp @@ -72,18 +72,27 @@ using namespace ::chip::Credentials; using namespace ::chip::DeviceLayer; namespace { -constexpr int kFactoryResetTriggerTimeout = 2000; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; -constexpr uint8_t kDefaultMinLevel = 0; -constexpr uint8_t kDefaultMaxLevel = 254; - -const struct pwm_dt_spec sBluePwmLed = LIGHTING_PWM_SPEC_BLUE; +constexpr int kFactoryResetTriggerTimeout = 2000; +constexpr int kAppEventQueueSize = 10; +constexpr uint8_t kButtonPushEvent = 1; +constexpr uint8_t kButtonReleaseEvent = 0; +constexpr EndpointId kLightEndpointId = 1; +constexpr uint8_t kDefaultMinLevel = 0; +constexpr uint8_t kDefaultMaxLevel = 254; +constexpr uint32_t kIdentifyBlinkRateMs = 200; +constexpr uint32_t kIdentifyOkayOnRateMs = 50; +constexpr uint32_t kIdentifyOkayOffRateMs = 950; +constexpr uint32_t kIdentifyFinishOnRateMs = 950; +constexpr uint32_t kIdentifyFinishOffRateMs = 50; +constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; +constexpr uint32_t kIdentifyBreatheRateMs = 1000; + +const struct pwm_dt_spec sPwmRgbSpecBlueLed = LIGHTING_PWM_SPEC_RGB_BLUE; #if USE_RGB_PWM -const struct pwm_dt_spec sGreenPwmLed = LIGHTING_PWM_SPEC_GREEN; -const struct pwm_dt_spec sRedPwmLed = LIGHTING_PWM_SPEC_RED; +const struct pwm_dt_spec sPwmRgbSpecGreenLed = LIGHTING_PWM_SPEC_RGB_GREEN; +const struct pwm_dt_spec sPwmRgbSpecRedLed = LIGHTING_PWM_SPEC_RGB_RED; #endif +const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; #if CONFIG_CHIP_FACTORY_DATA // NOTE! This key is for test/certification only and should not be available in production devices! @@ -118,29 +127,11 @@ 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; + AppTask::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); } Identify sIdentify = { - chip::EndpointId{ 1 }, + kLightEndpointId, [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, @@ -162,14 +153,15 @@ class AppFabricTableDelegate : public FabricTable::Delegate } }; -CHIP_ERROR AppTask::Init() +CHIP_ERROR AppTask::Init(void) { LOG_INF("SW 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); + // Initialize LEDs + LEDWidget::InitGpio(LEDS_PORT); LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - sStatusLED.Init(SYSTEM_STATE_LED_PIN); + + sStatusLED.Init(SYSTEM_STATE_LED); UpdateStatusLED(); @@ -181,33 +173,42 @@ CHIP_ERROR AppTask::Init() // Init lighting manager uint8_t minLightLevel = kDefaultMinLevel; - Clusters::LevelControl::Attributes::MinLevel::Get(1, &minLightLevel); + Clusters::LevelControl::Attributes::MinLevel::Get(kLightEndpointId, &minLightLevel); uint8_t maxLightLevel = kDefaultMaxLevel; - Clusters::LevelControl::Attributes::MaxLevel::Get(1, &maxLightLevel); + Clusters::LevelControl::Attributes::MaxLevel::Get(kLightEndpointId, &maxLightLevel); + + // Initialize PWM LEDs + CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("Green IDENTIFY PWM Device Init fail"); + return err; + } - CHIP_ERROR err = sAppTask.mBluePwmLed.Init(&sBluePwmLed, minLightLevel, maxLightLevel, maxLightLevel); + err = sAppTask.mPwmRgbBlueLed.Init(&sPwmRgbSpecBlueLed, minLightLevel, maxLightLevel, maxLightLevel); if (err != CHIP_NO_ERROR) { - LOG_ERR("Blue PWM Device Init fail"); + LOG_ERR("Blue RGB PWM Device Init fail"); return err; } #if USE_RGB_PWM - err = sAppTask.mRedPwmLed.Init(&sRedPwmLed, minLightLevel, maxLightLevel, maxLightLevel); + err = sAppTask.mPwmRgbRedLed.Init(&sPwmRgbSpecRedLed, minLightLevel, maxLightLevel, maxLightLevel); if (err != CHIP_NO_ERROR) { - LOG_ERR("Red PWM Device Init fail"); + LOG_ERR("Red RGB PWM Device Init fail"); return err; } - err = sAppTask.mGreenPwmLed.Init(&sGreenPwmLed, minLightLevel, maxLightLevel, maxLightLevel); + err = sAppTask.mPwmRgbGreenLed.Init(&sPwmRgbSpecGreenLed, minLightLevel, maxLightLevel, maxLightLevel); if (err != CHIP_NO_ERROR) { - LOG_ERR("Green PWM Device Init fail"); + LOG_ERR("Green RGB PWM Device Init fail"); return err; } #endif - sAppTask.mBluePwmLed.SetCallbacks(ActionInitiated, ActionCompleted); + sAppTask.mPwmRgbBlueLed.SetCallbacks(ActionInitiated, ActionCompleted, nullptr); + sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); // Initialize CHIP server #if CONFIG_CHIP_FACTORY_DATA @@ -265,7 +266,7 @@ CHIP_ERROR AppTask::Init() return CHIP_NO_ERROR; } -CHIP_ERROR AppTask::StartApp() +CHIP_ERROR AppTask::StartApp(void) { CHIP_ERROR err = Init(); @@ -312,7 +313,7 @@ void AppTask::LightingActionEventHandler(AppEvent * aEvent) else if (aEvent->Type == AppEvent::kEventType_Button) { #if USE_RGB_PWM - if (sAppTask.mRedPwmLed.IsTurnedOn() || sAppTask.mGreenPwmLed.IsTurnedOn() || sAppTask.mBluePwmLed.IsTurnedOn()) + if (sAppTask.mPwmRgbRedLed.IsTurnedOn() || sAppTask.mPwmRgbGreenLed.IsTurnedOn() || sAppTask.mPwmRgbBlueLed.IsTurnedOn()) { action = PWMDevice::OFF_ACTION; } @@ -321,7 +322,7 @@ void AppTask::LightingActionEventHandler(AppEvent * aEvent) action = PWMDevice::ON_ACTION; } #else - action = sAppTask.mBluePwmLed.IsTurnedOn() ? PWMDevice::OFF_ACTION : PWMDevice::ON_ACTION; + action = sAppTask.mPwmRgbBlueLed.IsTurnedOn() ? PWMDevice::OFF_ACTION : PWMDevice::ON_ACTION; #endif actor = AppEvent::kEventType_Button; } @@ -329,15 +330,65 @@ void AppTask::LightingActionEventHandler(AppEvent * aEvent) if (action != PWMDevice::INVALID_ACTION && ( #if USE_RGB_PWM - !sAppTask.mRedPwmLed.InitiateAction(action, actor, NULL) || - !sAppTask.mGreenPwmLed.InitiateAction(action, actor, NULL) || + !sAppTask.mPwmRgbRedLed.InitiateAction(action, actor, NULL) || + !sAppTask.mPwmRgbGreenLed.InitiateAction(action, actor, NULL) || #endif - !sAppTask.mBluePwmLed.InitiateAction(action, actor, NULL))) + !sAppTask.mPwmRgbBlueLed.InitiateAction(action, actor, NULL))) { LOG_INF("Action is in progress or active"); } } +void AppTask::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) +{ + AppEvent event; + event.Type = AppEvent::kEventType_IdentifyStart; + + switch (aEffect) + { + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); + event.Handler = [](AppEvent *) { sAppTask.mPwmIdentifyLed.StopAction(); }; + event.Type = AppEvent::kEventType_IdentifyStop; + break; + default: + ChipLogProgress(Zcl, "No identifier effect"); + return; + } + + sAppTask.PostEvent(&event); +} + void AppTask::FactoryResetButtonEventHandler(void) { AppEvent event; @@ -438,7 +489,7 @@ void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) sAppTask.PostEvent(&event); } -void AppTask::UpdateStatusLED() +void AppTask::UpdateStatusLED(void) { if (sIsThreadProvisioned && sIsThreadEnabled) { @@ -484,6 +535,19 @@ void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */ } } +void AppTask::ActionIdentifyStateUpdateHandler(k_timer * timer) +{ + AppEvent event; + event.Type = AppEvent::kEventType_UpdateLedState; + event.Handler = UpdateIdentifyStateEventHandler; + sAppTask.PostEvent(&event); +} + +void AppTask::UpdateIdentifyStateEventHandler(AppEvent * aEvent) +{ + sAppTask.mPwmIdentifyLed.UpdateAction(); +} + void AppTask::ActionInitiated(PWMDevice::Action_t aAction, int32_t aActor) { if (aAction == PWMDevice::ON_ACTION) @@ -541,15 +605,16 @@ void AppTask::DispatchEvent(AppEvent * aEvent) } } -void AppTask::UpdateClusterState() +void AppTask::UpdateClusterState(void) { #if USE_RGB_PWM - bool isTurnedOn = sAppTask.mRedPwmLed.IsTurnedOn() || sAppTask.mGreenPwmLed.IsTurnedOn() || sAppTask.mBluePwmLed.IsTurnedOn(); + bool isTurnedOn = + sAppTask.mPwmRgbRedLed.IsTurnedOn() || sAppTask.mPwmRgbGreenLed.IsTurnedOn() || sAppTask.mPwmRgbBlueLed.IsTurnedOn(); #else - bool isTurnedOn = sAppTask.mBluePwmLed.IsTurnedOn(); + bool isTurnedOn = sAppTask.mPwmRgbBlueLed.IsTurnedOn(); #endif // write the new on/off value - EmberAfStatus status = Clusters::OnOff::Attributes::OnOff::Set(1, isTurnedOn); + EmberAfStatus status = Clusters::OnOff::Attributes::OnOff::Set(kLightEndpointId, isTurnedOn); if (status != EMBER_ZCL_STATUS_SUCCESS) { @@ -565,12 +630,12 @@ void AppTask::UpdateClusterState() } else { - setLevel = sAppTask.mBluePwmLed.GetLevel(); + setLevel = sAppTask.mPwmRgbBlueLed.GetLevel(); } #else - uint8_t setLevel = sAppTask.mBluePwmLed.GetLevel(); + uint8_t setLevel = sAppTask.mPwmRgbBlueLed.GetLevel(); #endif - status = Clusters::LevelControl::Attributes::CurrentLevel::Set(1, setLevel); + status = Clusters::LevelControl::Attributes::CurrentLevel::Set(kLightEndpointId, setLevel); if (status != EMBER_ZCL_STATUS_SUCCESS) { LOG_ERR("Update CurrentLevel fail: %x", status); @@ -648,10 +713,10 @@ void AppTask::SetInitiateAction(PWMDevice::Action_t aAction, int32_t aActor, uin if (aAction == PWMDevice::ON_ACTION || aAction == PWMDevice::OFF_ACTION) { - sAppTask.mBluePwmLed.InitiateAction(aAction, aActor, value); + sAppTask.mPwmRgbBlueLed.InitiateAction(aAction, aActor, value); #if USE_RGB_PWM - sAppTask.mRedPwmLed.InitiateAction(aAction, aActor, value); - sAppTask.mGreenPwmLed.InitiateAction(aAction, aActor, value); + sAppTask.mPwmRgbRedLed.InitiateAction(aAction, aActor, value); + sAppTask.mPwmRgbGreenLed.InitiateAction(aAction, aActor, value); #endif } else if (aAction == PWMDevice::LEVEL_ACTION) @@ -679,7 +744,7 @@ void AppTask::SetInitiateAction(PWMDevice::Action_t aAction, int32_t aActor, uin ChipLogProgress(Zcl, "New brightness: %u | R: %u, G: %u, B: %u", sBrightness, rgb.r, rgb.g, rgb.b); setRgbAction = true; #else - sAppTask.mBluePwmLed.InitiateAction(aAction, aActor, value); + sAppTask.mPwmRgbBlueLed.InitiateAction(aAction, aActor, value); #endif } @@ -716,9 +781,9 @@ void AppTask::SetInitiateAction(PWMDevice::Action_t aAction, int32_t aActor, uin if (setRgbAction) { - sAppTask.mRedPwmLed.InitiateAction(aAction, aActor, &rgb.r); - sAppTask.mGreenPwmLed.InitiateAction(aAction, aActor, &rgb.g); - sAppTask.mBluePwmLed.InitiateAction(aAction, aActor, &rgb.b); + sAppTask.mPwmRgbRedLed.InitiateAction(aAction, aActor, &rgb.r); + sAppTask.mPwmRgbGreenLed.InitiateAction(aAction, aActor, &rgb.g); + sAppTask.mPwmRgbBlueLed.InitiateAction(aAction, aActor, &rgb.b); } #endif } diff --git a/examples/ota-requestor-app/telink/CMakeLists.txt b/examples/ota-requestor-app/telink/CMakeLists.txt index 2a44136882b383..2590a109de43d3 100644 --- a/examples/ota-requestor-app/telink/CMakeLists.txt +++ b/examples/ota-requestor-app/telink/CMakeLists.txt @@ -51,7 +51,8 @@ target_sources(app PRIVATE src/ZclCallbacks.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp - ${TELINK_COMMON}/util/src/ThreadUtil.cpp) + ${TELINK_COMMON}/util/src/ThreadUtil.cpp + ${TELINK_COMMON}/util/src/PWMDevice.cpp) chip_configure_data_model(app INCLUDE_SERVER diff --git a/examples/ota-requestor-app/telink/Readme.md b/examples/ota-requestor-app/telink/Readme.md index 9d460240ea0b05..7a38eb4a014bf2 100755 --- a/examples/ota-requestor-app/telink/Readme.md +++ b/examples/ota-requestor-app/telink/Readme.md @@ -60,14 +60,31 @@ The following buttons are available on **tlsr9518adk80d** board: ### LEDs -**Red** LED indicates current state of Thread network. It ables to be in +#### Indicate current state of Thread network + +**Red** LED indicates current state of Thread network. It is able 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 | +| Blinks with frequent pulses | Device is commissioned, Thread enabled. Device trying to JOIN thread network | +| Blinks with wide pulses | Device commissioned and joined to thread network as CHILD | + +#### Indicate identify of device + +**Green** LED used to identify the device. The LED starts blinking when the +Identify command of the Identify cluster is received. The command's argument can +be used to specify the the effect. It is able to be in following effects: + +| Effect | Description | +| :------------------------------ | :------------------------------------------------------------------- | +| Blinks (200 ms on/200 ms off) | Blink (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK) | +| Breathe (during 1000 ms) | Breathe (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE) | +| Blinks (50 ms on/950 ms off) | Okay (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY) | +| Blinks (1000 ms on/1000 ms off) | Channel Change (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE) | +| Blinks (950 ms on/50 ms off) | Finish (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT) | +| LED off | Stop (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT) | ### CHIP tool commands diff --git a/examples/ota-requestor-app/telink/include/AppConfig.h b/examples/ota-requestor-app/telink/include/AppConfig.h index d02c641ecf53d8..468e6440d45e3f 100644 --- a/examples/ota-requestor-app/telink/include/AppConfig.h +++ b/examples/ota-requestor-app/telink/include/AppConfig.h @@ -29,6 +29,6 @@ #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 +#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) +#define SYSTEM_STATE_LED 7 +#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) diff --git a/examples/ota-requestor-app/telink/include/AppEvent.h b/examples/ota-requestor-app/telink/include/AppEvent.h index 9a6fd3060c1685..72554b4bb54b5a 100644 --- a/examples/ota-requestor-app/telink/include/AppEvent.h +++ b/examples/ota-requestor-app/telink/include/AppEvent.h @@ -32,6 +32,8 @@ struct AppEvent kEventType_Button = 0, kEventType_Timer, kEventType_UpdateLedState, + kEventType_IdentifyStart, + kEventType_IdentifyStop, kEventType_Lighting, kEventType_Install, }; diff --git a/examples/ota-requestor-app/telink/include/AppTask.h b/examples/ota-requestor-app/telink/include/AppTask.h index a8b5c2dd3e7a93..d7111cc5f6ca9d 100755 --- a/examples/ota-requestor-app/telink/include/AppTask.h +++ b/examples/ota-requestor-app/telink/include/AppTask.h @@ -20,6 +20,7 @@ #include "AppEvent.h" #include "LEDWidget.h" +#include "PWMDevice.h" #include @@ -28,11 +29,12 @@ #include struct k_timer; +struct Identify; class AppTask { public: - CHIP_ERROR StartApp(); + CHIP_ERROR StartApp(void); enum Action_t : uint8_t { @@ -45,18 +47,19 @@ class AppTask void PostLightingActionRequest(Action_t aAction); void PostEvent(AppEvent * event); + static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); private: friend AppTask & GetAppTask(void); - - CHIP_ERROR Init(); + CHIP_ERROR Init(void); static void ActionInitiated(AppTask::Action_t aAction, int32_t aActor); static void ActionCompleted(AppTask::Action_t aAction, int32_t aActor); + static void ActionIdentifyStateUpdateHandler(k_timer * timer); void DispatchEvent(AppEvent * event); - static void UpdateStatusLED(); + static void UpdateStatusLED(void); static void LEDStateUpdateHandler(LEDWidget * ledWidget); static void FactoryResetButtonEventHandler(void); static void StartThreadButtonEventHandler(void); @@ -71,12 +74,14 @@ class AppTask static void StartThreadHandler(AppEvent * aEvent); static void StartBleAdvHandler(AppEvent * aEvent); static void UpdateLedStateEventHandler(AppEvent * aEvent); + static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); static void InitButtons(void); static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); static AppTask sAppTask; + PWMDevice mPwmIdentifyLed; }; inline AppTask & GetAppTask(void) diff --git a/examples/ota-requestor-app/telink/prj.conf b/examples/ota-requestor-app/telink/prj.conf index c801f50ac570a7..e787d9ffeed55b 100755 --- a/examples/ota-requestor-app/telink/prj.conf +++ b/examples/ota-requestor-app/telink/prj.conf @@ -21,6 +21,9 @@ # enable GPIO CONFIG_GPIO=y +# enable PWM +CONFIG_PWM=y + # OpenThread configs CONFIG_OPENTHREAD_MTD=y CONFIG_OPENTHREAD_FTD=n diff --git a/examples/ota-requestor-app/telink/src/AppTask.cpp b/examples/ota-requestor-app/telink/src/AppTask.cpp index af2bc6c906a811..2df8d641cb9890 100644 --- a/examples/ota-requestor-app/telink/src/AppTask.cpp +++ b/examples/ota-requestor-app/telink/src/AppTask.cpp @@ -72,11 +72,28 @@ SHELL_CMD_REGISTER(telink, &sub_telink, "Telink commands", NULL); LOG_MODULE_DECLARE(app); +using namespace ::chip; +using namespace ::chip::app; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; + namespace { -constexpr int kFactoryResetTriggerTimeout = 2000; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; +constexpr int kFactoryResetTriggerTimeout = 2000; +constexpr int kAppEventQueueSize = 10; +constexpr uint8_t kButtonPushEvent = 1; +constexpr uint8_t kButtonReleaseEvent = 0; +constexpr EndpointId kEndpointId = 1; +constexpr uint8_t kDefaultMinLevel = 0; +constexpr uint8_t kDefaultMaxLevel = 254; +constexpr uint32_t kIdentifyBlinkRateMs = 200; +constexpr uint32_t kIdentifyOkayOnRateMs = 50; +constexpr uint32_t kIdentifyOkayOffRateMs = 950; +constexpr uint32_t kIdentifyFinishOnRateMs = 950; +constexpr uint32_t kIdentifyFinishOffRateMs = 50; +constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; +constexpr uint32_t kIdentifyBreatheRateMs = 1000; + +const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); k_timer sFactoryResetTimer; @@ -97,29 +114,11 @@ 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; + AppTask::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); } Identify sIdentify = { - chip::EndpointId{ 1 }, + kEndpointId, [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, @@ -128,11 +127,6 @@ Identify sIdentify = { } // namespace -using namespace chip; -using namespace ::chip::Credentials; -using namespace ::chip::DeviceLayer; -using namespace ::chip::DeviceLayer::Internal; - AppTask AppTask::sAppTask; class AppFabricTableDelegate : public FabricTable::Delegate @@ -148,16 +142,14 @@ class AppFabricTableDelegate : public FabricTable::Delegate constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE; -CHIP_ERROR AppTask::Init() +CHIP_ERROR AppTask::Init(void) { - CHIP_ERROR ret; - LOG_INF("SW 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); + LEDWidget::InitGpio(LEDS_PORT); LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - sStatusLED.Init(SYSTEM_STATE_LED_PIN); + sStatusLED.Init(SYSTEM_STATE_LED); UpdateStatusLED(); @@ -172,6 +164,16 @@ CHIP_ERROR AppTask::Init() (void) initParams.InitializeStaticResourcesBeforeServerInit(); chip::Server::GetInstance().Init(initParams); + // Initialize PWM Identify led + CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("Green IDENTIFY PWM Device Init fail"); + return err; + } + + sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); + // 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 @@ -195,24 +197,24 @@ CHIP_ERROR AppTask::Init() // between the main and the CHIP threads. PlatformMgr().AddEventHandler(ChipEventHandler, 0); - ret = ConnectivityMgr().SetBLEDeviceName("TelinkOTAReq"); - if (ret != CHIP_NO_ERROR) + err = ConnectivityMgr().SetBLEDeviceName("TelinkOTAReq"); + if (err != CHIP_NO_ERROR) { LOG_ERR("SetBLEDeviceName fail"); - return ret; + return err; } - ret = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); - if (ret != CHIP_NO_ERROR) + err = chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(new AppFabricTableDelegate); + if (err != CHIP_NO_ERROR) { LOG_ERR("AppFabricTableDelegate fail"); - return ret; + return err; } return CHIP_NO_ERROR; } -CHIP_ERROR AppTask::StartApp() +CHIP_ERROR AppTask::StartApp(void) { CHIP_ERROR err = Init(); @@ -236,6 +238,56 @@ CHIP_ERROR AppTask::StartApp() } } +void AppTask::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) +{ + AppEvent event; + event.Type = AppEvent::kEventType_IdentifyStart; + + switch (aEffect) + { + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); + event.Handler = [](AppEvent *) { sAppTask.mPwmIdentifyLed.StopAction(); }; + event.Type = AppEvent::kEventType_IdentifyStop; + break; + default: + ChipLogProgress(Zcl, "No identifier effect"); + return; + } + + sAppTask.PostEvent(&event); +} + void AppTask::FactoryResetButtonEventHandler(void) { AppEvent event; @@ -276,7 +328,7 @@ void AppTask::StartThreadHandler(AppEvent * aEvent) if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned()) { // Switch context from BLE to Thread - BLEManagerImpl sInstance; + Internal::BLEManagerImpl sInstance; sInstance.SwitchToIeee802154(); StartDefaultThreadNetwork(); } @@ -336,7 +388,7 @@ void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) sAppTask.PostEvent(&event); } -void AppTask::UpdateStatusLED() +void AppTask::UpdateStatusLED(void) { if (sIsThreadProvisioned && sIsThreadEnabled) { @@ -382,6 +434,19 @@ void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */ } } +void AppTask::ActionIdentifyStateUpdateHandler(k_timer * timer) +{ + AppEvent event; + event.Type = AppEvent::kEventType_UpdateLedState; + event.Handler = UpdateIdentifyStateEventHandler; + sAppTask.PostEvent(&event); +} + +void AppTask::UpdateIdentifyStateEventHandler(AppEvent * aEvent) +{ + sAppTask.mPwmIdentifyLed.UpdateAction(); +} + void AppTask::ActionInitiated(AppTask::Action_t aAction, int32_t aActor) {} void AppTask::ActionCompleted(AppTask::Action_t aAction, int32_t aActor) {} diff --git a/examples/platform/telink/util/include/PWMDevice.h b/examples/platform/telink/util/include/PWMDevice.h index 8950884f3c106e..9b3bc24d30d8c6 100644 --- a/examples/platform/telink/util/include/PWMDevice.h +++ b/examples/platform/telink/util/include/PWMDevice.h @@ -44,27 +44,53 @@ class PWMDevice kState_Off, }; - using PWMCallback_fn = void (*)(Action_t, int32_t); + enum BreatheType_t : uint8_t + { + kBreatheType_Invalid = 0, + kBreatheType_Rising, + kBreatheType_Falling, + kBreatheType_Both, + }; + + using PWMCallback_fn = void (*)(Action_t, int32_t); + using PWMTimerCallback_fn = void (*)(k_timer *); CHIP_ERROR Init(const pwm_dt_spec * pwmDevice, uint8_t aMinLevel, uint8_t aMaxLevel, uint8_t aDefaultLevel = 0); void Set(bool aOn); - bool IsTurnedOn() const { return mState == kState_On; } - uint8_t GetLevel() const { return mLevel; } - uint8_t GetMinLevel() const { return mMinLevel; } - uint8_t GetMaxLevel() const { return mMaxLevel; } + bool IsTurnedOn(void) const { return mState == kState_On; } + uint8_t GetLevel(void) const { return mLevel; } + uint8_t GetMinLevel(void) const { return mMinLevel; } + uint8_t GetMaxLevel(void) const { return mMaxLevel; } + void SetCallbacks(PWMCallback_fn aActionInitiated_CB, PWMCallback_fn aActionCompleted_CB, + PWMTimerCallback_fn aActionBlinkStateUpdate_CB); bool InitiateAction(Action_t aAction, int32_t aActor, uint8_t * value); - void SetCallbacks(PWMCallback_fn aActionInitiated_CB, PWMCallback_fn aActionCompleted_CB); + void InitiateBlinkAction(uint32_t onTimeMS, uint32_t offTimeMS); + void InitiateBreatheAction(BreatheType_t type, uint32_t cycleTimeMS); + void StopAction(void); + void UpdateAction(void); private: State_t mState; uint8_t mMinLevel; uint8_t mMaxLevel; uint8_t mLevel; + uint8_t mBreatheStepLevel; + uint8_t mBreatheStepCntr; + bool mBreatheBothDirection; + BreatheType_t mBreatheType; + uint32_t mBreatheStepNumb; + uint32_t mBlinkOnTimeMS; + uint32_t mBlinkOffTimeMS; + k_timer mPwmLedTimer; const pwm_dt_spec * mPwmDevice; PWMCallback_fn mActionInitiated_CB; PWMCallback_fn mActionCompleted_CB; void SetLevel(uint8_t aLevel); - void UpdateLight(); + void UpdateLight(void); + void StartBlinkTimer(void); + void StartBreatheTimer(uint32_t stepTimeMS); + void ClearAction(void); + static void PwmLedTimerHandler(k_timer * timer); }; diff --git a/examples/platform/telink/util/src/PWMDevice.cpp b/examples/platform/telink/util/src/PWMDevice.cpp index 6a23b399be7576..302dc3bfdeb104 100644 --- a/examples/platform/telink/util/src/PWMDevice.cpp +++ b/examples/platform/telink/util/src/PWMDevice.cpp @@ -27,6 +27,10 @@ LOG_MODULE_DECLARE(app); +constexpr uint32_t kBreatheStepTimeMS = 10; + +static PWMDevice::PWMTimerCallback_fn mActionBlinkStateUpdate_CB; + CHIP_ERROR PWMDevice::Init(const pwm_dt_spec * pwmDevice, uint8_t aMinLevel, uint8_t aMaxLevel, uint8_t aDefaultLevel) { // We use a gpioPin instead of a LEDWidget here because we want to use PWM @@ -44,14 +48,20 @@ CHIP_ERROR PWMDevice::Init(const pwm_dt_spec * pwmDevice, uint8_t aMinLevel, uin return CHIP_ERROR_INCORRECT_STATE; } + k_timer_init(&mPwmLedTimer, &PWMDevice::PwmLedTimerHandler, nullptr); + k_timer_user_data_set(&mPwmLedTimer, this); + + ClearAction(); Set(false); return CHIP_NO_ERROR; } -void PWMDevice::SetCallbacks(PWMCallback_fn aActionInitiated_CB, PWMCallback_fn aActionCompleted_CB) +void PWMDevice::SetCallbacks(PWMCallback_fn aActionInitiated_CB, PWMCallback_fn aActionCompleted_CB, + PWMTimerCallback_fn aActionBlinkStateUpdate_CB) { - mActionInitiated_CB = aActionInitiated_CB; - mActionCompleted_CB = aActionCompleted_CB; + mActionInitiated_CB = aActionInitiated_CB; + mActionCompleted_CB = aActionCompleted_CB; + mActionBlinkStateUpdate_CB = aActionBlinkStateUpdate_CB; } bool PWMDevice::InitiateAction(Action_t aAction, int32_t aActor, uint8_t * value) @@ -122,7 +132,7 @@ void PWMDevice::Set(bool aOn) UpdateLight(); } -void PWMDevice::UpdateLight() +void PWMDevice::UpdateLight(void) { constexpr uint32_t kPwmWidthUs = 20000u; const uint8_t maxEffectiveLevel = mMaxLevel - mMinLevel; @@ -131,3 +141,155 @@ void PWMDevice::UpdateLight() pwm_set(mPwmDevice->dev, mPwmDevice->channel, PWM_USEC(kPwmWidthUs), PWM_USEC(kPwmWidthUs * effectiveLevel / maxEffectiveLevel), 0); } + +void PWMDevice::InitiateBlinkAction(uint32_t onTimeMS, uint32_t offTimeMS) +{ + ClearAction(); + + if (onTimeMS != 0 && offTimeMS != 0) + { + mBlinkOnTimeMS = onTimeMS; + mBlinkOffTimeMS = offTimeMS; + + Set(mState != kState_On ? true : false); + StartBlinkTimer(); + } + else + { + LOG_ERR("Invalid InitiateBlinkAction parameters. onTimeMS = %u, offTimeMS = %u", onTimeMS, offTimeMS); + } +} + +void PWMDevice::InitiateBreatheAction(BreatheType_t type, uint32_t cycleTimeMS) +{ + ClearAction(); + + if (type != kBreatheType_Invalid && cycleTimeMS != 0) + { + mBreatheType = type; + mBreatheStepNumb = cycleTimeMS / kBreatheStepTimeMS; + mBreatheStepLevel = (mMaxLevel - mMinLevel) / mBreatheStepNumb; + + if (mBreatheType == kBreatheType_Both) + { + mBreatheBothDirection = true; + mBreatheType = mState == kState_On ? kBreatheType_Falling : kBreatheType_Rising; + } + + if (mBreatheType == kBreatheType_Falling) + { + mLevel = mMaxLevel; + } + else + { + mLevel = mMinLevel; + } + + Set(true); + StartBreatheTimer(kBreatheStepTimeMS); + } + else + { + LOG_ERR("Invalid InitiateBreatheAction parameters. Type = %u, cycleTimeMS = %u", type, cycleTimeMS); + } +} + +void PWMDevice::StopAction(void) +{ + ClearAction(); + Set(false); +} + +void PWMDevice::UpdateAction(void) +{ + // Update of Breathe action + if (mBreatheType != kBreatheType_Invalid && mBreatheStepLevel != 0 && mBreatheStepNumb != 0) + { + if (mBreatheStepCntr == mBreatheStepNumb) + { + mBreatheStepCntr = 0; + if (mBreatheBothDirection) + { + mBreatheType = mBreatheType == kBreatheType_Rising ? kBreatheType_Falling : kBreatheType_Rising; + } + } + else + { + mBreatheStepCntr++; + } + + if (mBreatheType == kBreatheType_Rising) + { + if (mBreatheStepCntr == mBreatheStepNumb) + { + mLevel = mMaxLevel; + } + else if (mBreatheStepCntr == 0) + { + mLevel = mMinLevel; + } + else + { + mLevel += mBreatheStepLevel; + } + } + else if (mBreatheType == kBreatheType_Falling) + { + if (mBreatheStepCntr == mBreatheStepNumb) + { + mLevel = mMinLevel; + } + else if (mBreatheStepCntr == 0) + { + mLevel = mMaxLevel; + } + else + { + mLevel -= mBreatheStepLevel; + } + } + + Set(true); + StartBreatheTimer(kBreatheStepTimeMS); + } + // Update of Blink action + else if (mBlinkOnTimeMS != 0 && mBlinkOffTimeMS != 0) + { + Set(mState != kState_On ? true : false); + StartBlinkTimer(); + } + else + { + LOG_ERR("PWM LED update state is incorrect"); + } +} + +void PWMDevice::StartBlinkTimer(void) +{ + k_timer_start(&mPwmLedTimer, K_MSEC(mState == kState_On ? mBlinkOnTimeMS : mBlinkOffTimeMS), K_NO_WAIT); +} + +void PWMDevice::StartBreatheTimer(uint32_t stepTimeMS) +{ + k_timer_start(&mPwmLedTimer, K_MSEC(stepTimeMS), K_NO_WAIT); +} + +void PWMDevice::ClearAction(void) +{ + k_timer_stop(&mPwmLedTimer); + mBreatheBothDirection = false; + mBreatheType = kBreatheType_Invalid; + mBreatheStepLevel = 0; + mBreatheStepNumb = 0; + mBlinkOnTimeMS = 0; + mBlinkOffTimeMS = 0; + mLevel = mMaxLevel; +} + +void PWMDevice::PwmLedTimerHandler(k_timer * timer) +{ + if (mActionBlinkStateUpdate_CB) + { + mActionBlinkStateUpdate_CB(timer); + } +} diff --git a/examples/thermostat/telink/CMakeLists.txt b/examples/thermostat/telink/CMakeLists.txt index dd1399f54ab19f..375952e2959c53 100755 --- a/examples/thermostat/telink/CMakeLists.txt +++ b/examples/thermostat/telink/CMakeLists.txt @@ -53,7 +53,8 @@ target_sources(app PRIVATE src/ZclCallbacks.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp ${TELINK_COMMON}/util/src/ButtonManager.cpp - ${TELINK_COMMON}/util/src/ThreadUtil.cpp) + ${TELINK_COMMON}/util/src/ThreadUtil.cpp + ${TELINK_COMMON}/util/src/PWMDevice.cpp) chip_configure_data_model(app INCLUDE_SERVER diff --git a/examples/thermostat/telink/Readme.md b/examples/thermostat/telink/Readme.md index 18dd713f7ec07d..bba0bb64e465b3 100755 --- a/examples/thermostat/telink/Readme.md +++ b/examples/thermostat/telink/Readme.md @@ -64,14 +64,31 @@ The following buttons are available on **tlsr9518adk80d** board: ### LEDs -**Red** LED indicates current state of Thread network. It ables to be in +#### Indicate current state of Thread network + +**Red** LED indicates current state of Thread network. It is able 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 | +| Blinks with frequent pulses | Device is commissioned, Thread enabled. Device trying to JOIN thread network | +| Blinks with wide pulses | Device commissioned and joined to thread network as CHILD | + +#### Indicate identify of device + +**Green** LED used to identify the device. The LED starts blinking when the +Identify command of the Identify cluster is received. The command's argument can +be used to specify the the effect. It is able to be in following effects: + +| Effect | Description | +| :------------------------------ | :------------------------------------------------------------------- | +| Blinks (200 ms on/200 ms off) | Blink (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK) | +| Breathe (during 1000 ms) | Breathe (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE) | +| Blinks (50 ms on/950 ms off) | Okay (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY) | +| Blinks (1000 ms on/1000 ms off) | Channel Change (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE) | +| Blinks (950 ms on/50 ms off) | Finish (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT) | +| LED off | Stop (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT) | ### CHIP tool commands diff --git a/examples/thermostat/telink/include/AppConfig.h b/examples/thermostat/telink/include/AppConfig.h index d852da9edb0417..4e023cca312073 100755 --- a/examples/thermostat/telink/include/AppConfig.h +++ b/examples/thermostat/telink/include/AppConfig.h @@ -29,6 +29,6 @@ #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 +#define LEDS_PORT DEVICE_DT_GET(DT_NODELABEL(gpiob)) +#define SYSTEM_STATE_LED 7 +#define LIGHTING_PWM_SPEC_IDENTIFY_GREEN PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3)) diff --git a/examples/thermostat/telink/include/AppEvent.h b/examples/thermostat/telink/include/AppEvent.h index 07a10228175763..3d5d5bc78d5883 100755 --- a/examples/thermostat/telink/include/AppEvent.h +++ b/examples/thermostat/telink/include/AppEvent.h @@ -32,6 +32,8 @@ struct AppEvent kEventType_Button = 0, kEventType_Timer, kEventType_UpdateLedState, + kEventType_IdentifyStart, + kEventType_IdentifyStop, kEventType_Thermostat, kEventType_Install, }; diff --git a/examples/thermostat/telink/include/AppTask.h b/examples/thermostat/telink/include/AppTask.h index 18edadc0436845..2f75c4f308133b 100755 --- a/examples/thermostat/telink/include/AppTask.h +++ b/examples/thermostat/telink/include/AppTask.h @@ -20,6 +20,7 @@ #include "AppEvent.h" #include "LEDWidget.h" +#include "PWMDevice.h" #include "SensorManager.h" #include "TemperatureManager.h" @@ -34,23 +35,28 @@ #include struct k_timer; +struct Identify; class AppTask { public: - CHIP_ERROR StartApp(); + CHIP_ERROR StartApp(void); void PostEvent(AppEvent * event); - void UpdateClusterState(); - void UpdateThermoStatUI(); + static void IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect); + + void UpdateClusterState(void); + void UpdateThermoStatUI(void); private: friend AppTask & GetAppTask(void); - CHIP_ERROR Init(); + CHIP_ERROR Init(void); + + static void ActionIdentifyStateUpdateHandler(k_timer * timer); void DispatchEvent(AppEvent * event); - static void UpdateStatusLED(); + static void UpdateStatusLED(void); static void LEDStateUpdateHandler(LEDWidget * ledWidget); static void FactoryResetButtonEventHandler(void); static void StartThreadButtonEventHandler(void); @@ -65,12 +71,14 @@ class AppTask static void StartThreadHandler(AppEvent * aEvent); static void StartBleAdvHandler(AppEvent * aEvent); static void UpdateLedStateEventHandler(AppEvent * aEvent); + static void UpdateIdentifyStateEventHandler(AppEvent * aEvent); static void InitButtons(void); static void ThreadProvisioningHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); static AppTask sAppTask; + PWMDevice mPwmIdentifyLed; #if CONFIG_CHIP_FACTORY_DATA // chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; diff --git a/examples/thermostat/telink/prj.conf b/examples/thermostat/telink/prj.conf index 0c37f49ea8f8c6..26765a55c99d10 100755 --- a/examples/thermostat/telink/prj.conf +++ b/examples/thermostat/telink/prj.conf @@ -21,6 +21,9 @@ # enable GPIO CONFIG_GPIO=y +# enable PWM +CONFIG_PWM=y + # OpenThread configs CONFIG_OPENTHREAD_MTD=y CONFIG_OPENTHREAD_FTD=n diff --git a/examples/thermostat/telink/src/AppTask.cpp b/examples/thermostat/telink/src/AppTask.cpp index 28df4af294a3bc..3640f4830f8af4 100644 --- a/examples/thermostat/telink/src/AppTask.cpp +++ b/examples/thermostat/telink/src/AppTask.cpp @@ -70,15 +70,28 @@ using namespace ::chip::Credentials; using namespace ::chip::DeviceLayer; namespace { -constexpr int kFactoryResetTriggerTimeout = 2000; -constexpr int kAppEventQueueSize = 10; -constexpr uint8_t kButtonPushEvent = 1; -constexpr uint8_t kButtonReleaseEvent = 0; +constexpr int kFactoryResetTriggerTimeout = 2000; +constexpr int kAppEventQueueSize = 10; +constexpr uint8_t kButtonPushEvent = 1; +constexpr uint8_t kButtonReleaseEvent = 0; +constexpr EndpointId kEndpointId = 1; +constexpr uint8_t kDefaultMinLevel = 0; +constexpr uint8_t kDefaultMaxLevel = 254; +constexpr uint32_t kIdentifyBlinkRateMs = 200; +constexpr uint32_t kIdentifyOkayOnRateMs = 50; +constexpr uint32_t kIdentifyOkayOffRateMs = 950; +constexpr uint32_t kIdentifyFinishOnRateMs = 950; +constexpr uint32_t kIdentifyFinishOffRateMs = 50; +constexpr uint32_t kIdentifyChannelChangeRateMs = 1000; +constexpr uint32_t kIdentifyBreatheRateMs = 1000; + +const struct pwm_dt_spec sPwmIdentifySpecGreenLed = LIGHTING_PWM_SPEC_IDENTIFY_GREEN; +#if CONFIG_CHIP_FACTORY_DATA // NOTE! This key is for test/certification only and should not be available in production devices! -// If CONFIG_CHIP_FACTORY_DATA is enabled, this value is read from the factory data. uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; +#endif K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); k_timer sFactoryResetTimer; @@ -99,29 +112,11 @@ 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; + AppTask::IdentifyEffectHandler(identify->mCurrentEffectIdentifier); } Identify sIdentify = { - chip::EndpointId{ 1 }, + kEndpointId, [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStart"); }, [](Identify *) { ChipLogProgress(Zcl, "OnIdentifyStop"); }, EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, @@ -143,16 +138,14 @@ class AppFabricTableDelegate : public FabricTable::Delegate } }; -CHIP_ERROR AppTask::Init() +CHIP_ERROR AppTask::Init(void) { - CHIP_ERROR err; - LOG_INF("SW 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); + LEDWidget::InitGpio(LEDS_PORT); LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); - sStatusLED.Init(SYSTEM_STATE_LED_PIN); + sStatusLED.Init(SYSTEM_STATE_LED); UpdateStatusLED(); @@ -162,6 +155,16 @@ CHIP_ERROR AppTask::Init() k_timer_init(&sFactoryResetTimer, &AppTask::FactoryResetTimerTimeoutCallback, nullptr); k_timer_user_data_set(&sFactoryResetTimer, this); + // Initialize PWM Identify led + CHIP_ERROR err = sAppTask.mPwmIdentifyLed.Init(&sPwmIdentifySpecGreenLed, kDefaultMinLevel, kDefaultMaxLevel, kDefaultMaxLevel); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("Green IDENTIFY PWM Device Init fail"); + return err; + } + + sAppTask.mPwmIdentifyLed.SetCallbacks(nullptr, nullptr, ActionIdentifyStateUpdateHandler); + // Initialize CHIP server #if CONFIG_CHIP_FACTORY_DATA ReturnErrorOnFailure(mFactoryDataProvider.Init()); @@ -231,7 +234,7 @@ CHIP_ERROR AppTask::Init() return CHIP_NO_ERROR; } -CHIP_ERROR AppTask::StartApp() +CHIP_ERROR AppTask::StartApp(void) { CHIP_ERROR err = Init(); @@ -255,7 +258,57 @@ CHIP_ERROR AppTask::StartApp() } } -void AppTask::UpdateThermoStatUI() +void AppTask::IdentifyEffectHandler(EmberAfIdentifyEffectIdentifier aEffect) +{ + AppEvent event; + event.Type = AppEvent::kEventType_IdentifyStart; + + switch (aEffect) + { + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyBlinkRateMs, kIdentifyBlinkRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBreatheAction(PWMDevice::kBreatheType_Both, kIdentifyBreatheRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyOkayOnRateMs, kIdentifyOkayOffRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyChannelChangeRateMs, kIdentifyChannelChangeRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_FINISH_EFFECT"); + event.Handler = [](AppEvent *) { + sAppTask.mPwmIdentifyLed.InitiateBlinkAction(kIdentifyFinishOnRateMs, kIdentifyFinishOffRateMs); + }; + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_STOP_EFFECT"); + event.Handler = [](AppEvent *) { sAppTask.mPwmIdentifyLed.StopAction(); }; + event.Type = AppEvent::kEventType_IdentifyStop; + break; + default: + ChipLogProgress(Zcl, "No identifier effect"); + return; + } + + sAppTask.PostEvent(&event); +} + +void AppTask::UpdateThermoStatUI(void) { LOG_INF("Thermostat Status - M:%d T:%d'C H:%d'C C:%d'C", TempMgr().GetMode(), TempMgr().GetCurrentTemp(), TempMgr().GetHeatingSetPoint(), TempMgr().GetCoolingSetPoint()); @@ -361,7 +414,7 @@ void AppTask::LEDStateUpdateHandler(LEDWidget * ledWidget) sAppTask.PostEvent(&event); } -void AppTask::UpdateStatusLED() +void AppTask::UpdateStatusLED(void) { if (sIsThreadProvisioned && sIsThreadEnabled) { @@ -407,6 +460,19 @@ void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */ } } +void AppTask::ActionIdentifyStateUpdateHandler(k_timer * timer) +{ + AppEvent event; + event.Type = AppEvent::kEventType_UpdateLedState; + event.Handler = UpdateIdentifyStateEventHandler; + sAppTask.PostEvent(&event); +} + +void AppTask::UpdateIdentifyStateEventHandler(AppEvent * aEvent) +{ + sAppTask.mPwmIdentifyLed.UpdateAction(); +} + void AppTask::PostEvent(AppEvent * aEvent) { if (k_msgq_put(&sAppEventQueue, aEvent, K_NO_WAIT) != 0) diff --git a/examples/thermostat/thermostat-common/thermostat.matter b/examples/thermostat/thermostat-common/thermostat.matter index c9189ff37486d0..b0827ce5344894 100644 --- a/examples/thermostat/thermostat-common/thermostat.matter +++ b/examples/thermostat/thermostat-common/thermostat.matter @@ -73,7 +73,13 @@ server cluster Identify = 3 { INT16U identifyTime = 0; } + request struct TriggerEffectRequest { + IdentifyEffectIdentifier effectIdentifier = 0; + IdentifyEffectVariant effectVariant = 1; + } + command access(invoke: manage) Identify(IdentifyRequest): DefaultSuccess = 0; + command access(invoke: manage) TriggerEffect(TriggerEffectRequest): DefaultSuccess = 64; } server cluster Groups = 4 { diff --git a/examples/thermostat/thermostat-common/thermostat.zap b/examples/thermostat/thermostat-common/thermostat.zap index 724bf8984810c5..7ac2eb62c9b93c 100644 --- a/examples/thermostat/thermostat-common/thermostat.zap +++ b/examples/thermostat/thermostat-common/thermostat.zap @@ -7509,6 +7509,14 @@ "source": "client", "incoming": 1, "outgoing": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 } ], "attributes": [ diff --git a/integrations/cloudbuild/build-all.yaml b/integrations/cloudbuild/build-all.yaml index b4367b94d5c75d..4e02ff540ae2d6 100644 --- a/integrations/cloudbuild/build-all.yaml +++ b/integrations/cloudbuild/build-all.yaml @@ -6,7 +6,7 @@ steps: - "--init" - "--recursive" id: Submodules - - name: "connectedhomeip/chip-build-vscode:0.6.34" + - name: "connectedhomeip/chip-build-vscode:0.6.35" env: - PW_ENVIRONMENT_ROOT=/pwenv args: @@ -21,7 +21,7 @@ steps: path: /pwenv timeout: 900s - - name: "connectedhomeip/chip-build-vscode:0.6.34" + - name: "connectedhomeip/chip-build-vscode:0.6.35" env: - PW_ENVIRONMENT_ROOT=/pwenv args: @@ -76,7 +76,7 @@ steps: --target k32w-shell build --create-archives /workspace/artifacts/ - - name: "connectedhomeip/chip-build-vscode:0.6.34" + - name: "connectedhomeip/chip-build-vscode:0.6.35" env: - PW_ENVIRONMENT_ROOT=/pwenv args: diff --git a/integrations/cloudbuild/chef.yaml b/integrations/cloudbuild/chef.yaml index e32fb2487c47fb..917f6316867ccc 100644 --- a/integrations/cloudbuild/chef.yaml +++ b/integrations/cloudbuild/chef.yaml @@ -1,5 +1,5 @@ steps: - - name: "connectedhomeip/chip-build-vscode:0.6.34" + - name: "connectedhomeip/chip-build-vscode:0.6.35" env: - PW_ENVIRONMENT_ROOT=/pwenv args: @@ -12,7 +12,7 @@ steps: path: /pwenv timeout: 2700s - - name: "connectedhomeip/chip-build-vscode:0.6.34" + - name: "connectedhomeip/chip-build-vscode:0.6.35" env: - PW_ENVIRONMENT_ROOT=/pwenv args: @@ -26,7 +26,7 @@ steps: - name: pwenv path: /pwenv - - name: "connectedhomeip/chip-build-vscode:0.6.34" + - name: "connectedhomeip/chip-build-vscode:0.6.35" env: - PW_ENVIRONMENT_ROOT=/pwenv args: diff --git a/integrations/cloudbuild/smoke-test.yaml b/integrations/cloudbuild/smoke-test.yaml index b5400057e7db54..02fb0b6601f97a 100644 --- a/integrations/cloudbuild/smoke-test.yaml +++ b/integrations/cloudbuild/smoke-test.yaml @@ -1,5 +1,5 @@ steps: - - name: "connectedhomeip/chip-build-vscode:0.6.34" + - name: "connectedhomeip/chip-build-vscode:0.6.35" entrypoint: "bash" args: - "-c" @@ -7,7 +7,7 @@ steps: git config --global --add safe.directory "*" git submodule update --init --recursive id: Submodules - - name: "connectedhomeip/chip-build-vscode:0.6.34" + - name: "connectedhomeip/chip-build-vscode:0.6.35" env: - PW_ENVIRONMENT_ROOT=/pwenv args: @@ -22,7 +22,7 @@ steps: path: /pwenv timeout: 900s - - name: "connectedhomeip/chip-build-vscode:0.6.34" + - name: "connectedhomeip/chip-build-vscode:0.6.35" id: ESP32 env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -40,7 +40,7 @@ steps: volumes: - name: pwenv path: /pwenv - - name: "connectedhomeip/chip-build-vscode:0.6.34" + - name: "connectedhomeip/chip-build-vscode:0.6.35" id: NRFConnect env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -61,7 +61,7 @@ steps: - name: pwenv path: /pwenv - - name: "connectedhomeip/chip-build-vscode:0.6.34" + - name: "connectedhomeip/chip-build-vscode:0.6.35" id: EFR32 env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -83,7 +83,7 @@ steps: - name: pwenv path: /pwenv - - name: "connectedhomeip/chip-build-vscode:0.6.34" + - name: "connectedhomeip/chip-build-vscode:0.6.35" id: Linux env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -141,7 +141,7 @@ steps: - name: pwenv path: /pwenv - - name: "connectedhomeip/chip-build-vscode:0.6.34" + - name: "connectedhomeip/chip-build-vscode:0.6.35" id: Android env: - PW_ENVIRONMENT_ROOT=/pwenv