Initial commit: ESP32-C6 Zigbee sensor switch project
This commit is contained in:
5
common/switch_driver/CMakeLists.txt
Normal file
5
common/switch_driver/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
idf_component_register(SRC_DIRS "src"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES
|
||||
driver
|
||||
)
|
||||
72
common/switch_driver/include/switch_driver.h
Normal file
72
common/switch_driver/include/switch_driver.h
Normal 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
|
||||
159
common/switch_driver/src/switch_driver.c
Normal file
159
common/switch_driver/src/switch_driver.c
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user