diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index b183a1f607..e5ddee193d 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -85,7 +85,6 @@ /components/esp_https_ota/ @esp-idf-codeowners/app-utilities /components/esp_https_server/ @esp-idf-codeowners/app-utilities /components/esp_hw_support/ @esp-idf-codeowners/system -/components/esp_ipc/ @esp-idf-codeowners/system /components/esp_lcd/ @esp-idf-codeowners/peripherals /components/esp_local_ctrl/ @esp-idf-codeowners/app-utilities /components/esp_netif/ @esp-idf-codeowners/network @@ -171,11 +170,10 @@ /examples/storage/ @esp-idf-codeowners/storage /examples/system/ @esp-idf-codeowners/system /examples/wifi/ @esp-idf-codeowners/wifi +/examples/zigbee/ @esp-idf-codeowners/ieee802154 /examples/**/*.py @esp-idf-codeowners/ci @esp-idf-codeowners/tools -/make/ @esp-idf-codeowners/build-config - /tools/ @esp-idf-codeowners/tools /tools/*_apps.py @esp-idf-codeowners/ci /tools/ble/ @esp-idf-codeowners/app-utilities diff --git a/docs/en/COPYRIGHT.rst b/docs/en/COPYRIGHT.rst index 85e638e4bd..c2b58804e3 100644 --- a/docs/en/COPYRIGHT.rst +++ b/docs/en/COPYRIGHT.rst @@ -10,6 +10,8 @@ Additional third party copyrighted code is included under the following licenses Where source code headers specify Copyright & License information, this information takes precedence over the summaries made here. +Some examples use external components which are not Apache licensed, please check the copyright description in each example source code. + Firmware Components ------------------- @@ -69,7 +71,7 @@ These third party libraries can be included into the application (firmware) prod * `qrcode`_ QR Code generator library Copyright (c) Project Nayuki, is licensed under MIT license. -* :component:`openthread`, Copyright (c) The OpenThread Authors, is licensed under Apache License 2.0 as described in :component_file:`LICENSE file`. +* :component:`openthread`, Copyright (c) The OpenThread Authors, is licensed under BSD License as described in :component_file:`LICENSE file`. * :component_file:`UBSAN runtime ` — Copyright (c) 2016, Linaro Limited and Jiří Zárevúcky, licensed under the BSD 2-clause license. diff --git a/examples/zigbee/light_sample/README.md b/examples/zigbee/light_sample/README.md new file mode 100644 index 0000000000..3f1eb7a9ae --- /dev/null +++ b/examples/zigbee/light_sample/README.md @@ -0,0 +1,14 @@ +# Light Switch and Bulb Control Example + +(See the `README.md` file in the upper level 'examples' directory for more information about examples.) + +## Overview + +The folder contains examples demonstrating Zigbee Router, Coordinator, and End-Device roles + +* [light_bulb](light_bulb) is a light bulb example demonstrating Zigbee Router role. It provides a simple on/off condition for a Zigbee light. It runs on an 802.15.4 SoC like ESP32-H2. For more details see the example readme file. + +* [light_coordinator](light_coordinator) is a light coordinator example demonstrating Zigbee Coordinator role. It provides a formation of the Zigbee network. It runs on an 802.15.4 SoC like ESP32-H2. For more details to see the example readme file. + +* [light_switch](light_switch) is a light switch example demonstrating Zigbee End-Device role. It provides an on/off toggle to control light. It runs on an 802.15.4 SoC like ESP32-H2. For more details to see the example readme file. + diff --git a/examples/zigbee/light_sample/light_bulb/CMakeLists.txt b/examples/zigbee/light_sample/light_bulb/CMakeLists.txt new file mode 100644 index 0000000000..48752c3e8d --- /dev/null +++ b/examples/zigbee/light_sample/light_bulb/CMakeLists.txt @@ -0,0 +1,9 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +set(EXTRA_COMPONENT_DIRS + $ENV{IDF_PATH}/examples/common_components/led_strip + ) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(light_bulb) diff --git a/examples/zigbee/light_sample/light_bulb/README.md b/examples/zigbee/light_sample/light_bulb/README.md new file mode 100644 index 0000000000..3aae742e27 --- /dev/null +++ b/examples/zigbee/light_sample/light_bulb/README.md @@ -0,0 +1,53 @@ +| Supported Targets | ESP32-H2 | +| ----------------- | -------- | + +# Light Bulb Example + +(See the `README.md` file in the upper level 'examples' directory for more information about examples.) + +This test code shows how to configure Zigbee router device and use it as a light bulb + +## Hardware Required + +* One development board with ESP32-H2 SoC acting as Zigbee router (loaded with light bulb example) +* A USB cable for power supply and programming +* Choose another ESP32-H2 as Zigbee coordinator (see [light coordinator example](../light_coordinator)) +* Choose another ESP32-H2 as Zigbee end-device (see [light switch example](../light_switch)) + +## Configure the project + +[**Mandatory**] Download esp-zboss-lib packages from [Espressif's component serivce](https://components.espressif.com/). +You can add them to your project via `idf.py add-dependency espressif/esp-zboss-lib==0.0.2` + +Before project configuration and build, make sure to set the correct chip target using `idf.py set-target esp32h2`. + +## Build and Flash + +Build the project, flash it to the board, and start the monitor tool to view the serial output by running `idf.py -p PORT flash monitor`. + +(To exit the serial monitor, type ``Ctrl-]``.) + +## Example Output + +As you run the example, you will see the following log: + +light bulb: +I (9638) ESP_ZB_LIGHT: status: 255 +I (9638) ESP_ZB_LIGHT: Zigbee stack initialized +I (9648) ESP_ZB_LIGHT: Start network steering +I (12368) ESP_ZB_LIGHT: Joined network successfully (Extended PAN ID: f9:54:2d:01:a0:03:f7:84, PAN ID: 0xf5b5) +I (12398) ESP_ZB_LIGHT: status: 0 +I (18158) ESP_ZB_LIGHT: on/off attribute setting to 1 +I (19388) ESP_ZB_LIGHT: on/off attribute setting to 0 +I (20418) ESP_ZB_LIGHT: on/off attribute setting to 1 +I (21558) ESP_ZB_LIGHT: on/off attribute setting to 0 +I (22478) ESP_ZB_LIGHT: on/off attribute setting to 1 +I (23088) ESP_ZB_LIGHT: on/off attribute setting to 0 + +## Light Control Functions + + * By toggling the switch button (BOOT) on the ESP32-H2 board loaded with the `light switch` example, the LED on this board loaded with `light bulb` example will be on and off. + +## Troubleshooting + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/zigbee/light_sample/light_bulb/main/CMakeLists.txt b/examples/zigbee/light_sample/light_bulb/main/CMakeLists.txt new file mode 100644 index 0000000000..61bef7bbbe --- /dev/null +++ b/examples/zigbee/light_sample/light_bulb/main/CMakeLists.txt @@ -0,0 +1,6 @@ +idf_component_register( + SRCS + "esp_zb_light.c" + "light_driver.c" + INCLUDE_DIRS "." +) diff --git a/examples/zigbee/light_sample/light_bulb/main/esp_zb_light.c b/examples/zigbee/light_sample/light_bulb/main/esp_zb_light.c new file mode 100644 index 0000000000..175a14a350 --- /dev/null +++ b/examples/zigbee/light_sample/light_bulb/main/esp_zb_light.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2021 Espressif Systems (Shanghai) CO LTD + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Espressif Systems + * integrated circuit in a product or a software update for such product, + * must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * 4. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "esp_log.h" +#include "esp_zb_light.h" + +static bulb_device_ctx_t esp_light_ctx = { + /* basic cluster attributes data */ + .basic_attr.zcl_version = ZB_ZCL_VERSION, + .basic_attr.power_source = ZB_ZCL_BASIC_POWER_SOURCE_UNKNOWN, + /* identify cluster attributes data */ + .identify_attr.identify_time = 0, + /* groups cluster attributes data */ + .groups_attr.name_support = 0, + /* on/off cluster attributes data */ + .on_off_attr.on_off = ZB_ZCL_ON_OFF_IS_OFF, +}; + +static const char *TAG = "ESP_ZB_LIGHT"; +/******************* Declare attributes ************************/ + +/* basic cluster attributes data */ +ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST(basic_attr_list, + &esp_light_ctx.basic_attr.zcl_version, + &esp_light_ctx.basic_attr.power_source); + +/* identify cluster attributes data */ +ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(identify_attr_list, + &esp_light_ctx.identify_attr.identify_time); + +/* groups cluster attributes data */ +ZB_ZCL_DECLARE_GROUPS_ATTRIB_LIST(groups_attr_list, + &esp_light_ctx.groups_attr.name_support); + +/* scenes cluster attribute data */ +ZB_ZCL_DECLARE_SCENES_ATTRIB_LIST(scenes_attr_list, + &esp_light_ctx.scenes_attr.scene_count, + &esp_light_ctx.scenes_attr.current_scene, + &esp_light_ctx.scenes_attr.current_group, + &esp_light_ctx.scenes_attr.scene_valid, + &esp_light_ctx.scenes_attr.name_support); + +/* on/off cluster attributes data */ +ZB_ZCL_DECLARE_ON_OFF_ATTRIB_LIST(on_off_attr_list, + &esp_light_ctx.on_off_attr.on_off); + +/********************* Declare device **************************/ +ZB_HA_DECLARE_ON_OFF_OUTPUT_CLUSTER_LIST(custom_light_clusters, + on_off_attr_list, + basic_attr_list, + identify_attr_list, + groups_attr_list, + scenes_attr_list); + +ZB_HA_DECLARE_ON_OFF_OUTPUT_EP(custom_esp_light_ep, + HA_ESP_LIGHT_ENDPOINT, + custom_light_clusters); + +ZB_HA_DECLARE_ON_OFF_OUTPUT_CTX(esp_zb_light_ctx, + custom_esp_light_ep); + +/********************* Define functions **************************/ +static void bdb_start_top_level_commissioning_cb(zb_uint8_t mode_mask) +{ + if (!bdb_start_top_level_commissioning(mode_mask)) { + ESP_LOGE(TAG, "In BDB commissioning, an error occurred (for example: the device has already been running)"); + } +} + +/** + * @brief Zigbee zboss stack event signal handler. + * + * @param bufid Zigbee zboss stack buffer id used to pass signal. + */ +void zboss_signal_handler(zb_uint8_t bufid) +{ + zb_uint8_t status = ZB_GET_APP_SIGNAL_STATUS(bufid); + zb_zdo_app_signal_type_t sig = zb_get_app_signal(bufid, NULL); + + switch (sig) { + case ZB_ZDO_SIGNAL_SKIP_STARTUP: + ESP_LOGI(TAG, "Zigbee stack initialized"); + bdb_start_top_level_commissioning(ZB_BDB_INITIALIZATION); + break; + case ZB_BDB_SIGNAL_DEVICE_FIRST_START: + if (status == RET_OK) { + ESP_LOGI(TAG, "Start network steering"); + bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING); + } else { + ESP_LOGE(TAG, "Failed to initialize Zigbee stack (status: %d)", status); + } + break; + case ZB_BDB_SIGNAL_STEERING: + if (status == RET_OK) { + zb_ext_pan_id_t extended_pan_id; + zb_get_extended_pan_id(extended_pan_id); + ESP_LOGI(TAG, "Joined network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx)", + extended_pan_id[7], extended_pan_id[6], extended_pan_id[5], extended_pan_id[4], + extended_pan_id[3], extended_pan_id[2], extended_pan_id[1], extended_pan_id[0], + ZB_PIBCACHE_PAN_ID()); + } else { + ESP_LOGI(TAG, "Network steering was not successful (status: %d)", status); + ZB_SCHEDULE_APP_ALARM((zb_callback_t)bdb_start_top_level_commissioning_cb, ZB_BDB_NETWORK_STEERING, ZB_TIME_ONE_SECOND); + } + break; + default: + ESP_LOGI(TAG, "status: %d", status); + break; + } + if (bufid) { + zb_buf_free(bufid); + } +} + +/** + * @brief Function for turning on/off the light bulb. + * + * @param power Boolean light bulb state power on/off. + */ +static void esp_zb_light_set_value(zb_bool_t power) +{ + ZB_ZCL_SET_ATTRIBUTE(HA_ESP_LIGHT_ENDPOINT, + ZB_ZCL_CLUSTER_ID_ON_OFF, + ZB_ZCL_CLUSTER_SERVER_ROLE, + ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID, + (zb_uint8_t *)&power, + ZB_FALSE); + + light_driver_set_power(power); +} + +/** + * @brief Callback function for handling attribute value from ZCL. + * + * @param bufid Zigbee zboss stack buffer id used to pass received data. + */ +static void esp_zb_light_cb(zb_bufid_t bufid) +{ + zb_zcl_device_callback_param_t *p_device_cb_param = ZB_BUF_GET_PARAM(bufid, zb_zcl_device_callback_param_t); + zb_zcl_device_callback_id_t device_cb_id = p_device_cb_param->device_cb_id; + zb_uint16_t cluster_id = p_device_cb_param->cb_param.set_attr_value_param.cluster_id; + zb_uint16_t attr_id = p_device_cb_param->cb_param.set_attr_value_param.attr_id; + p_device_cb_param->status = RET_OK; + + switch (device_cb_id) { + /* ZCL set attribute value */ + case ZB_ZCL_SET_ATTR_VALUE_CB_ID: + if (cluster_id == ZB_ZCL_CLUSTER_ID_ON_OFF) { + uint8_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data8; + ESP_LOGI(TAG, "on/off attribute setting to %hd", value); + + if (attr_id == ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID) { + /* implemented light on/off control */ + esp_zb_light_set_value((zb_bool_t) value); + } + } else if (cluster_id == ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL) { + uint16_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data16; + ESP_LOGI(TAG, "level control attribute setting to %hd", value); + + if (attr_id == ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID) { + /* implement light level control if needed */ + } + } else if (cluster_id == ZB_ZCL_CLUSTER_ID_COLOR_CONTROL) { + uint16_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data8; + ESP_LOGI(TAG, "attribute 0x%x setting to %d", attr_id, value); + + if (attr_id == ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_HUE_ID) { + /* implement light color change if needed */ + } + } else { + /* other clusters attribute handled here */ + ESP_LOGI(TAG, "Unhandled cluster attribute id: %d", cluster_id); + } + break; + default: + p_device_cb_param->status = RET_ERROR; + break; + } +} + +void app_main() +{ + zb_ret_t zb_err_code; + zb_ieee_addr_t g_ieee_addr; + + /* initialize Zigbee stack */ + ZB_INIT("light_bulb"); + esp_read_mac(g_ieee_addr, ESP_MAC_IEEE802154); + zb_set_long_address(g_ieee_addr); + zb_set_network_router_role(IEEE_CHANNEL_MASK); + zb_set_max_children(MAX_CHILDREN); + zb_set_nvram_erase_at_start(ERASE_PERSISTENT_CONFIG); + zb_set_keepalive_timeout(ZB_MILLISECONDS_TO_BEACON_INTERVAL(3000)); + /* hardware related and device init */ + light_driver_init(LIGHT_DEFAULT_OFF); + /* register callback for handling ZCL commands */ + ZB_ZCL_REGISTER_DEVICE_CB(esp_zb_light_cb); + /* register light device context (endpoints) */ + ZB_AF_REGISTER_DEVICE_CTX(&esp_zb_light_ctx); + zb_err_code = zboss_start_no_autostart(); + ESP_ERROR_CHECK(zb_err_code); + + while (1) { + zboss_main_loop_iteration(); + } +} diff --git a/examples/zigbee/light_sample/light_bulb/main/esp_zb_light.h b/examples/zigbee/light_sample/light_bulb/main/esp_zb_light.h new file mode 100644 index 0000000000..5492510253 --- /dev/null +++ b/examples/zigbee/light_sample/light_bulb/main/esp_zb_light.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2021 Espressif Systems (Shanghai) CO LTD + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Espressif Systems + * integrated circuit in a product or a software update for such product, + * must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * 4. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "light_driver.h" +#include "zboss_api.h" + +/* Zigbee configuration */ +#define IEEE_CHANNEL_MASK (1l << 13) /* Zigbee default setting is channel 13 for light example usage */ +#define ERASE_PERSISTENT_CONFIG ZB_TRUE /* erase network devices before running example */ +#define MAX_CHILDREN 10 /* the max amount of connected devices */ + +/* groups cluster attributes */ +typedef struct { + zb_uint8_t name_support; +} zb_zcl_groups_attrs_t; + +/* scene cluster attributes */ +typedef struct { + zb_uint8_t scene_count; + zb_uint8_t current_scene; + zb_uint8_t scene_valid; + zb_uint8_t name_support; + zb_uint16_t current_group; +} zb_zcl_scenes_attrs_t; + +/* light bulb device cluster attributes */ +typedef struct { + zb_zcl_basic_attrs_t basic_attr; + zb_zcl_identify_attrs_t identify_attr; + zb_zcl_groups_attrs_t groups_attr; + zb_zcl_scenes_attrs_t scenes_attr; + zb_zcl_on_off_attrs_t on_off_attr; +} bulb_device_ctx_t; + +#define HA_ESP_LIGHT_ENDPOINT 10 /* esp light bulb device endpoint, used to process light controlling commands */ diff --git a/examples/zigbee/light_sample/light_bulb/main/light_driver.c b/examples/zigbee/light_sample/light_bulb/main/light_driver.c new file mode 100644 index 0000000000..3436ec8803 --- /dev/null +++ b/examples/zigbee/light_sample/light_bulb/main/light_driver.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 Espressif Systems (Shanghai) CO LTD + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Espressif Systems + * integrated circuit in a product or a software update for such product, + * must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * 4. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "light_driver.h" +#include "led_strip.h" +#include "esp_log.h" + +static led_strip_t *led_strip; + +void light_driver_set_power(bool power) +{ + ESP_ERROR_CHECK(led_strip->set_pixel(led_strip, 0, 255 * power, 255 * power, 255 * power)); + ESP_ERROR_CHECK(led_strip->refresh(led_strip, 100)); +} + +int light_driver_init(bool power) +{ + led_strip = led_strip_init(RMT_TX_CHANNEL, CONFIG_EXAMPLE_RMT_TX_GPIO, CONFIG_EXAMPLE_STRIP_LED_NUMBER); + light_driver_set_power(power); + return ESP_OK; +} diff --git a/examples/zigbee/light_sample/light_bulb/main/light_driver.h b/examples/zigbee/light_sample/light_bulb/main/light_driver.h new file mode 100644 index 0000000000..fc56c6244e --- /dev/null +++ b/examples/zigbee/light_sample/light_bulb/main/light_driver.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021 Espressif Systems (Shanghai) CO LTD + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Espressif Systems + * integrated circuit in a product or a software update for such product, + * must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * 4. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + + +#include "driver/rmt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* light intensity level */ +#define LIGHT_DEFAULT_ON 1 +#define LIGHT_DEFAULT_OFF 0 + +/* LED strip configuration */ +#define RMT_TX_CHANNEL RMT_CHANNEL_0 +#define CONFIG_EXAMPLE_RMT_TX_GPIO 8 +#define CONFIG_EXAMPLE_STRIP_LED_NUMBER 1 + +/** + * @brief Set light power (on/off). + * + * @param power The light power to be set +*/ +void light_driver_set_power(bool power); + +/** + * @brief color light driver init, be invoked where you want to use color light + * + * @param power power on/off +*/ +int light_driver_init(bool power); + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/examples/zigbee/light_sample/light_bulb/partitions.csv b/examples/zigbee/light_sample/light_bulb/partitions.csv new file mode 100644 index 0000000000..30e8c9e132 --- /dev/null +++ b/examples/zigbee/light_sample/light_bulb/partitions.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 1M, +zb_storage, data, fat, , 128K, diff --git a/examples/zigbee/light_sample/light_bulb/sdkconfig.defaults b/examples/zigbee/light_sample/light_bulb/sdkconfig.defaults new file mode 100644 index 0000000000..1fa4e7a917 --- /dev/null +++ b/examples/zigbee/light_sample/light_bulb/sdkconfig.defaults @@ -0,0 +1,42 @@ +CONFIG_IDF_TARGET="esp32h2" + +# +# libsodium +# +CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y +# end of libsodium + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# mbedTLS +# +CONFIG_MBEDTLS_HARDWARE_AES=n +CONFIG_MBEDTLS_HARDWARE_MPI=n +CONFIG_MBEDTLS_HARDWARE_SHA=n +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_SSL_PROTO_DTLS=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_ECJPAKE_C=y +# end of mbedTLS + +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=n + +# +# Zboss +# +CONFIG_ZB_ENABLED=y +CONFIG_ZB_ZCZR=y +# end of Zboss +# end of Component config diff --git a/examples/zigbee/light_sample/light_coordinator/CMakeLists.txt b/examples/zigbee/light_sample/light_coordinator/CMakeLists.txt new file mode 100644 index 0000000000..b288178e00 --- /dev/null +++ b/examples/zigbee/light_sample/light_coordinator/CMakeLists.txt @@ -0,0 +1,5 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(light_coordinator) diff --git a/examples/zigbee/light_sample/light_coordinator/README.md b/examples/zigbee/light_sample/light_coordinator/README.md new file mode 100644 index 0000000000..54f6f92a95 --- /dev/null +++ b/examples/zigbee/light_sample/light_coordinator/README.md @@ -0,0 +1,56 @@ +| Supported Targets | ESP32-H2 | +| ----------------- | -------- | + +# Light Coordinator Example + +(See the `README.md` file in the upper level 'examples' directory for more information about examples.) + +This test code shows how to configure Zigbee coordinator device. + +## Hardware Required + +* One development board with ESP32-H2 SoC acting as Zigbee coordinator (loaded with light coordinator example) +* A USB cable for power supply and programming +* Choose another ESP32-H2 as Zigbee router (see [light bulb example](../light_bulb)) +* Choose another ESP32-H2 as Zigbee end-device (see [light switch example](../light_switch)) + +## Configure the project + +[**Mandatory**] Download esp-zboss-lib packages from [Espressif's component serivce](https://components.espressif.com/). +You can add them to your project via `idf.py add-dependency espressif/esp-zboss-lib==0.0.2` + +Before project configuration and build, make sure to set the correct chip target using `idf.py set-target esp32h2`. + +## Build and Flash + +Build the project, flash it to the board, and start the monitor tool to view the serial output by running `idf.py -p PORT flash monitor`. + +(To exit the serial monitor, type ``Ctrl-]``.) + +## Example Output + +As you run the example, you will see the following log: + +light coodrinator: +I (9556) ESP_ZB_COORDINATOR: status: -1 +I (9556) ESP_ZB_COORDINATOR: Zigbee stack initialized +I (9556) ESP_ZB_COORDINATOR: Start network formation +I (10066) ESP_ZB_COORDINATOR: Joined network successfully (Extended PAN ID: f9:54:2d:01:a0:03:f7:84, PAN ID: 0xf5b5) +I (10526) ESP_ZB_COORDINATOR: Network steering started +I (11306) ESP_ZB_COORDINATOR: status: 0 +I (11806) ESP_ZB_COORDINATOR: status: 0 +I (11886) ESP_ZB_COORDINATOR: New device commissioned or rejoined (short: 0x434a) +I (12386) ESP_ZB_COORDINATOR: status: 0 +I (12486) ESP_ZB_COORDINATOR: status: 0 +I (12896) ESP_ZB_COORDINATOR: status: 0 +I (12946) ESP_ZB_COORDINATOR: New device commissioned or rejoined (short: 0x09c2) +I (13516) ESP_ZB_COORDINATOR: status: 0 +I (26686) ESP_ZB_COORDINATOR: status: 0 + +## Light Control Functions + + * By toggling the switch button (BOOT) on the ESP32-H2 board loaded with `light switch` example, the LED on the board loaded with `light bulb` example will be on and off. + +## Troubleshooting + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/zigbee/light_sample/light_coordinator/main/CMakeLists.txt b/examples/zigbee/light_sample/light_coordinator/main/CMakeLists.txt new file mode 100644 index 0000000000..083b194144 --- /dev/null +++ b/examples/zigbee/light_sample/light_coordinator/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "esp_zb_coordinator.c" + INCLUDE_DIRS ".") diff --git a/examples/zigbee/light_sample/light_coordinator/main/esp_zb_coordinator.c b/examples/zigbee/light_sample/light_coordinator/main/esp_zb_coordinator.c new file mode 100644 index 0000000000..fb1721fb3f --- /dev/null +++ b/examples/zigbee/light_sample/light_coordinator/main/esp_zb_coordinator.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2021 Espressif Systems (Shanghai) CO LTD + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Espressif Systems + * integrated circuit in a product or a software update for such product, + * must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * 4. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "esp_zb_coordinator.h" +#include "esp_log.h" + +static const char *TAG = "ESP_ZB_COORDINATOR"; + +/********************* Define functions **************************/ +static void bdb_start_top_level_commissioning_cb(zb_uint8_t mode_mask) +{ + if (!bdb_start_top_level_commissioning(mode_mask)) { + ESP_LOGE(TAG, "In BDB commissioning, an error occurred (for example: the device has already been running)"); + } +} + +/** + * @brief Zigbee zboss stack event signal handler. + * + * @param bufid Zigbee zboss stack buffer id used to pass signal. + */ +void zboss_signal_handler(zb_bufid_t bufid) +{ + /* Read signal description out of memory buffer. */ + zb_zdo_app_signal_hdr_t *p_sg_p = NULL; + zb_zdo_app_signal_type_t sig = zb_get_app_signal(bufid, &p_sg_p); + zb_ret_t status = ZB_GET_APP_SIGNAL_STATUS(bufid); + + switch (sig) { + case ZB_ZDO_SIGNAL_SKIP_STARTUP: + ESP_LOGI(TAG, "Zigbee stack initialized"); + bdb_start_top_level_commissioning(ZB_BDB_INITIALIZATION); + break; + + case ZB_BDB_SIGNAL_DEVICE_FIRST_START: + if (status == RET_OK) { + ESP_LOGI(TAG, "Start network formation"); + bdb_start_top_level_commissioning(ZB_BDB_NETWORK_FORMATION); + } else { + ESP_LOGE(TAG, "Failed to initialize Zigbee stack (status: %d)", status); + } + break; + + case ZB_BDB_SIGNAL_FORMATION: + if (status == RET_OK) { + zb_ext_pan_id_t extended_pan_id; + zb_get_extended_pan_id(extended_pan_id); + ESP_LOGI(TAG, "Joined network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx)", + extended_pan_id[7], extended_pan_id[6], extended_pan_id[5], extended_pan_id[4], + extended_pan_id[3], extended_pan_id[2], extended_pan_id[1], extended_pan_id[0], + ZB_PIBCACHE_PAN_ID()); + bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING); + } else { + ESP_LOGI(TAG, "Restart network formation (status: %d)", status); + ZB_SCHEDULE_APP_ALARM((zb_callback_t)bdb_start_top_level_commissioning_cb, ZB_BDB_NETWORK_FORMATION, ZB_TIME_ONE_SECOND); + } + break; + + case ZB_BDB_SIGNAL_STEERING: + if (status == RET_OK) { + ESP_LOGI(TAG, "Network steering started"); + } + break; + + case ZB_ZDO_SIGNAL_DEVICE_ANNCE: { + zb_zdo_signal_device_annce_params_t *dev_annce_params = ZB_ZDO_SIGNAL_GET_PARAMS(p_sg_p, zb_zdo_signal_device_annce_params_t); + ESP_LOGI(TAG, "New device commissioned or rejoined (short: 0x%04hx)", dev_annce_params->device_short_addr); + } + break; + default: + ESP_LOGI(TAG, "status: %d", status); + break; + } + /* All callbacks should either reuse or free passed buffers. If bufid == 0, the buffer is invalid (not passed) */ + if (bufid) { + zb_buf_free(bufid); + } +} + +void app_main() +{ + zb_ret_t zb_err_code; + zb_ieee_addr_t g_ieee_addr; + + /* initialize Zigbee stack */ + ZB_INIT("light_coordinator"); + esp_read_mac(g_ieee_addr, ESP_MAC_IEEE802154); + zb_set_long_address(g_ieee_addr); + zb_set_network_coordinator_role(IEEE_CHANNEL_MASK); + zb_set_nvram_erase_at_start(ERASE_PERSISTENT_CONFIG); + zb_set_max_children(MAX_CHILDREN); + zb_err_code = zboss_start_no_autostart(); + ESP_ERROR_CHECK(zb_err_code); + + while (1) { + zboss_main_loop_iteration(); + } +} diff --git a/examples/zigbee/light_sample/light_coordinator/main/esp_zb_coordinator.h b/examples/zigbee/light_sample/light_coordinator/main/esp_zb_coordinator.h new file mode 100644 index 0000000000..2b8fbd0d0e --- /dev/null +++ b/examples/zigbee/light_sample/light_coordinator/main/esp_zb_coordinator.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 Espressif Systems (Shanghai) CO LTD + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Espressif Systems + * integrated circuit in a product or a software update for such product, + * must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * 4. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "zboss_api.h" +#include "esp_err.h" + +/* Zigbee Configuration */ +#define IEEE_CHANNEL_MASK (1l << 13) /* ZigBee default setting is channel 13 for light example usage */ +#define ERASE_PERSISTENT_CONFIG ZB_TRUE /* erase network devices before running example */ +#define MAX_CHILDREN 10 /* the max amount of connected devices */ diff --git a/examples/zigbee/light_sample/light_coordinator/partitions.csv b/examples/zigbee/light_sample/light_coordinator/partitions.csv new file mode 100644 index 0000000000..30e8c9e132 --- /dev/null +++ b/examples/zigbee/light_sample/light_coordinator/partitions.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 1M, +zb_storage, data, fat, , 128K, diff --git a/examples/zigbee/light_sample/light_coordinator/sdkconfig.defaults b/examples/zigbee/light_sample/light_coordinator/sdkconfig.defaults new file mode 100644 index 0000000000..1fa4e7a917 --- /dev/null +++ b/examples/zigbee/light_sample/light_coordinator/sdkconfig.defaults @@ -0,0 +1,42 @@ +CONFIG_IDF_TARGET="esp32h2" + +# +# libsodium +# +CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y +# end of libsodium + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# mbedTLS +# +CONFIG_MBEDTLS_HARDWARE_AES=n +CONFIG_MBEDTLS_HARDWARE_MPI=n +CONFIG_MBEDTLS_HARDWARE_SHA=n +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_SSL_PROTO_DTLS=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_ECJPAKE_C=y +# end of mbedTLS + +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=n + +# +# Zboss +# +CONFIG_ZB_ENABLED=y +CONFIG_ZB_ZCZR=y +# end of Zboss +# end of Component config diff --git a/examples/zigbee/light_sample/light_switch/CMakeLists.txt b/examples/zigbee/light_sample/light_switch/CMakeLists.txt new file mode 100644 index 0000000000..5d38697d00 --- /dev/null +++ b/examples/zigbee/light_sample/light_switch/CMakeLists.txt @@ -0,0 +1,5 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(light_switch) diff --git a/examples/zigbee/light_sample/light_switch/README.md b/examples/zigbee/light_sample/light_switch/README.md new file mode 100644 index 0000000000..4f40b13430 --- /dev/null +++ b/examples/zigbee/light_sample/light_switch/README.md @@ -0,0 +1,55 @@ +| Supported Targets | ESP32-H2 | +| ----------------- | -------- | + +# Light Switch Example + +(See the `README.md` file in the upper level 'examples' directory for more information about examples.) + +This test code shows how to configure Zigbee end device and use it as a light switch + +## Hardware Required + +* One development board with ESP32-H2 SoC acting as Zigbee end device (loaded with light switch example) +* A USB cable for power supply and programming +* Choose another ESP32-H2 as Zigbee coordinator (see [light coordinator example](../light_coordinator)) +* Choose another ESP32-H2 as Zigbee router (see [light bulb example](../light_bulb)) + +## Configure the project + +[**Mandatory**] Download esp-zboss-lib packages from [Espressif's component serivce](https://components.espressif.com/). +You can add them to your project via `idf.py add-dependency espressif/esp-zboss-lib==0.0.2` + +Before project configuration and build, make sure to set the correct chip target using `idf.py set-target esp32h2`. + +## Build and Flash + +Build the project, flash it to the board, and start the monitor tool to view the serial output by running `idf.py -p PORT flash monitor`. + +(To exit the serial monitor, type ``Ctrl-]``.) + +## Example Output + +As you run the example, you will see the following log: + +light switch: +I (9423) gpio: GPIO[9]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:2 +I (9523) ESP_ZB_SWITCH: status: -1 +I (9523) ESP_ZB_SWITCH: Zigbee stack initialized +I (9523) ESP_ZB_SWITCH: Start network steering +I (11263) ESP_ZB_SWITCH: Joined network successfully (Extended PAN ID: f9:54:2d:01:a0:03:f7:84, PAN ID: 0xf5b5) +I (13433) ESP_ZB_SWITCH: Found bulb addr: 0x434a ep: 10 +I (16433) ESP_ZB_SWITCH: Send ON/OFF toggle command +I (17663) ESP_ZB_SWITCH: Send ON/OFF toggle command +I (18693) ESP_ZB_SWITCH: Send ON/OFF toggle command +I (19833) ESP_ZB_SWITCH: Send ON/OFF toggle command +I (20753) ESP_ZB_SWITCH: Send ON/OFF toggle command +I (21363) ESP_ZB_SWITCH: Send ON/OFF toggle command + +## Light Control Functions + + * By toggling the switch button (BOOT) on this board, the LED on the board loaded with the `light bulb` example will be on and off. + + +## Troubleshooting + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/zigbee/light_sample/light_switch/main/CMakeLists.txt b/examples/zigbee/light_sample/light_switch/main/CMakeLists.txt new file mode 100644 index 0000000000..b996c0f78a --- /dev/null +++ b/examples/zigbee/light_sample/light_switch/main/CMakeLists.txt @@ -0,0 +1,6 @@ +idf_component_register( + SRCS + "esp_zb_switch.c" + "switch_driver.c" + INCLUDE_DIRS "." +) diff --git a/examples/zigbee/light_sample/light_switch/main/esp_zb_switch.c b/examples/zigbee/light_sample/light_switch/main/esp_zb_switch.c new file mode 100644 index 0000000000..925a0740e3 --- /dev/null +++ b/examples/zigbee/light_sample/light_switch/main/esp_zb_switch.c @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2021 Espressif Systems (Shanghai) CO LTD + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Espressif Systems + * integrated circuit in a product or a software update for such product, + * must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * 4. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "esp_zb_switch.h" +#include "esp_log.h" + +/** + * @note Make sure set idf.py menuconfig in zigbee component as zigbee end device! +*/ +#if !defined ZB_ED_ROLE +#error Define ZB_ED_ROLE in idf.py menuconfig to compile light switch (End Device) source code. +#endif + +/* define Button function currently only 1 switch define */ +static switch_func_pair_t button_func_pair[] = { + {GPIO_INPUT_IO_TOGGLE_SWITCH, SWITCH_ONOFF_TOGGLE_CONTROL} +}; + +static switch_device_ctx_t esp_switch_ctx = { + /* basic cluster attributes data */ + .basic_attr.zcl_version = ZB_ZCL_VERSION, + .basic_attr.power_source = ZB_ZCL_BASIC_POWER_SOURCE_UNKNOWN, + /* identify cluster attributes data */ + .identify_attr.identify_time = 0, + /* On_Off cluster attributes data */ + .on_off_attr.on_off = 0, + /* bulb parameters */ + .bulb_params.short_addr = 0xffff, +}; + +static const char *TAG = "ESP_ZB_SWITCH"; +/******************* Declare attributes ************************/ + +/* basic cluster attributes data */ +ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST(basic_attr_list, + &esp_switch_ctx.basic_attr.zcl_version, + &esp_switch_ctx.basic_attr.power_source); + +/* identify cluster attributes data */ +ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(identify_attr_list, + &esp_switch_ctx.identify_attr.identify_time); + +/* switch config cluster attributes data */ +zb_uint8_t attr_switch_type = + ZB_ZCL_ON_OFF_SWITCH_CONFIGURATION_SWITCH_TYPE_TOGGLE; +zb_uint8_t attr_switch_actions = + ZB_ZCL_ON_OFF_SWITCH_CONFIGURATION_SWITCH_ACTIONS_DEFAULT_VALUE; + +ZB_ZCL_DECLARE_ON_OFF_SWITCH_CONFIGURATION_ATTRIB_LIST(switch_cfg_attr_list, &attr_switch_type, &attr_switch_actions); + +/********************* Declare device **************************/ + +ZB_HA_DECLARE_ON_OFF_SWITCH_CLUSTER_LIST(on_off_switch_clusters, switch_cfg_attr_list, basic_attr_list, identify_attr_list); + +ZB_HA_DECLARE_ON_OFF_SWITCH_EP(on_off_switch_ep, HA_ONOFF_SWITCH_ENDPOINT, on_off_switch_clusters); + +ZB_HA_DECLARE_ON_OFF_SWITCH_CTX(on_off_switch_ctx, on_off_switch_ep); + +static void esp_zb_find_light_bulb_cb(zb_bufid_t bufid); + +/********************* Define functions **************************/ +/** + * @brief return true is switch find bulb + */ +static bool esp_zb_already_find_light_bulb(void) +{ + return !(esp_switch_ctx.bulb_params.short_addr == 0xffff); +} + +/** + * @brief Function for sending on/off and Level Control find request. + * + * @param bufid Zigbee zboss stack buffer id will be used to construct find request. + */ +static void esp_zb_find_light_bulb(zb_bufid_t bufid) +{ + zb_zdo_match_desc_param_t *p_req; + + /* initialize pointers inside buffer and reserve space for zb_zdo_match_desc_param_t request */ + p_req = zb_buf_initial_alloc(bufid, sizeof(zb_zdo_match_desc_param_t) + (1) * sizeof(zb_uint16_t)); + p_req->nwk_addr = MATCH_DESC_REQ_ROLE; /* send to devices specified by MATCH_DESC_REQ_ROLE */ + p_req->addr_of_interest = MATCH_DESC_REQ_ROLE; /* get responses from devices specified by MATCH_DESC_REQ_ROLE */ + p_req->profile_id = ZB_AF_HA_PROFILE_ID; /* look for Home Automation profile clusters */ + + /* we are searching for 1 cluster: + on/off + */ + p_req->num_in_clusters = 1; + p_req->num_out_clusters = 0; + p_req->cluster_list[0] = ZB_ZCL_CLUSTER_ID_ON_OFF; + /* set 0xFFFF to reset short address in order to parse only one response. */ + esp_switch_ctx.bulb_params.short_addr = 0xFFFF; + zb_zdo_match_desc_req(bufid, esp_zb_find_light_bulb_cb); +} + +/** + * @brief Finding procedure timeout handler. + * + * @param bufid Zigbee zboss stack buffer id will be used to construct find request. + */ +static void esp_zb_find_light_bulb_timeout(zb_bufid_t bufid) +{ + zb_ret_t zb_err_code; + + if (bufid) { + ESP_LOGW(TAG, "Bulb not found, try again"); + zb_err_code = ZB_SCHEDULE_APP_ALARM(esp_zb_find_light_bulb, bufid, MATCH_DESC_REQ_START_DELAY); + ESP_ERROR_CHECK(zb_err_code); + zb_err_code = ZB_SCHEDULE_APP_ALARM(esp_zb_find_light_bulb_timeout, 0, MATCH_DESC_REQ_TIMEOUT); + ESP_ERROR_CHECK(zb_err_code); + } else { + zb_err_code = zb_buf_get_out_delayed(esp_zb_find_light_bulb_timeout); + ESP_ERROR_CHECK(zb_err_code); + } +} + +/** + * @brief Callback function receiving finding procedure results. + * + * @param bufid Zigbee zboss stack buffer id is used to pass received data. + */ +static void esp_zb_find_light_bulb_cb(zb_bufid_t bufid) +{ + zb_zdo_match_desc_resp_t *p_resp = (zb_zdo_match_desc_resp_t *) zb_buf_begin(bufid); /* get the beginning of the response */ + zb_apsde_data_indication_t *p_ind = ZB_BUF_GET_PARAM(bufid, zb_apsde_data_indication_t); /* get the pointer to the parameters buffer, which stores APS layer response */ + zb_uint8_t *p_match_ep; + zb_ret_t zb_err_code; + + if ((p_resp->status == ZB_ZDP_STATUS_SUCCESS) && (p_resp->match_len > 0) && (esp_switch_ctx.bulb_params.short_addr == 0xFFFF)) { + /* match EP list follows right after response header */ + p_match_ep = (zb_uint8_t *)(p_resp + 1); + + /* We are searching for exact cluster, so only 1 EP may be found */ + esp_switch_ctx.bulb_params.endpoint = *p_match_ep; + esp_switch_ctx.bulb_params.short_addr = p_ind->src_addr; + + ESP_LOGI(TAG, "Found bulb addr: 0x%x ep: %d", esp_switch_ctx.bulb_params.short_addr, esp_switch_ctx.bulb_params.endpoint); + zb_err_code = ZB_SCHEDULE_APP_ALARM_CANCEL(esp_zb_find_light_bulb_timeout, ZB_ALARM_ANY_PARAM); + ESP_ERROR_CHECK(zb_err_code); + } + if (bufid) { + zb_buf_free(bufid); + } +} + +/** + * @brief Function for sending on/off Toggle requests to the light bulb. + * + * @param bufid Zigbee zboss stack buffer id will be used to construct on/off request. + * @param on_off_toggle unused value. + */ +static void esp_zb_light_switch_send_on_off_toggle(zb_bufid_t bufid, zb_uint16_t on_off_toggle) +{ + static zb_uint8_t cmd_id = ZB_ZCL_CMD_ON_OFF_TOGGLE_ID; + + ESP_LOGI(TAG, "Send ON/OFF toggle command"); + ZB_ZCL_ON_OFF_SEND_REQ(bufid, + esp_switch_ctx.bulb_params.short_addr, + ZB_APS_ADDR_MODE_16_ENDP_PRESENT, + esp_switch_ctx.bulb_params.endpoint, + HA_ONOFF_SWITCH_ENDPOINT, + ZB_AF_HA_PROFILE_ID, + ZB_ZCL_DISABLE_DEFAULT_RESPONSE, + cmd_id, + NULL); +} + +/** + * @brief Callback for button events, currently only toggle event available + * + * @param button_func_pair Incoming event from the button_pair. + */ +static void esp_zb_buttons_handler(switch_func_pair_t button_func_pair) +{ + zb_ret_t zb_err_code = ESP_OK; + + if (!esp_zb_already_find_light_bulb()) { + /* no bulb found yet */ + return; + } + if (button_func_pair.func == SWITCH_ONOFF_TOGGLE_CONTROL) { + /* implemented light switch toggle functionality */ + zb_err_code = zb_buf_get_out_delayed_ext(esp_zb_light_switch_send_on_off_toggle, 0, 0); + } + ESP_ERROR_CHECK(zb_err_code); +} + +static void bdb_start_top_level_commissioning_cb(zb_uint8_t mode_mask) +{ + if (!bdb_start_top_level_commissioning(mode_mask)) { + ESP_LOGE(TAG, "In BDB commissioning, an error occurred (for example: the device has already been running)"); + } +} + +/** + * @brief Zigbee zboss stack event signal handler. + * + * @param bufid Zigbee zboss stack buffer id used to pass signal. + */ +void zboss_signal_handler(zb_uint8_t bufid) +{ + zb_zdo_app_signal_hdr_t *p_sg_p = NULL; + zb_zdo_app_signal_type_t sig = zb_get_app_signal(bufid, &p_sg_p); + zb_ret_t status = ZB_GET_APP_SIGNAL_STATUS(bufid); + zb_ret_t zb_err_code; + + switch (sig) { + case ZB_ZDO_SIGNAL_SKIP_STARTUP: + ESP_LOGI(TAG, "Zigbee stack initialized"); + bdb_start_top_level_commissioning(ZB_BDB_INITIALIZATION); + break; + case ZB_BDB_SIGNAL_DEVICE_FIRST_START: + if (status == RET_OK) { + ESP_LOGI(TAG, "Start network steering"); + bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING); + } else { + ESP_LOGE(TAG, "Failed to initialize Zigbee stack (status: %d)", status); + } + break; + case ZB_BDB_SIGNAL_STEERING: + if (status == RET_OK) { + zb_ext_pan_id_t extended_pan_id; + zb_get_extended_pan_id(extended_pan_id); + ESP_LOGI(TAG, "Joined network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx)", + extended_pan_id[7], extended_pan_id[6], extended_pan_id[5], extended_pan_id[4], + extended_pan_id[3], extended_pan_id[2], extended_pan_id[1], extended_pan_id[0], + ZB_PIBCACHE_PAN_ID()); + /* check the light device address */ + if (!esp_zb_already_find_light_bulb()) { + zb_err_code = ZB_SCHEDULE_APP_ALARM(esp_zb_find_light_bulb, bufid, MATCH_DESC_REQ_START_DELAY); + ESP_ERROR_CHECK(zb_err_code); + zb_err_code = ZB_SCHEDULE_APP_ALARM(esp_zb_find_light_bulb_timeout, 0, MATCH_DESC_REQ_TIMEOUT); + ESP_ERROR_CHECK(zb_err_code); + bufid = 0; /* Do not free buffer - it will be reused by find_light_bulb callback */ + } + } else { + ESP_LOGI(TAG, "Network steering was not successful (status: %d)", status); + ZB_SCHEDULE_APP_ALARM((zb_callback_t)bdb_start_top_level_commissioning_cb, ZB_BDB_NETWORK_STEERING, ZB_TIME_ONE_SECOND); + } + break; + default: + ESP_LOGI(TAG, "status: %d", status); + break; + } + if (bufid) { + zb_buf_free(bufid); + } +} + +void app_main() +{ + zb_ret_t zb_err_code; + zb_ieee_addr_t g_ieee_addr; + + /* initialize Zigbee stack */ + ZB_INIT("light_switch"); + esp_read_mac(g_ieee_addr, ESP_MAC_IEEE802154); + zb_set_long_address(g_ieee_addr); + zb_set_network_ed_role(IEEE_CHANNEL_MASK); + zb_set_nvram_erase_at_start(ERASE_PERSISTENT_CONFIG); + zb_set_ed_timeout(ED_AGING_TIMEOUT_64MIN); + zb_set_keepalive_timeout(ZB_MILLISECONDS_TO_BEACON_INTERVAL(3000)); + /* hardware related and device init */ + switch_driver_init(button_func_pair, PAIR_SIZE(button_func_pair), esp_zb_buttons_handler); + /* register on_off switch device context (endpoints) */ + ZB_AF_REGISTER_DEVICE_CTX(&on_off_switch_ctx); + zb_err_code = zboss_start_no_autostart(); + ESP_ERROR_CHECK(zb_err_code); + + while (1) { + zboss_main_loop_iteration(); + } +} diff --git a/examples/zigbee/light_sample/light_switch/main/esp_zb_switch.h b/examples/zigbee/light_sample/light_switch/main/esp_zb_switch.h new file mode 100644 index 0000000000..61422597a8 --- /dev/null +++ b/examples/zigbee/light_sample/light_switch/main/esp_zb_switch.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 Espressif Systems (Shanghai) CO LTD + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Espressif Systems + * integrated circuit in a product or a software update for such product, + * must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * 4. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "switch_driver.h" +#include "zboss_api.h" + +/* Zigbee configuration */ +#define IEEE_CHANNEL_MASK (1l << 13) /* ZigBee default setting is channel 13 for light example usage */ +#define ERASE_PERSISTENT_CONFIG ZB_TRUE /* erase network devices before running example */ + +/* ZCL configuration */ +#define HA_ONOFF_SWITCH_ENDPOINT 1 +#define MATCH_DESC_REQ_START_DELAY (2 * ZB_TIME_ONE_SECOND) /* time delay between the light switch startup and light finding procedure */ +#define MATCH_DESC_REQ_TIMEOUT (5 * ZB_TIME_ONE_SECOND) /* timeout for finding bulb */ +#define MATCH_DESC_REQ_ROLE ZB_NWK_BROADCAST_RX_ON_WHEN_IDLE /* find non-sleep Zigbee device */ + +typedef struct light_switch_bulb_params_s { + zb_uint8_t endpoint; + zb_uint16_t short_addr; +} light_switch_bulb_params_t; + +/* light switch device cluster attributes */ +typedef struct { + zb_zcl_basic_attrs_t basic_attr; + zb_zcl_identify_attrs_t identify_attr; + zb_zcl_on_off_attrs_t on_off_attr; + light_switch_bulb_params_t bulb_params; +} switch_device_ctx_t; diff --git a/examples/zigbee/light_sample/light_switch/main/switch_driver.c b/examples/zigbee/light_sample/light_switch/main/switch_driver.c new file mode 100644 index 0000000000..be6a472212 --- /dev/null +++ b/examples/zigbee/light_sample/light_switch/main/switch_driver.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2021 Espressif Systems (Shanghai) CO LTD + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Espressif Systems + * integrated circuit in a product or a software update for such product, + * must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * 4. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "switch_driver.h" +#include +#include +#include "freertos/queue.h" +#include "esp_log.h" + +/** + * @brief: + * This example code shows how to configure light switch with attribute as well as button switch handler. + * + * @note: + Currently only support toggle switch functionality available + * + * @note: + * For other possible switch functions (on/off,level up/down,step up/down). User need to implement and create them by themselves + */ + +static xQueueHandle gpio_evt_queue = NULL; +/* button function pair, should be defined in switch example source file */ +static switch_func_pair_t *switch_func_pair; +/* call back function pointer */ +static esp_switch_callback_t func_ptr; +/* which button is pressed */ +static uint8_t switch_num; +static const char *TAG = "ESP_ZB_SWITCH"; + +static void IRAM_ATTR gpio_isr_handler(void *arg) +{ + xQueueSendFromISR(gpio_evt_queue, (switch_func_pair_t *)arg, NULL); +} + +/** + * @brief Enable GPIO (switchs refer to) isr + * + * @param enabled enable isr if true. + */ +static void switch_driver_gpios_intr_enabled(bool enabled) +{ + for (int i = 0; i < switch_num; ++i) { + if (enabled) { + gpio_intr_enable((switch_func_pair + i)->pin); + } else { + gpio_intr_disable((switch_func_pair + i)->pin); + } + } +} + +/** + * @brief Tasks for checking the button event and debounce the switch state + * + * @param arg Unused value. + */ +static void switch_driver_button_detected(void *arg) +{ + gpio_num_t io_num = GPIO_NUM_NC; + switch_func_pair_t button_func_pair; + static switch_state_t switch_state = SWITCH_IDLE; + bool evt_flag = false; + + for (;;) { + /* check if there is any queue received, if yes read out the button_func_pair */ + if (xQueueReceive(gpio_evt_queue, &button_func_pair, portMAX_DELAY)) { + io_num = button_func_pair.pin; + switch_driver_gpios_intr_enabled(false); + evt_flag = true; + } + while (evt_flag) { + bool value = gpio_get_level(io_num); + switch (switch_state) { + case SWITCH_IDLE: + switch_state = (value == GPIO_INPUT_LEVEL_ON) ? SWITCH_PRESS_DETECTED : SWITCH_IDLE; + break; + case SWITCH_PRESS_DETECTED: + switch_state = (value == GPIO_INPUT_LEVEL_ON) ? SWITCH_PRESS_DETECTED : SWITCH_RELEASE_DETECTED; + break; + case SWITCH_RELEASE_DETECTED: + switch_state = SWITCH_IDLE; + /* callback to button_handler */ + (*func_ptr)(button_func_pair); + break; + default: + break; + } + if (switch_state == SWITCH_IDLE) { + switch_driver_gpios_intr_enabled(true); + evt_flag = false; + break; + } + vTaskDelay(10 / portTICK_RATE_MS); + } + } +} + +/** + * @brief init GPIO configuration as well as isr + * + * @param button_func_pair pointer of the button pair. + * @param button_num number of button pair. + */ +static bool switch_driver_gpio_init(switch_func_pair_t *button_func_pair, uint8_t button_num) +{ + gpio_config_t io_conf = {}; + switch_func_pair = button_func_pair; + switch_num = button_num; + uint64_t pin_bit_mask = 0; + + /* set up button func pair pin mask */ + for (int i = 0; i < button_num; ++i) { + pin_bit_mask |= (1ULL << (button_func_pair + i)->pin); + } + /* interrupt of falling edge */ + io_conf.intr_type = GPIO_INTR_NEGEDGE; + io_conf.pin_bit_mask = pin_bit_mask; + io_conf.mode = GPIO_MODE_INPUT; + io_conf.pull_up_en = 1; + /* configure GPIO with the given settings */ + gpio_config(&io_conf); + /* create a queue to handle gpio event from isr */ + gpio_evt_queue = xQueueCreate(10, sizeof(switch_func_pair_t)); + if ( gpio_evt_queue == 0) { + ESP_LOGE(TAG, "Queue was not created and must not be used"); + return false; + } + /* start gpio task */ + xTaskCreate(switch_driver_button_detected, "button_detected", 2048, NULL, 10, NULL); + /* install gpio isr service */ + gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); + for (int i = 0; i < button_num; ++i) { + gpio_isr_handler_add((button_func_pair + i)->pin, gpio_isr_handler, (void *) (button_func_pair + i)); + } + return true; +} + +bool switch_driver_init(switch_func_pair_t *button_func_pair, uint8_t button_num, esp_switch_callback_t cb) +{ + if (!switch_driver_gpio_init(button_func_pair, button_num)) { + return false; + } + func_ptr = cb; + return true; +} diff --git a/examples/zigbee/light_sample/light_switch/main/switch_driver.h b/examples/zigbee/light_sample/light_switch/main/switch_driver.h new file mode 100644 index 0000000000..8144460f32 --- /dev/null +++ b/examples/zigbee/light_sample/light_switch/main/switch_driver.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2021 Espressif Systems (Shanghai) CO LTD + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Espressif Systems + * integrated circuit in a product or a software update for such product, + * must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * 4. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#pragma once + +#include "driver/gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* user should configure which I/O port as toggle switch input, default is GPIO9 */ +#define GPIO_INPUT_IO_TOGGLE_SWITCH GPIO_NUM_9 + +/* config button level depends on the pull up/down setting + push button level is on level = 1 when pull-down enable + push button level is on level = 0 when pull-up enable +*/ +#define GPIO_INPUT_LEVEL_ON 0 + +#define ESP_INTR_FLAG_DEFAULT 0 + +#define PAIR_SIZE(TYPE_STR_PAIR) (sizeof(TYPE_STR_PAIR) / sizeof(TYPE_STR_PAIR[0])) + +typedef enum { + SWITCH_IDLE, + SWITCH_PRESS_ARMED, + SWITCH_PRESS_DETECTED, + SWITCH_PRESSED, + SWITCH_RELEASE_DETECTED, +} switch_state_t; + +typedef enum { + SWITCH_ON_CONTROL, + SWITCH_OFF_CONTROL, + SWITCH_ONOFF_TOGGLE_CONTROL, + SWITCH_LEVEL_UP_CONTROL, + SWITCH_LEVEL_DOWN_CONTROL, + SWITCH_LEVEL_CYCLE_CONTROL, + SWITCH_COLOR_CONTROL, +} switch_func_t; + +typedef struct { + uint32_t pin; + switch_func_t func; +} switch_func_pair_t; + +typedef void (*esp_switch_callback_t)(switch_func_pair_t param); + +/** + * @brief init function for switch and callback setup + * + * @param button_func_pair pointer of the button pair. + * @param button_num number of button pair. + * @param cb callback pointer. + */ +bool switch_driver_init(switch_func_pair_t *button_func_pair, uint8_t button_num, esp_switch_callback_t cb); + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/examples/zigbee/light_sample/light_switch/partitions.csv b/examples/zigbee/light_sample/light_switch/partitions.csv new file mode 100644 index 0000000000..30e8c9e132 --- /dev/null +++ b/examples/zigbee/light_sample/light_switch/partitions.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 1M, +zb_storage, data, fat, , 128K, diff --git a/examples/zigbee/light_sample/light_switch/sdkconfig.defaults b/examples/zigbee/light_sample/light_switch/sdkconfig.defaults new file mode 100644 index 0000000000..ae34b12a3d --- /dev/null +++ b/examples/zigbee/light_sample/light_switch/sdkconfig.defaults @@ -0,0 +1,42 @@ +CONFIG_IDF_TARGET="esp32h2" + +# +# libsodium +# +CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y +# end of libsodium + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# mbedTLS +# +CONFIG_MBEDTLS_HARDWARE_AES=n +CONFIG_MBEDTLS_HARDWARE_MPI=n +CONFIG_MBEDTLS_HARDWARE_SHA=n +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_SSL_PROTO_DTLS=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_ECJPAKE_C=y +# end of mbedTLS + +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=n +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=n + +# +# Zboss +# +CONFIG_ZB_ENABLED=y +CONFIG_ZB_ZED=y +# end of Zboss +# end of Component config diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 640d17c591..3049764924 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -3489,6 +3489,16 @@ examples/wifi/smart_config/main/smartconfig_main.c examples/wifi/wifi_easy_connect/dpp-enrollee/main/dpp_enrollee_main.c examples/wifi/wifi_enterprise/main/wifi_enterprise_main.c examples/wifi/wps/main/wps.c +examples/zigbee/light_sample/light_bulb/main/esp_zb_light.c +examples/zigbee/light_sample/light_bulb/main/esp_zb_light.h +examples/zigbee/light_sample/light_bulb/main/light_driver.c +examples/zigbee/light_sample/light_bulb/main/light_driver.h +examples/zigbee/light_sample/light_coordinator/main/esp_zb_coordinator.c +examples/zigbee/light_sample/light_coordinator/main/esp_zb_coordinator.h +examples/zigbee/light_sample/light_switch/main/esp_zb_switch.c +examples/zigbee/light_sample/light_switch/main/esp_zb_switch.h +examples/zigbee/light_sample/light_switch/main/switch_driver.c +examples/zigbee/light_sample/light_switch/main/switch_driver.h tools/ble/lib_ble_client.py tools/ble/lib_gap.py tools/ble/lib_gatt.py