Working zigbee generic, connected to network and HA

This commit is contained in:
Sam
2025-05-14 12:18:50 +10:00
parent 40691d1884
commit 5d3a5422c4
1585 changed files with 271860 additions and 3 deletions

View File

@@ -0,0 +1,5 @@
idf_component_register(SRC_DIRS "src"
INCLUDE_DIRS "include"
REQUIRES
driver
)

View File

@@ -0,0 +1,72 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*
* Zigbee switch driver example
*
* This example code is in the Public Domain (or CC0 licensed, at your option.)
*
* Unless required by applicable law or agreed to in writing, this
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied.
*/
#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

View File

@@ -0,0 +1,159 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*
* Zigbee switch driver example
*
* This example code is in the Public Domain (or CC0 licensed, at your option.)
*
* Unless required by applicable law or agreed to in writing, this
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied.
*/
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "switch_driver.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 is 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 QueueHandle_t 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 switch_driver_gpios_intr_enabled(bool enabled);
static void IRAM_ATTR gpio_isr_handler(void *arg)
{
switch_driver_gpios_intr_enabled(false);
xQueueSendFromISR(gpio_evt_queue, (switch_func_pair_t *)arg, NULL);
}
/**
* @brief Enable GPIO (switches 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_PERIOD_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_LOW_LEVEL;
io_conf.pin_bit_mask = pin_bit_mask;
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pull_down_en = 0;
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", 4096, 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;
}