commit 1945589d607816a29b0a4748b60ec33d53809c60 Author: MartB Date: Fri Apr 1 18:59:22 2022 +0200 Initial SDK Import diff --git a/app_cfg.h b/app_cfg.h new file mode 100644 index 0000000..d326110 --- /dev/null +++ b/app_cfg.h @@ -0,0 +1,166 @@ +/******************************************************************************************************** + * @file app_cfg.h + * + * @brief This is the header file for app_cfg + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#pragma once + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + + +/********************************************************************** + * Version configuration + */ +#include "version_cfg.h" + +/********************************************************************** + * Product Information + */ +/* Debug mode config */ +#define UART_PRINTF_MODE 0 +#define USB_PRINTF_MODE 0 + +/* HCI interface */ +#define ZBHCI_UART 0 + +/* RGB or CCT */ +#define COLOR_RGB_SUPPORT 0 +#define COLOR_CCT_SUPPORT 1 + +/* BDB */ +#define TOUCHLINK_SUPPORT 1 +#define FIND_AND_BIND_SUPPORT 0 + +/* Board ID */ +#define BOARD_826x_EVK 0 +#define BOARD_826x_DONGLE 1 +#define BOARD_8258_EVK 2 +#define BOARD_8258_DONGLE 3 +#define BOARD_8278_EVK 4 +#define BOARD_8278_DONGLE 5 +#define BOARD_9518_EVK 6 +#define BOARD_9518_DONGLE 7 + +/* Board define */ +#if defined(MCU_CORE_826x) + #define BOARD BOARD_826x_DONGLE + #define CLOCK_SYS_CLOCK_HZ 32000000 +#elif defined(MCU_CORE_8258) +#if (CHIP_TYPE == TLSR_8258_1M) + #define FLASH_CAP_SIZE_1M 1 +#endif + #define BOARD BOARD_8258_DONGLE//BOARD_8258_EVK + #define CLOCK_SYS_CLOCK_HZ 48000000 +#elif defined(MCU_CORE_8278) + #define FLASH_CAP_SIZE_1M 1 + #define BOARD BOARD_8278_DONGLE//BOARD_8278_EVK + #define CLOCK_SYS_CLOCK_HZ 48000000 +#elif defined(MCU_CORE_B91) + #define FLASH_CAP_SIZE_1M 1 + #define BOARD BOARD_9518_DONGLE//BOARD_9518_EVK + #define CLOCK_SYS_CLOCK_HZ 48000000 +#else + #error "MCU is undefined!" +#endif + +/* Board include */ +#if (BOARD == BOARD_826x_EVK) + #include "board_826x_evk.h" +#elif(BOARD == BOARD_826x_DONGLE) + #include "board_826x_dongle.h" +#elif(BOARD == BOARD_8258_DONGLE) + #include "board_8258_dongle.h" +#elif(BOARD == BOARD_8258_EVK) + #include "board_8258_evk.h" +#elif(BOARD == BOARD_8278_EVK) + #include "board_8278_evk.h" +#elif(BOARD == BOARD_8278_DONGLE) + #include "board_8278_dongle.h" +#elif (BOARD == BOARD_9518_EVK) + #include "board_9518_evk.h" +#elif (BOARD == BOARD_9518_DONGLE) + #include "board_9518_dongle.h" +#endif + + +/* Voltage detect module */ +/* If you want to define the VOLTAGE_DETECT_ENABLE to 1, + * and the model of the development board is B91 evk or dongle, + * be sure to connect GPIO_PB0 to VCC. + */ +#define VOLTAGE_DETECT_ENABLE 0 + +/* Watch dog module */ +#define MODULE_WATCHDOG_ENABLE 0 + +/* UART module */ +#if ZBHCI_UART +#define MODULE_UART_ENABLE 1 +#endif + +#if (ZBHCI_USB_PRINT || ZBHCI_USB_CDC || ZBHCI_USB_HID || ZBHCI_UART) + #define ZBHCI_EN 1 +#endif + + +/********************************************************************** + * ZCL cluster support setting + */ +#define ZCL_ON_OFF_SUPPORT 1 +#define ZCL_LEVEL_CTRL_SUPPORT 1 +#if (COLOR_RGB_SUPPORT || COLOR_CCT_SUPPORT) +#define ZCL_LIGHT_COLOR_CONTROL_SUPPORT 1 +#endif +#define ZCL_GROUP_SUPPORT 1 +#define ZCL_SCENE_SUPPORT 1 +#define ZCL_OTA_SUPPORT 1 +#define ZCL_GP_SUPPORT 1 +#define ZCL_WWAH_SUPPORT 0 +#if TOUCHLINK_SUPPORT +#define ZCL_ZLL_COMMISSIONING_SUPPORT 1 +#endif + +#define AF_TEST_ENABLE 0 + + +/********************************************************************** + * Stack configuration + */ +#include "stack_cfg.h" + + +/********************************************************************** + * EV configuration + */ +typedef enum{ + EV_POLL_ED_DETECT, + EV_POLL_HCI, + EV_POLL_IDLE, + EV_POLL_MAX, +}ev_poll_e; + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +} +#endif diff --git a/app_ui.c b/app_ui.c new file mode 100644 index 0000000..0694bf5 --- /dev/null +++ b/app_ui.c @@ -0,0 +1,147 @@ +/******************************************************************************************************** + * @file app_ui.c + * + * @brief This is the source file for app_ui + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#if (__PROJECT_TL_DIMMABLE_LIGHT__) + +/********************************************************************** + * INCLUDES + */ +#include "tl_common.h" +#include "zb_api.h" +#include "zcl_include.h" +#include "sampleLight.h" +#include "app_ui.h" + +/********************************************************************** + * LOCAL CONSTANTS + */ + + +/********************************************************************** + * TYPEDEFS + */ + + +/********************************************************************** + * GLOBAL VARIABLES + */ + + +/********************************************************************** + * LOCAL FUNCTIONS + */ +void led_on(u32 pin){ + drv_gpio_write(pin, LED_ON); +} + +void led_off(u32 pin){ + drv_gpio_write(pin, LED_OFF); +} + +void led_init(void){ + led_off(LED_POWER); + led_off(LED_PERMIT); +} + +void localPermitJoinState(void){ + static bool assocPermit = 0; + if(assocPermit != zb_getMacAssocPermit()){ + assocPermit = zb_getMacAssocPermit(); + if(assocPermit){ + led_on(LED_PERMIT); + }else{ + led_off(LED_PERMIT); + } + } +} + +void buttonKeepPressed(u8 btNum){ + if(btNum == VK_SW1){ + gLightCtx.state = APP_FACTORY_NEW_DOING; + zb_factoryReset(); + }else if(btNum == VK_SW2){ + + } +} + +void buttonShortPressed(u8 btNum){ + if(btNum == VK_SW1){ + if(zb_isDeviceJoinedNwk()){ + gLightCtx.sta = !gLightCtx.sta; + if(gLightCtx.sta){ + sampleLight_onoff(ZCL_ONOFF_STATUS_ON); + }else{ + sampleLight_onoff(ZCL_ONOFF_STATUS_OFF); + } + } + }else if(btNum == VK_SW2){ + /* toggle local permit Joining */ + static u8 duration = 0; + duration = duration ? 0 : 0xff; + zb_nlmePermitJoiningRequest(duration); + } +} + +void keyScan_keyPressedCB(kb_data_t *kbEvt){ +// u8 toNormal = 0; + u8 keyCode = kbEvt->keycode[0]; +// static u8 lastKeyCode = 0xff; + + buttonShortPressed(keyCode); + + if(keyCode == VK_SW1){ + gLightCtx.keyPressedTime = clock_time(); + gLightCtx.state = APP_FACTORY_NEW_SET_CHECK; + } +} + + +void keyScan_keyReleasedCB(u8 keyCode){ + gLightCtx.state = APP_STATE_NORMAL; +} + +volatile u8 T_keyPressedNum = 0; +void app_key_handler(void){ + static u8 valid_keyCode = 0xff; + + if(gLightCtx.state == APP_FACTORY_NEW_SET_CHECK){ + if(clock_time_exceed(gLightCtx.keyPressedTime, 5*1000*1000)){ + buttonKeepPressed(VK_SW1); + } + } + + if(kb_scan_key(0 , 1)){ + T_keyPressedNum++; + if(kb_event.cnt){ + keyScan_keyPressedCB(&kb_event); + if(kb_event.cnt == 1){ + valid_keyCode = kb_event.keycode[0]; + } + }else{ + keyScan_keyReleasedCB(valid_keyCode); + valid_keyCode = 0xff; + } + } +} + +#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */ diff --git a/app_ui.h b/app_ui.h new file mode 100644 index 0000000..9e9ccd8 --- /dev/null +++ b/app_ui.h @@ -0,0 +1,53 @@ +/******************************************************************************************************** + * @file app_ui.h + * + * @brief This is the header file for app_ui + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef _APP_UI_H_ +#define _APP_UI_H_ + +/********************************************************************** + * CONSTANT + */ +#define LED_ON 1 +#define LED_OFF 0 + + +/********************************************************************** + * TYPEDEFS + */ +enum{ + APP_STATE_NORMAL, + APP_FACTORY_NEW_SET_CHECK, + APP_FACTORY_NEW_DOING, +}; + + +/********************************************************************** + * FUNCTIONS + */ +void led_init(void); +void led_on(u32 pin); +void led_off(u32 pin); +void localPermitJoinState(void); +void app_key_handler(void); + +#endif /* _APP_UI_H_ */ diff --git a/board_8258_dongle.h b/board_8258_dongle.h new file mode 100644 index 0000000..9f90668 --- /dev/null +++ b/board_8258_dongle.h @@ -0,0 +1,295 @@ +/******************************************************************************************************** + * @file board_8258_dongle.h + * + * @brief This is the header file for board_8258_dongle + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#pragma once + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + + +#define DONGLE_8258_32 0 +#define DONGLE_8258_48 1 + +#if defined DONGLE_8258_32 && (DONGLE_8258_32 == 1) +/******************************************************************************************************* +*********************8258Dongle with 32 Pins: Start***************************************************** +*******************************************************************************************************/ +//KEY +#define BUTTON1 GPIO_PD7 +#define PD7_FUNC AS_GPIO +#define PD7_OUTPUT_ENABLE 0 +#define PD7_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PD7 PM_PIN_PULLUP_10K + +#define BUTTON2 GPIO_PA1 +#define PA1_FUNC AS_GPIO +#define PA1_OUTPUT_ENABLE 0 +#define PA1_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PA1 PM_PIN_PULLUP_10K + +//LED +/*************************************************************** +* LED_R GPIO_PD4 //D1 -- red PWM2_N +* LED_G GPIO_PA0 //D2 -- green PWM0_N +* LED_B GPIO_PD3 //D3 -- blue PWM1_N +* LED_W GPIO_PD2 //D4 -- yellow PWM3 +****************************************************************/ +#if defined COLOR_RGB_SUPPORT && (COLOR_RGB_SUPPORT == 1) + +#define LED_R GPIO_PD4 //D1 -- red PWM2_N +#define LED_G GPIO_PA0 //D2 -- green PWM0_N +#define LED_B GPIO_PD3 //D3 -- blue PWM1_N + +#define PWM_R_CHANNEL 2//PWM2_N +#define PWM_R_CHANNEL_SET() do{ \ + gpio_set_func(LED_R, AS_PWM2_N); \ + drv_pwm_n_invert(PWM_R_CHANNEL); \ + }while(0) + +#define PWM_G_CHANNEL 0//PWM0_N +#define PWM_G_CHANNEL_SET() do{ \ + gpio_set_func(LED_G, AS_PWM0_N); \ + drv_pwm_n_invert(PWM_G_CHANNEL); \ + }while(0) + +#define PWM_B_CHANNEL 1//PWM1_N +#define PWM_B_CHANNEL_SET() do{ \ + gpio_set_func(LED_B, AS_PWM1_N); \ + drv_pwm_n_invert(PWM_B_CHANNEL); \ + }while(0) + +#define R_LIGHT_PWM_CHANNEL PWM_R_CHANNEL +#define G_LIGHT_PWM_CHANNEL PWM_G_CHANNEL +#define B_LIGHT_PWM_CHANNEL PWM_B_CHANNEL +#define R_LIGHT_PWM_SET() PWM_R_CHANNEL_SET() +#define G_LIGHT_PWM_SET() PWM_G_CHANNEL_SET() +#define B_LIGHT_PWM_SET() PWM_B_CHANNEL_SET() + +#define LED_W GPIO_PD2 + +#define PD2_FUNC AS_GPIO +#define PD2_OUTPUT_ENABLE 1 +#define PD2_INPUT_ENABLE 0 + +#define LED_POWER NULL +#define LED_PERMIT LED_W + +#else + +//PWM configuration, LED_B as warm light, LED_W as cool light. +#define LED_B GPIO_PD3 //D3 -- blue PWM1_N +#define LED_W GPIO_PD2 //D4 -- yellow PWM3 + +#define PWM_B_CHANNEL 1//PWM1_N +#define PWM_B_CHANNEL_SET() do{ \ + gpio_set_func(LED_B, AS_PWM1_N); \ + drv_pwm_n_invert(PWM_B_CHANNEL); \ + }while(0) + +#define PWM_W_CHANNEL 3//PWM3 +#define PWM_W_CHANNEL_SET() do{ \ + gpio_set_func(LED_W, AS_PWM3); \ + }while(0) + +#define WARM_LIGHT_PWM_CHANNEL PWM_B_CHANNEL +#define COOL_LIGHT_PWM_CHANNEL PWM_W_CHANNEL +#define WARM_LIGHT_PWM_SET() PWM_B_CHANNEL_SET() +#define COOL_LIGHT_PWM_SET() PWM_W_CHANNEL_SET() + +//LED_R and LED_G as GPIO. +#define LED_R GPIO_PD4 +#define LED_G GPIO_PA0 + +#define PD4_FUNC AS_GPIO +#define PD4_OUTPUT_ENABLE 1 +#define PD4_INPUT_ENABLE 0 + +#define PA0_FUNC AS_GPIO +#define PA0_OUTPUT_ENABLE 1 +#define PA0_INPUT_ENABLE 0 + +#define LED_POWER LED_R +#define LED_PERMIT LED_G + +#endif + +// UART +#if ZBHCI_UART + #error please configurate uart PIN!!!!!! +#endif + +// DEBUG +#if UART_PRINTF_MODE + #define DEBUG_INFO_TX_PIN GPIO_PC4//print +#endif +/******************************************************************************************************* +*********************8258Dongle with 32 Pins: End***************************************************** +*******************************************************************************************************/ +#elif defined DONGLE_8258_48 && (DONGLE_8258_48 == 1) +/******************************************************************************************************* +*********************8258Dongle with 48 Pins: Start***************************************************** +*******************************************************************************************************/ +//KEY +#define BUTTON1 GPIO_PD6 +#define PD6_FUNC AS_GPIO +#define PD6_OUTPUT_ENABLE 0 +#define PD6_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PD6 PM_PIN_PULLUP_10K + +#define BUTTON2 GPIO_PD5 +#define PD5_FUNC AS_GPIO +#define PD5_OUTPUT_ENABLE 0 +#define PD5_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PD5 PM_PIN_PULLUP_10K + +//LED +/*************************************************************** +* LED_R GPIO_PA3 //D2 -- red PWM1 +* LED_G GPIO_PA2 //D1 -- green PWM0 +* LED_B GPIO_PB0 //D4 -- blue PWM3 +* LED_W GPIO_PB1 //D5 -- white PWM4 +* LED_Y GPIO_PA4 //D3 -- yellow PWM2 +****************************************************************/ +#if defined COLOR_RGB_SUPPORT && (COLOR_RGB_SUPPORT == 1) + +#define LED_R GPIO_PA3 //D2 -- red PWM1 +#define LED_G GPIO_PA2 //D1 -- green PWM0 +#define LED_B GPIO_PB0 //D4 -- blue PWM3 + +#define PWM_R_CHANNEL 1//PWM1 +#define PWM_R_CHANNEL_SET() do{ \ + gpio_set_func(LED_R, AS_PWM1); \ + }while(0) + +#define PWM_G_CHANNEL 0//PWM0 +#define PWM_G_CHANNEL_SET() do{ \ + gpio_set_func(LED_G, AS_PWM0); \ + }while(0) + +#define PWM_B_CHANNEL 3//PWM3 +#define PWM_B_CHANNEL_SET() do{ \ + gpio_set_func(LED_B, AS_PWM3); \ + }while(0) + +#define R_LIGHT_PWM_CHANNEL PWM_R_CHANNEL +#define G_LIGHT_PWM_CHANNEL PWM_G_CHANNEL +#define B_LIGHT_PWM_CHANNEL PWM_B_CHANNEL +#define R_LIGHT_PWM_SET() PWM_R_CHANNEL_SET() +#define G_LIGHT_PWM_SET() PWM_G_CHANNEL_SET() +#define B_LIGHT_PWM_SET() PWM_B_CHANNEL_SET() + +//LED_Y and LED_W as GPIO. +#define LED_Y GPIO_PA4 +#define LED_W GPIO_PB1 + +#define PA4_FUNC AS_GPIO +#define PA4_OUTPUT_ENABLE 1 +#define PA4_INPUT_ENABLE 0 + +#define PB1_FUNC AS_GPIO +#define PB1_OUTPUT_ENABLE 1 +#define PB1_INPUT_ENABLE 0 + +#define LED_POWER LED_W +#define LED_PERMIT LED_Y + +#else + +//PWM configuration, LED_Y as warm light, LED_W as cool light. +#define LED_Y GPIO_PA4 //D3 -- yellow PWM2 +#define LED_W GPIO_PB1 //D5 -- white PWM4 + +#define PWM_Y_CHANNEL 2//PWM2 +#define PWM_Y_CHANNEL_SET() do{ \ + gpio_set_func(LED_Y, AS_PWM2); \ + }while(0) + +#define PWM_W_CHANNEL 4//PWM4 +#define PWM_W_CHANNEL_SET() do{ \ + gpio_set_func(LED_W, AS_PWM4); \ + }while(0) + +#define WARM_LIGHT_PWM_CHANNEL PWM_Y_CHANNEL +#define COOL_LIGHT_PWM_CHANNEL PWM_W_CHANNEL +#define WARM_LIGHT_PWM_SET() PWM_Y_CHANNEL_SET() +#define COOL_LIGHT_PWM_SET() PWM_W_CHANNEL_SET() + +//LED_R and LED_G as GPIO. +#define LED_R GPIO_PA3 +#define LED_G GPIO_PA2 + +#define PA3_FUNC AS_GPIO +#define PA3_OUTPUT_ENABLE 1 +#define PA3_INPUT_ENABLE 0 + +#define PA2_FUNC AS_GPIO +#define PA2_OUTPUT_ENABLE 1 +#define PA2_INPUT_ENABLE 0 + +#define LED_POWER LED_R +#define LED_PERMIT LED_G + +#endif + +// UART +#if ZBHCI_UART + #define UART_TX_PIN UART_TX_PD7 + #define UART_RX_PIN UART_RX_PA0 + + #define UART_PIN_CFG() uart_gpio_set(UART_TX_PIN, UART_RX_PIN);// uart tx/rx pin set +#endif + +// DEBUG +#if UART_PRINTF_MODE + #define DEBUG_INFO_TX_PIN GPIO_PC6//print +#endif +/******************************************************************************************************* +*********************8258Dongle with 48 Pins: End***************************************************** +*******************************************************************************************************/ +#else + #error "Board defined error!" +#endif + + +enum{ + VK_SW1 = 0x01, + VK_SW2 = 0x02 +}; + +#define KB_MAP_NORMAL {\ + {VK_SW1,}, \ + {VK_SW2,}, } + +#define KB_MAP_NUM KB_MAP_NORMAL +#define KB_MAP_FN KB_MAP_NORMAL + +#define KB_DRIVE_PINS {NULL } +#define KB_SCAN_PINS {BUTTON1, BUTTON2} + + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +} +#endif diff --git a/board_8258_evk.h b/board_8258_evk.h new file mode 100644 index 0000000..684c503 --- /dev/null +++ b/board_8258_evk.h @@ -0,0 +1,123 @@ +/******************************************************************************************************** + * @file board_8258_evk.h + * + * @brief This is the header file for board_8258_evk + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#pragma once + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + + +// BUTTON +#define BUTTON1 GPIO_PD1 +#define PD1_FUNC AS_GPIO +#define PD1_OUTPUT_ENABLE 0 +#define PD1_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PD1 PM_PIN_PULLUP_10K + +#define BUTTON2 GPIO_PD2 +#define PD2_FUNC AS_GPIO +#define PD2_OUTPUT_ENABLE 0 +#define PD2_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PD2 PM_PIN_PULLUP_10K + +// LED +/*************************************************************** +* LED_R GPIO_PD0 //D5 -- red +* LED_G GPIO_PD4 //D3 -- green +* LED_B GPIO_PD5 //D2 -- blue +* LED_W GPIO_PD3 //D4 -- yellow +****************************************************************/ +#if defined COLOR_RGB_SUPPORT && (COLOR_RGB_SUPPORT == 1) + #error "GPIO_PD0 can't be configured as PWM!" +#else + +//PWM configuration, LED_B as warm light, LED_W as cool light. +#define LED_B GPIO_PD5 //D2 -- blue PWM0 +#define LED_W GPIO_PD3 //D4 -- yellow PWM1_N + +#define PWM_W_CHANNEL 1 //PWM1_N +#define PWM_W_CHANNEL_SET() do{ \ + gpio_set_func(LED_W, AS_PWM1_N); \ + drv_pwm_n_invert(PWM_W_CHANNEL); \ + }while(0) + +#define PWM_B_CHANNEL 0 //PWM0 +#define PWM_B_CHANNEL_SET() do{ \ + gpio_set_func(LED_B, AS_PWM0); \ + }while(0) + +#define WARM_LIGHT_PWM_CHANNEL PWM_B_CHANNEL +#define COOL_LIGHT_PWM_CHANNEL PWM_W_CHANNEL +#define WARM_LIGHT_PWM_SET() PWM_B_CHANNEL_SET() +#define COOL_LIGHT_PWM_SET() PWM_W_CHANNEL_SET() + +//LED_R and LED_G as GPIO. +#define LED_R GPIO_PD0 +#define LED_G GPIO_PD4 + +#define PD4_FUNC AS_GPIO +#define PD4_OUTPUT_ENABLE 1 +#define PD4_INPUT_ENABLE 0 + +#define PD0_FUNC AS_GPIO +#define PD0_OUTPUT_ENABLE 1 +#define PD0_INPUT_ENABLE 0 + +#define LED_POWER LED_R +#define LED_PERMIT LED_G + +#endif + +// UART +#if ZBHCI_UART + #error please configurate uart PIN!!!!!! +#endif + +// DEBUG +#if UART_PRINTF_MODE + #define DEBUG_INFO_TX_PIN GPIO_PC7//print +#endif + + +enum{ + VK_SW1 = 0x01, + VK_SW2 = 0x02 +}; + +#define KB_MAP_NORMAL {\ + {VK_SW1,}, \ + {VK_SW2,}, } + +#define KB_MAP_NUM KB_MAP_NORMAL +#define KB_MAP_FN KB_MAP_NORMAL + +#define KB_DRIVE_PINS {NULL } +#define KB_SCAN_PINS {BUTTON1, BUTTON2} + + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +} +#endif diff --git a/board_826x_dongle.h b/board_826x_dongle.h new file mode 100644 index 0000000..459cb08 --- /dev/null +++ b/board_826x_dongle.h @@ -0,0 +1,158 @@ +/******************************************************************************************************** + * @file board_826x_dongle.h + * + * @brief This is the header file for board_826x_dongle + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#pragma once + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + +//KEY +#define BUTTON1 GPIO_PD2 +#define PD2_FUNC AS_GPIO +#define PD2_OUTPUT_ENABLE 0 +#define PD2_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PD2 PM_PIN_PULLUP_10K + +#define BUTTON2 GPIO_PC5 +#define PC5_FUNC AS_GPIO +#define PC5_OUTPUT_ENABLE 0 +#define PC5_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PC5 PM_PIN_PULLUP_10K + +//LED +/*************************************************************** +* LED_R GPIO_PC2 //D3 -- red PWM2 +* LED_G GPIO_PC3 //D1 -- green PWM3 +* LED_B GPIO_PB6 //D2 -- blue PWM5 +* LED_W GPIO_PB4 //D4 -- white PWM4 +****************************************************************/ +#if defined COLOR_RGB_SUPPORT && (COLOR_RGB_SUPPORT == 1) + +#define PC2_FUNC AS_PWM +#define PC2_OUTPUT_ENABLE 1 +#define PC2_INPUT_ENABLE 0 + +#define PC3_FUNC AS_PWM +#define PC3_OUTPUT_ENABLE 1 +#define PC3_INPUT_ENABLE 0 + +#define PB6_FUNC AS_PWM +#define PB6_OUTPUT_ENABLE 1 +#define PB6_INPUT_ENABLE 0 + +#define PWM_R_CHANNEL_SET() PWM2_CFG_GPIO_C2() +#define PWM_R_CHANNEL 2//PWM2 + +#define PWM_G_CHANNEL_SET() PWM3_CFG_GPIO_C3() +#define PWM_G_CHANNEL 3//PWM3 + +#define PWM_B_CHANNEL_SET() PWM5_CFG_GPIO_B6() +#define PWM_B_CHANNEL 5//PWM5 + +#define R_LIGHT_PWM_CHANNEL PWM_R_CHANNEL +#define G_LIGHT_PWM_CHANNEL PWM_G_CHANNEL +#define B_LIGHT_PWM_CHANNEL PWM_B_CHANNEL +#define R_LIGHT_PWM_SET() PWM_R_CHANNEL_SET() +#define G_LIGHT_PWM_SET() PWM_G_CHANNEL_SET() +#define B_LIGHT_PWM_SET() PWM_B_CHANNEL_SET() + +#define LED_W GPIO_PB4 + +#define PB4_FUNC AS_GPIO +#define PB4_OUTPUT_ENABLE 1 +#define PB4_INPUT_ENABLE 0 + +#define LED_POWER NULL +#define LED_PERMIT LED_W + +#else + +//PWM configuration, LED_B as warm light, LED_W as cool light. +#define PB6_FUNC AS_PWM +#define PB6_OUTPUT_ENABLE 1 +#define PB6_INPUT_ENABLE 0 + +#define PB4_FUNC AS_PWM +#define PB4_OUTPUT_ENABLE 1 +#define PB4_INPUT_ENABLE 0 + +#define PWM_B_CHANNEL_SET() PWM5_CFG_GPIO_B6() +#define PWM_B_CHANNEL 5//PWM5 + +#define PWM_W_CHANNEL_SET() PWM4_CFG_GPIO_B4() +#define PWM_W_CHANNEL 4//PWM4 + +#define WARM_LIGHT_PWM_CHANNEL PWM_B_CHANNEL +#define COOL_LIGHT_PWM_CHANNEL PWM_W_CHANNEL +#define WARM_LIGHT_PWM_SET() PWM_B_CHANNEL_SET() +#define COOL_LIGHT_PWM_SET() PWM_W_CHANNEL_SET() + +#define LED_R GPIO_PC2 +#define LED_G GPIO_PC3 + +#define PC2_FUNC AS_GPIO +#define PC2_OUTPUT_ENABLE 1 +#define PC2_INPUT_ENABLE 0 + +#define PC3_FUNC AS_GPIO +#define PC3_OUTPUT_ENABLE 1 +#define PC3_INPUT_ENABLE 0 + +#define LED_POWER LED_R +#define LED_PERMIT LED_G + +#endif + +//UART +#if ZBHCI_UART + PC2 & PC3 are configured as LED pins +#endif + +//DEBUG +#if UART_PRINTF_MODE + #define DEBUG_INFO_TX_PIN GPIO_PB5//print +#endif + + +enum{ + VK_SW1 = 0x01, + VK_SW2 = 0x02 +}; + +#define KB_MAP_NORMAL {\ + {VK_SW1,}, \ + {VK_SW2,}, } + +#define KB_MAP_NUM KB_MAP_NORMAL +#define KB_MAP_FN KB_MAP_NORMAL + +#define KB_DRIVE_PINS {NULL } +#define KB_SCAN_PINS {BUTTON1, BUTTON2} + + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +} +#endif diff --git a/board_826x_evk.h b/board_826x_evk.h new file mode 100644 index 0000000..33cd3d6 --- /dev/null +++ b/board_826x_evk.h @@ -0,0 +1,158 @@ +/******************************************************************************************************** + * @file board_826x_evk.h + * + * @brief This is the header file for board_826x_evk + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#pragma once + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + +//KEY +#define BUTTON1 GPIO_PD2 +#define PD2_FUNC AS_GPIO +#define PD2_OUTPUT_ENABLE 0 +#define PD2_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PD2 PM_PIN_PULLUP_10K + +#define BUTTON2 GPIO_PC7 +#define PC7_FUNC AS_GPIO +#define PC7_OUTPUT_ENABLE 0 +#define PC7_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PC7 PM_PIN_PULLUP_10K + +//LED +/*************************************************************** +* LED_R GPIO_PD5 //D4 -- red PWM0 +* LED_G GPIO_PD6 //D2 -- green PWM1 +* LED_B GPIO_PB4 //D1 -- blue PWM4 +* LED_W GPIO_PD7 //D3 -- white PWM2 +****************************************************************/ +#if defined COLOR_RGB_SUPPORT && (COLOR_RGB_SUPPORT == 1) + +#define PD5_FUNC AS_PWM +#define PD5_OUTPUT_ENABLE 1 +#define PD5_INPUT_ENABLE 0 + +#define PD6_FUNC AS_PWM +#define PD6_OUTPUT_ENABLE 1 +#define PD6_INPUT_ENABLE 0 + +#define PB4_FUNC AS_PWM +#define PB4_OUTPUT_ENABLE 1 +#define PB4_INPUT_ENABLE 0 + +#define PWM_R_CHANNEL_SET() PWM0_CFG_GPIO_D5() +#define PWM_R_CHANNEL 0//PWM0 + +#define PWM_G_CHANNEL_SET() PWM1_CFG_GPIO_D6() +#define PWM_G_CHANNEL 1//PWM1 + +#define PWM_B_CHANNEL_SET() PWM4_CFG_GPIO_B4() +#define PWM_B_CHANNEL 4//PWM4 + +#define R_LIGHT_PWM_CHANNEL PWM_R_CHANNEL +#define G_LIGHT_PWM_CHANNEL PWM_G_CHANNEL +#define B_LIGHT_PWM_CHANNEL PWM_B_CHANNEL +#define R_LIGHT_PWM_SET() PWM_R_CHANNEL_SET() +#define G_LIGHT_PWM_SET() PWM_G_CHANNEL_SET() +#define B_LIGHT_PWM_SET() PWM_B_CHANNEL_SET() + +#define LED_W GPIO_PD7 + +#define PD7_FUNC AS_GPIO +#define PD7_OUTPUT_ENABLE 1 +#define PD7_INPUT_ENABLE 0 + +#define LED_POWER NULL +#define LED_PERMIT LED_W + +#else + +//PWM configuration, LED_B as warm light, LED_W as cool light. +#define PB4_FUNC AS_PWM +#define PB4_OUTPUT_ENABLE 1 +#define PB4_INPUT_ENABLE 0 + +#define PD7_FUNC AS_PWM +#define PD7_OUTPUT_ENABLE 1 +#define PD7_INPUT_ENABLE 0 + +#define PWM_B_CHANNEL_SET() PWM4_CFG_GPIO_B4() +#define PWM_B_CHANNEL 4//PWM4 + +#define PWM_W_CHANNEL_SET() PWM2_CFG_GPIO_D7() +#define PWM_W_CHANNEL 2//PWM2 + +#define WARM_LIGHT_PWM_CHANNEL PWM_B_CHANNEL +#define COOL_LIGHT_PWM_CHANNEL PWM_W_CHANNEL +#define WARM_LIGHT_PWM_SET() PWM_B_CHANNEL_SET() +#define COOL_LIGHT_PWM_SET() PWM_W_CHANNEL_SET() + +#define LED_R GPIO_PD5 +#define LED_G GPIO_PD6 + +#define PD5_FUNC AS_GPIO +#define PD5_OUTPUT_ENABLE 1 +#define PD5_INPUT_ENABLE 0 + +#define PD6_FUNC AS_GPIO +#define PD6_OUTPUT_ENABLE 1 +#define PD6_INPUT_ENABLE 0 + +#define LED_POWER LED_R +#define LED_PERMIT LED_G + +#endif + +//UART +#if ZBHCI_UART + #error please configurate uart PIN!!!!!! +#endif + +//DEBUG +#if UART_PRINTF_MODE + #define DEBUG_INFO_TX_PIN GPIO_PC5//print +#endif + + +enum{ + VK_SW1 = 0x01, + VK_SW2 = 0x02 +}; + +#define KB_MAP_NORMAL {\ + {VK_SW1,}, \ + {VK_SW2,}, } + +#define KB_MAP_NUM KB_MAP_NORMAL +#define KB_MAP_FN KB_MAP_NORMAL + +#define KB_DRIVE_PINS {NULL } +#define KB_SCAN_PINS {BUTTON1, BUTTON2} + + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +} +#endif diff --git a/board_8278_dongle.h b/board_8278_dongle.h new file mode 100644 index 0000000..f9aea98 --- /dev/null +++ b/board_8278_dongle.h @@ -0,0 +1,170 @@ +/******************************************************************************************************** + * @file board_8278_dongle.h + * + * @brief This is the header file for board_8278_dongle + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#pragma once + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + + +/******************************************************************************************************* +*********************8278Dongle with 48 Pins: Start***************************************************** +*******************************************************************************************************/ +//KEY +#define BUTTON1 GPIO_PD6 +#define PD6_FUNC AS_GPIO +#define PD6_OUTPUT_ENABLE 0 +#define PD6_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PD6 PM_PIN_PULLUP_10K + +#define BUTTON2 GPIO_PD5 +#define PD5_FUNC AS_GPIO +#define PD5_OUTPUT_ENABLE 0 +#define PD5_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PD5 PM_PIN_PULLUP_10K + +//LED +/*************************************************************** +* LED_R GPIO_PA3 //D2 -- red PWM1 +* LED_G GPIO_PA2 //D1 -- green PWM0 +* LED_B GPIO_PB0 //D4 -- blue PWM3 +* LED_W GPIO_PB1 //D5 -- white PWM4 +* LED_Y GPIO_PA4 //D3 -- yellow PWM2 +****************************************************************/ +#if defined COLOR_RGB_SUPPORT && (COLOR_RGB_SUPPORT == 1) + +#define LED_R GPIO_PA3 //D2 -- red PWM1 +#define LED_G GPIO_PA2 //D1 -- green PWM0 +#define LED_B GPIO_PB0 //D4 -- blue PWM3 + +#define PWM_R_CHANNEL 1//PWM1 +#define PWM_R_CHANNEL_SET() do{ \ + gpio_set_func(LED_R, AS_PWM1); \ + }while(0) + +#define PWM_G_CHANNEL 0//PWM0 +#define PWM_G_CHANNEL_SET() do{ \ + gpio_set_func(LED_G, AS_PWM0); \ + }while(0) + +#define PWM_B_CHANNEL 3//PWM3 +#define PWM_B_CHANNEL_SET() do{ \ + gpio_set_func(LED_B, AS_PWM3); \ + }while(0) + +#define R_LIGHT_PWM_CHANNEL PWM_R_CHANNEL +#define G_LIGHT_PWM_CHANNEL PWM_G_CHANNEL +#define B_LIGHT_PWM_CHANNEL PWM_B_CHANNEL +#define R_LIGHT_PWM_SET() PWM_R_CHANNEL_SET() +#define G_LIGHT_PWM_SET() PWM_G_CHANNEL_SET() +#define B_LIGHT_PWM_SET() PWM_B_CHANNEL_SET() + +//LED_Y and LED_W as GPIO. +#define LED_Y GPIO_PA4 +#define LED_W GPIO_PB1 + +#define PA4_FUNC AS_GPIO +#define PA4_OUTPUT_ENABLE 1 +#define PA4_INPUT_ENABLE 0 + +#define PB1_FUNC AS_GPIO +#define PB1_OUTPUT_ENABLE 1 +#define PB1_INPUT_ENABLE 0 + +#define LED_POWER LED_W +#define LED_PERMIT LED_Y + +#else + +//PWM configuration, LED_Y as warm light, LED_W as cool light. +#define LED_Y GPIO_PA4 //D3 -- yellow PWM2 +#define LED_W GPIO_PB1 //D5 -- white PWM4 + +#define PWM_Y_CHANNEL 2//PWM2 +#define PWM_Y_CHANNEL_SET() do{ \ + gpio_set_func(LED_Y, AS_PWM2); \ + }while(0) + +#define PWM_W_CHANNEL 4//PWM4 +#define PWM_W_CHANNEL_SET() do{ \ + gpio_set_func(LED_W, AS_PWM4); \ + }while(0) + +#define WARM_LIGHT_PWM_CHANNEL PWM_Y_CHANNEL +#define COOL_LIGHT_PWM_CHANNEL PWM_W_CHANNEL +#define WARM_LIGHT_PWM_SET() PWM_Y_CHANNEL_SET() +#define COOL_LIGHT_PWM_SET() PWM_W_CHANNEL_SET() + +//LED_R and LED_G as GPIO. +#define LED_R GPIO_PA3 +#define LED_G GPIO_PA2 + +#define PA3_FUNC AS_GPIO +#define PA3_OUTPUT_ENABLE 1 +#define PA3_INPUT_ENABLE 0 + +#define PA2_FUNC AS_GPIO +#define PA2_OUTPUT_ENABLE 1 +#define PA2_INPUT_ENABLE 0 + +#define LED_POWER LED_R +#define LED_PERMIT LED_G + +#endif + +// UART +#if ZBHCI_UART + #define UART_TX_PIN UART_TX_PD7 + #define UART_RX_PIN UART_RX_PA0 + + #define UART_PIN_CFG() uart_gpio_set(UART_TX_PIN, UART_RX_PIN);// uart tx/rx pin set +#endif + +// DEBUG +#if UART_PRINTF_MODE + #define DEBUG_INFO_TX_PIN GPIO_PC6//print +#endif + + +enum{ + VK_SW1 = 0x01, + VK_SW2 = 0x02 +}; + +#define KB_MAP_NORMAL {\ + {VK_SW1,}, \ + {VK_SW2,}, } + +#define KB_MAP_NUM KB_MAP_NORMAL +#define KB_MAP_FN KB_MAP_NORMAL + +#define KB_DRIVE_PINS {NULL } +#define KB_SCAN_PINS {BUTTON1, BUTTON2} + + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +} +#endif diff --git a/board_8278_evk.h b/board_8278_evk.h new file mode 100644 index 0000000..a3652d1 --- /dev/null +++ b/board_8278_evk.h @@ -0,0 +1,124 @@ +/******************************************************************************************************** + * @file board_8278_evk.h + * + * @brief This is the header file for board_8278_evk + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#pragma once + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + + +// BUTTON +#define BUTTON1 GPIO_PB2 +#define PB2_FUNC AS_GPIO +#define PB2_OUTPUT_ENABLE 0 +#define PB2_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PB2 PM_PIN_PULLUP_10K + +#define BUTTON2 GPIO_PB3 +#define PB3_FUNC AS_GPIO +#define PB3_OUTPUT_ENABLE 0 +#define PB3_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PB3 PM_PIN_PULLUP_10K + +//LED +/*************************************************************** +* LED_R GPIO_PD0 //D5 -- red +* LED_G GPIO_PD4 //D3 -- green +* LED_B GPIO_PD5 //D2 -- blue +* LED_W GPIO_PD3 //D4 -- yellow +****************************************************************/ +#if defined COLOR_RGB_SUPPORT && (COLOR_RGB_SUPPORT == 1) + +#error "GPIO_PD0 can't be configured as PWM!" + +#else + +//PWM configuration, LED_B as warm light, LED_W as cool light. +#define LED_B GPIO_PD2 //D2 -- blue PWM3 +#define LED_W GPIO_PD4 //D4 -- white PWM2_N + +#define PWM_W_CHANNEL 2 //PWM1_N +#define PWM_W_CHANNEL_SET() do{ \ + gpio_set_func(LED_W, AS_PWM2_N); \ + drv_pwm_n_invert(PWM_W_CHANNEL); \ + }while(0) + +#define PWM_B_CHANNEL 3 //PWM0 +#define PWM_B_CHANNEL_SET() do{ \ + gpio_set_func(LED_B, AS_PWM3); \ + }while(0) + +#define WARM_LIGHT_PWM_CHANNEL PWM_B_CHANNEL +#define COOL_LIGHT_PWM_CHANNEL PWM_W_CHANNEL +#define WARM_LIGHT_PWM_SET() PWM_B_CHANNEL_SET() +#define COOL_LIGHT_PWM_SET() PWM_W_CHANNEL_SET() + +//LED_R and LED_G as GPIO. +#define LED_R GPIO_PD5 +#define LED_G GPIO_PD3 + +#define PD3_FUNC AS_GPIO +#define PD3_OUTPUT_ENABLE 1 +#define PD3_INPUT_ENABLE 0 + +#define PD5_FUNC AS_GPIO +#define PD5_OUTPUT_ENABLE 1 +#define PD5_INPUT_ENABLE 0 + +#define LED_POWER LED_R +#define LED_PERMIT LED_G + +#endif + +// UART +#if ZBHCI_UART + #error please configurate uart PIN!!!!!! +#endif + +// DEBUG +#if UART_PRINTF_MODE + #define DEBUG_INFO_TX_PIN GPIO_PA2//print +#endif + + +enum{ + VK_SW1 = 0x01, + VK_SW2 = 0x02 +}; + +#define KB_MAP_NORMAL {\ + {VK_SW1,}, \ + {VK_SW2,}, } + +#define KB_MAP_NUM KB_MAP_NORMAL +#define KB_MAP_FN KB_MAP_NORMAL + +#define KB_DRIVE_PINS {NULL } +#define KB_SCAN_PINS {BUTTON1, BUTTON2} + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +} +#endif diff --git a/board_9518_dongle.h b/board_9518_dongle.h new file mode 100644 index 0000000..a8ac8f4 --- /dev/null +++ b/board_9518_dongle.h @@ -0,0 +1,134 @@ +/******************************************************************************************************** + * @file board_9518_dongle.h + * + * @brief This is the header file for board_9518_dongle + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#pragma once + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + + +// BUTTON +#define BUTTON1 GPIO_PB2//SW2 +#define PB2_FUNC AS_GPIO +#define PB2_OUTPUT_ENABLE 0 +#define PB2_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PB2 GPIO_PIN_PULLUP_10K + +#define BUTTON2 GPIO_PB3//SW7 +#define PB3_FUNC AS_GPIO +#define PB3_OUTPUT_ENABLE 0 +#define PB3_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PB3 GPIO_PIN_PULLUP_10K + +// LED +/*************************************************************** +* LED_R GPIO_PB4 //D9 -- red PWM0 +* LED_G GPIO_PB0 //D6 -- green PWM5 +* LED_B GPIO_PB7 //D8 -- blue PWM2 +* LED_Y GPIO_PB5 //D7 -- yellow PWM1 +* +* LED_B2 GPIO_PB1 //D10 -- blue PWM3 +* LED_B3 GPIO_PE3 //D11 -- blue PWM0 +****************************************************************/ +#if defined COLOR_RGB_SUPPORT && (COLOR_RGB_SUPPORT == 1) + #error "To do!" +#else +//PWM configuration, LED_R as warm light, LED_B1 as cool light. +#define LED_R GPIO_PB4 +#define LED_B GPIO_PB7 + +#define PWM_R_CHANNEL 0 //PWM0 +#define PWM_R_CHANNEL_SET() do{\ + pwm_set_pin(LED_R); \ + }while(0) + +#define PWM_B_CHANNEL 2 //PWM2 +#define PWM_B_CHANNEL_SET() do{\ + pwm_set_pin(LED_B); \ + }while(0) + +#define WARM_LIGHT_PWM_CHANNEL PWM_R_CHANNEL +#define COOL_LIGHT_PWM_CHANNEL PWM_B_CHANNEL +#define WARM_LIGHT_PWM_SET() PWM_R_CHANNEL_SET() +#define COOL_LIGHT_PWM_SET() PWM_B_CHANNEL_SET() + +//Others as GPIO. +#define LED_Y GPIO_PB5 +#define LED_G GPIO_PB0 +#define LED_B2 GPIO_PB1 +#define LED_B3 GPIO_PE3 + +#define PB5_FUNC AS_GPIO +#define PB5_OUTPUT_ENABLE 1 +#define PB5_INPUT_ENABLE 0 + +#define PB0_FUNC AS_GPIO +#define PB0_OUTPUT_ENABLE 1 +#define PB0_INPUT_ENABLE 0 + +#define PB1_FUNC AS_GPIO +#define PB1_OUTPUT_ENABLE 1 +#define PB1_INPUT_ENABLE 0 + +#define PE3_FUNC AS_GPIO +#define PE3_OUTPUT_ENABLE 1 +#define PE3_INPUT_ENABLE 0 + +#define LED_POWER LED_Y +#define LED_PERMIT LED_G +#endif + +// UART +#if ZBHCI_UART + #error please configurate uart PIN!!!!!! +#endif + +// DEBUG +#if UART_PRINTF_MODE + #define DEBUG_INFO_TX_PIN GPIO_PC1//print +#endif + + +enum{ + VK_SW1 = 0x01, + VK_SW2 = 0x02, +}; + +#define KB_MAP_NORMAL {\ + {VK_SW1,}, \ + {VK_SW2,}, } + +#define KB_MAP_NUM KB_MAP_NORMAL +#define KB_MAP_FN KB_MAP_NORMAL + +#define KB_DRIVE_PINS {NULL} +#define KB_SCAN_PINS {BUTTON1, BUTTON2} + + + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +} +#endif diff --git a/board_9518_evk.h b/board_9518_evk.h new file mode 100644 index 0000000..575957f --- /dev/null +++ b/board_9518_evk.h @@ -0,0 +1,136 @@ +/******************************************************************************************************** + * @file board_9518_evk.h + * + * @brief This is the header file for board_9518_evk + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#pragma once + +/* Enable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +extern "C" { +#endif + + +// BUTTON +#define BUTTON1 GPIO_PC2 +#define PC2_FUNC AS_GPIO +#define PC2_OUTPUT_ENABLE 0 +#define PC2_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PC2 GPIO_PIN_PULLDOWN_100K + +#define BUTTON2 GPIO_PC0 +#define PC0_FUNC AS_GPIO +#define PC0_OUTPUT_ENABLE 0 +#define PC0_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PC0 GPIO_PIN_PULLDOWN_100K + +#define BUTTON3 GPIO_PC3 +#define PC3_FUNC AS_GPIO +#define PC3_OUTPUT_ENABLE 0 +#define PC3_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PC3 GPIO_PIN_PULLUP_10K + +#define BUTTON4 GPIO_PC1 +#define PC1_FUNC AS_GPIO +#define PC1_OUTPUT_ENABLE 0 +#define PC1_INPUT_ENABLE 1 +#define PULL_WAKEUP_SRC_PC1 GPIO_PIN_PULLUP_10K + +// LED +/*************************************************************** +* LED_R GPIO_PB7 //D4 -- red +* LED_G GPIO_PB5 //D2 -- green +* LED_B GPIO_PB4 //D1 -- blue +* LED_W GPIO_PB6 //D3 -- white +****************************************************************/ +#if defined COLOR_RGB_SUPPORT && (COLOR_RGB_SUPPORT == 1) + #error "To do!" +#else +//PWM configuration, LED_R as warm light, LED_B as cool light. +#define LED_R GPIO_PB7 +#define LED_B GPIO_PB4 + +#define PWM_R_CHANNEL 2 //PWM2 +#define PWM_R_CHANNEL_SET() do{\ + pwm_set_pin(LED_R); \ + }while(0) + +#define PWM_B_CHANNEL 0 //PWM0 +#define PWM_B_CHANNEL_SET() do{\ + pwm_set_pin(LED_B); \ + }while(0) + +#define WARM_LIGHT_PWM_CHANNEL PWM_R_CHANNEL +#define COOL_LIGHT_PWM_CHANNEL PWM_B_CHANNEL +#define WARM_LIGHT_PWM_SET() PWM_R_CHANNEL_SET() +#define COOL_LIGHT_PWM_SET() PWM_B_CHANNEL_SET() + +//LED_W and LED_G as GPIO. +#define LED_W GPIO_PB6 +#define LED_G GPIO_PB5 + +#define PB6_FUNC AS_GPIO +#define PB6_OUTPUT_ENABLE 1 +#define PB6_INPUT_ENABLE 0 + +#define PB5_FUNC AS_GPIO +#define PB5_OUTPUT_ENABLE 1 +#define PB5_INPUT_ENABLE 0 + +#define LED_POWER LED_W +#define LED_PERMIT LED_G +#endif + +// UART +#if ZBHCI_UART + #error please configurate uart PIN!!!!!! +#endif + +// DEBUG +#if UART_PRINTF_MODE + #define DEBUG_INFO_TX_PIN GPIO_PC7//print +#endif + + +enum{ + VK_SW1 = 0x01, + VK_SW2 = 0x02, + VK_SW3 = 0x03, + VK_SW4 = 0x04 +}; + +#define KB_MAP_NORMAL {\ + {VK_SW1, VK_SW3}, \ + {VK_SW2, VK_SW4}, } + +#define KB_MAP_NUM KB_MAP_NORMAL +#define KB_MAP_FN KB_MAP_NORMAL + +#define KB_DRIVE_PINS {GPIO_PC2, GPIO_PC0} +#define KB_SCAN_PINS {GPIO_PC3, GPIO_PC1} + +#define KB_LINE_MODE 0 +#define KB_LINE_HIGH_VALID 0 + +/* Disable C linkage for C++ Compilers: */ +#if defined(__cplusplus) +} +#endif diff --git a/sampleLight.c b/sampleLight.c new file mode 100644 index 0000000..5aadc43 --- /dev/null +++ b/sampleLight.c @@ -0,0 +1,314 @@ +/******************************************************************************************************** + * @file sampleLight.c + * + * @brief This is the source file for sampleLight + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#if (__PROJECT_TL_DIMMABLE_LIGHT__) + +/********************************************************************** + * INCLUDES + */ +#include "tl_common.h" +#include "zb_api.h" +#include "zcl_include.h" +#include "bdb.h" +#include "ota.h" +#include "gp.h" +#include "sampleLight.h" +#include "sampleLightCtrl.h" +#include "app_ui.h" +#include "factory_reset.h" +#if ZBHCI_EN +#include "zbhci.h" +#endif +#if ZCL_WWAH_SUPPORT +#include "wwah.h" +#endif + +/********************************************************************** + * LOCAL CONSTANTS + */ + + +/********************************************************************** + * TYPEDEFS + */ + + +/********************************************************************** + * GLOBAL VARIABLES + */ +app_ctx_t gLightCtx; + + +#ifdef ZCL_OTA +extern ota_callBack_t sampleLight_otaCb; + +//running code firmware information +ota_preamble_t sampleLight_otaInfo = { + .fileVer = FILE_VERSION, + .imageType = IMAGE_TYPE, + .manufacturerCode = MANUFACTURER_CODE_TELINK, +}; +#endif + + +//Must declare the application call back function which used by ZDO layer +const zdo_appIndCb_t appCbLst = { + bdb_zdoStartDevCnf,//start device cnf cb + NULL,//reset cnf cb + NULL,//device announce indication cb + sampleLight_leaveIndHandler,//leave ind cb + sampleLight_leaveCnfHandler,//leave cnf cb + sampleLight_nwkUpdateIndicateHandler,//nwk update ind cb + NULL,//permit join ind cb + NULL,//nlme sync cnf cb + NULL,//tc join ind cb + NULL,//tc detects that the frame counter is near limit +}; + + +/** + * @brief Definition for bdb commissioning setting + */ +bdb_commissionSetting_t g_bdbCommissionSetting = { + .linkKey.tcLinkKey.keyType = SS_GLOBAL_LINK_KEY, + .linkKey.tcLinkKey.key = (u8 *)tcLinkKeyCentralDefault, //can use unique link key stored in NV + + .linkKey.distributeLinkKey.keyType = MASTER_KEY, + .linkKey.distributeLinkKey.key = (u8 *)linkKeyDistributedMaster, //use linkKeyDistributedCertification before testing + + .linkKey.touchLinkKey.keyType = MASTER_KEY, + .linkKey.touchLinkKey.key = (u8 *)touchLinkKeyMaster, //use touchLinkKeyCertification before testing + +#if TOUCHLINK_SUPPORT + .touchlinkEnable = 1, /* enable touch-link */ +#else + .touchlinkEnable = 0, /* disable touch-link */ +#endif + .touchlinkChannel = DEFAULT_CHANNEL, /* touch-link default operation channel for target */ + .touchlinkLqiThreshold = 0xA0, /* threshold for touch-link scan req/resp command */ +}; + +/********************************************************************** + * LOCAL VARIABLES + */ +ev_timer_event_t *sampleLightAttrsStoreTimerEvt = NULL; + + +/********************************************************************** + * FUNCTIONS + */ + +/********************************************************************* + * @fn stack_init + * + * @brief This function initialize the ZigBee stack and related profile. If HA/ZLL profile is + * enabled in this application, related cluster should be registered here. + * + * @param None + * + * @return None + */ +void stack_init(void) +{ + /* Initialize ZB stack */ + zb_init(); + + /* Register stack CB */ + zb_zdoCbRegister((zdo_appIndCb_t *)&appCbLst); +} + +/********************************************************************* + * @fn user_app_init + * + * @brief This function initialize the application(Endpoint) information for this node. + * + * @param None + * + * @return None + */ +void user_app_init(void) +{ + af_nodeDescManuCodeUpdate(MANUFACTURER_CODE_TELINK); + + /* Initialize ZCL layer */ + /* Register Incoming ZCL Foundation command/response messages */ + zcl_init(sampleLight_zclProcessIncomingMsg); + + /* Register endPoint */ + af_endpointRegister(SAMPLE_LIGHT_ENDPOINT, (af_simple_descriptor_t *)&sampleLight_simpleDesc, zcl_rx_handler, NULL); +#if AF_TEST_ENABLE + /* A sample of AF data handler. */ + af_endpointRegister(SAMPLE_TEST_ENDPOINT, (af_simple_descriptor_t *)&sampleTestDesc, afTest_rx_handler, afTest_dataSendConfirm); +#endif + + /* Initialize or restore attributes, this must before 'zcl_register()' */ + zcl_sampleLightAttrsInit(); + zcl_reportingTabInit(); + + /* Register ZCL specific cluster information */ + zcl_register(SAMPLE_LIGHT_ENDPOINT, SAMPLELIGHT_CB_CLUSTER_NUM, (zcl_specClusterInfo_t *)g_sampleLightClusterList); + +#if ZCL_GP_SUPPORT + /* Initialize GP */ + gp_init(); +#endif + +#if ZCL_OTA_SUPPORT + /* Initialize OTA */ + ota_init(OTA_TYPE_CLIENT, (af_simple_descriptor_t *)&sampleLight_simpleDesc, &sampleLight_otaInfo, &sampleLight_otaCb); +#endif + +#if ZCL_WWAH_SUPPORT + /* Initialize WWAH server */ + wwah_init(WWAH_TYPE_SERVER, (af_simple_descriptor_t *)&sampleLight_simpleDesc); +#endif +} + + + +s32 sampleLightAttrsStoreTimerCb(void *arg) +{ + zcl_onOffAttr_save(); + zcl_levelAttr_save(); + zcl_colorCtrlAttr_save(); + + sampleLightAttrsStoreTimerEvt = NULL; + return -1; +} + +void sampleLightAttrsStoreTimerStart(void) +{ + if(sampleLightAttrsStoreTimerEvt){ + TL_ZB_TIMER_CANCEL(&sampleLightAttrsStoreTimerEvt); + } + sampleLightAttrsStoreTimerEvt = TL_ZB_TIMER_SCHEDULE(sampleLightAttrsStoreTimerCb, NULL, 200); +} + +void sampleLightAttrsChk(void) +{ + if(gLightCtx.lightAttrsChanged){ + gLightCtx.lightAttrsChanged = FALSE; + if(zb_isDeviceJoinedNwk()){ + sampleLightAttrsStoreTimerStart(); + } + } +} + +void report_handler(void) +{ + if(zb_isDeviceJoinedNwk()){ + if(zcl_reportingEntryActiveNumGet()){ + u16 second = 1;//TODO: fix me + + reportNoMinLimit(); + + //start report timer + reportAttrTimerStart(second); + }else{ + //stop report timer + reportAttrTimerStop(); + } + } +} + +void app_task(void) +{ + app_key_handler(); + localPermitJoinState(); + if(BDB_STATE_GET() == BDB_STATE_IDLE){ + //factroyRst_handler(); + + report_handler(); + +#if 0/* NOTE: If set to '1', the latest status of lighting will be stored. */ + sampleLightAttrsChk(); +#endif + } +} + +static void sampleLightSysException(void) +{ + zcl_onOffAttr_save(); + zcl_levelAttr_save(); + zcl_colorCtrlAttr_save(); + + SYSTEM_RESET(); + //led_on(LED_POWER); + //while(1); +} + +/********************************************************************* + * @fn user_init + * + * @brief User level initialization code. + * + * @param isRetention - if it is waking up with ram retention. + * + * @return None + */ +void user_init(bool isRetention) +{ + (void)isRetention; + + /* Initialize LEDs*/ + led_init(); + hwLight_init(); + + //factroyRst_init(); + + /* Initialize Stack */ + stack_init(); + + /* Initialize user application */ + user_app_init(); + + /* Register except handler for test */ + sys_exceptHandlerRegister(sampleLightSysException); + + /* Adjust light state to default attributes*/ + light_adjust(); + + /* User's Task */ +#if ZBHCI_EN + zbhciInit(); + ev_on_poll(EV_POLL_HCI, zbhciTask); +#endif + ev_on_poll(EV_POLL_IDLE, app_task); + + /* Read the pre-install code from NV */ + if(bdb_preInstallCodeLoad(&gLightCtx.tcLinkKey.keyType, gLightCtx.tcLinkKey.key) == RET_OK){ + g_bdbCommissionSetting.linkKey.tcLinkKey.keyType = gLightCtx.tcLinkKey.keyType; + g_bdbCommissionSetting.linkKey.tcLinkKey.key = gLightCtx.tcLinkKey.key; + } + + /* Set default reporting configuration */ + u8 reportableChange = 0x00; + bdb_defaultReportingCfg(SAMPLE_LIGHT_ENDPOINT, HA_PROFILE_ID, ZCL_CLUSTER_GEN_ON_OFF, ZCL_ATTRID_ONOFF, + 0x0000, 0x003c, (u8 *)&reportableChange); + + /* Initialize BDB */ + bdb_init((af_simple_descriptor_t *)&sampleLight_simpleDesc, &g_bdbCommissionSetting, &g_zbDemoBdbCb, 1); +} + +#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */ + diff --git a/sampleLight.h b/sampleLight.h new file mode 100644 index 0000000..6d255ea --- /dev/null +++ b/sampleLight.h @@ -0,0 +1,233 @@ +/******************************************************************************************************** + * @file sampleLight.h + * + * @brief This is the header file for sampleLight + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef _SAMPLE_LIGHT_H_ +#define _SAMPLE_LIGHT_H_ + + + +/********************************************************************** + * CONSTANT + */ +#define SAMPLE_LIGHT_ENDPOINT 0x01 +#define SAMPLE_TEST_ENDPOINT 0x02 + +/********************************************************************** + * TYPEDEFS + */ +typedef struct{ + u8 keyType; /* ERTIFICATION_KEY or MASTER_KEY key for touch-link or distribute network + SS_UNIQUE_LINK_KEY or SS_GLOBAL_LINK_KEY for distribute network */ + u8 key[16]; /* the key used */ +}app_linkKey_info_t; + +typedef struct{ + ev_timer_event_t *timerLedEvt; + u32 keyPressedTime; + + u16 ledOnTime; + u16 ledOffTime; + u8 oriSta; //original state before blink + u8 sta; //current state in blink + u8 times; //blink times + u8 state; + + bool bdbFindBindFlg; + bool lightAttrsChanged; + + app_linkKey_info_t tcLinkKey; +}app_ctx_t; + +/** + * @brief Defined for basic cluster attributes + */ +typedef struct{ + u8 zclVersion; + u8 appVersion; + u8 stackVersion; + u8 hwVersion; + u8 manuName[ZCL_BASIC_MAX_LENGTH]; + u8 modelId[ZCL_BASIC_MAX_LENGTH]; + u8 swBuildId[ZCL_BASIC_MAX_LENGTH]; + u8 powerSource; + u8 deviceEnable; +}zcl_basicAttr_t; + +/** + * @brief Defined for identify cluster attributes + */ +typedef struct{ + u16 identifyTime; +}zcl_identifyAttr_t; + +/** + * @brief Defined for group cluster attributes + */ +typedef struct{ + u8 nameSupport; +}zcl_groupAttr_t; + +/** + * @brief Defined for scene cluster attributes + */ +typedef struct{ + u8 sceneCount; + u8 currentScene; + u8 nameSupport; + bool sceneValid; + u16 currentGroup; +}zcl_sceneAttr_t; + +/** + * @brief Defined for on/off cluster attributes + */ +typedef struct{ + u16 onTime; + u16 offWaitTime; + u8 startUpOnOff; + bool onOff; + bool globalSceneControl; +}zcl_onOffAttr_t; + +/** + * @brief Defined for level cluster attributes + */ +typedef struct{ + u16 remainingTime; + u8 curLevel; + u8 startUpCurrentLevel; +}zcl_levelAttr_t; + +/** + * @brief Defined for color control cluster attributes + */ +typedef struct{ + u8 colorMode; + u8 options; + u8 enhancedColorMode; + u8 numOfPrimaries; + u16 colorCapabilities; +#if COLOR_RGB_SUPPORT + u8 currentHue; + u8 currentSaturation; + u8 colorLoopActive; + u8 colorLoopDirection; + u16 colorLoopTime; + u16 colorLoopStartEnhancedHue; + u16 colorLoopStoredEnhancedHue; +#elif COLOR_CCT_SUPPORT + u16 colorTemperatureMireds; + u16 colorTempPhysicalMinMireds; + u16 colorTempPhysicalMaxMireds; + u16 startUpColorTemperatureMireds; +#endif +}zcl_lightColorCtrlAttr_t; + +/** + * @brief Defined for saving on/off attributes + */ +typedef struct { + u8 onOff; + u8 startUpOnOff; +}zcl_nv_onOff_t; + +/** + * @brief Defined for saving level attributes + */ +typedef struct { + u8 curLevel; + u8 startUpCurLevel; +}zcl_nv_level_t; + +/** + * @brief Defined for saving color control attributes + */ +typedef struct { +#if COLOR_RGB_SUPPORT + u8 currentHue; + u8 currentSaturation; +#elif COLOR_CCT_SUPPORT + u16 colorTemperatureMireds; + u16 startUpColorTemperatureMireds; +#endif +}zcl_nv_colorCtrl_t; + +/********************************************************************** + * GLOBAL VARIABLES + */ +extern app_ctx_t gLightCtx; +extern bdb_commissionSetting_t g_bdbCommissionSetting; +extern bdb_appCb_t g_zbDemoBdbCb; + + +extern u8 SAMPLELIGHT_CB_CLUSTER_NUM; +extern const zcl_specClusterInfo_t g_sampleLightClusterList[]; +extern const af_simple_descriptor_t sampleLight_simpleDesc; +#if AF_TEST_ENABLE +extern const af_simple_descriptor_t sampleTestDesc; +#endif + +/* Attributes */ +extern zcl_basicAttr_t g_zcl_basicAttrs; +extern zcl_identifyAttr_t g_zcl_identifyAttrs; +extern zcl_groupAttr_t g_zcl_groupAttrs; +extern zcl_sceneAttr_t g_zcl_sceneAttrs; +extern zcl_onOffAttr_t g_zcl_onOffAttrs; +extern zcl_levelAttr_t g_zcl_levelAttrs; +extern zcl_lightColorCtrlAttr_t g_zcl_colorCtrlAttrs; + +#define zcl_sceneAttrGet() &g_zcl_sceneAttrs +#define zcl_onoffAttrGet() &g_zcl_onOffAttrs +#define zcl_levelAttrGet() &g_zcl_levelAttrs +#define zcl_colorAttrGet() &g_zcl_colorCtrlAttrs + +/********************************************************************** + * FUNCTIONS + */ +void sampleLight_zclProcessIncomingMsg(zclIncoming_t *pInHdlrMsg); + +status_t sampleLight_basicCb(zclIncomingAddrInfo_t *pAddrInfo, u8 cmdId, void *cmdPayload); +status_t sampleLight_identifyCb(zclIncomingAddrInfo_t *pAddrInfo, u8 cmdId, void *cmdPayload); +status_t sampleLight_sceneCb(zclIncomingAddrInfo_t *pAddrInfo, u8 cmdId, void *cmdPayload); +status_t sampleLight_onOffCb(zclIncomingAddrInfo_t *pAddrInfo, u8 cmdId, void *cmdPayload); +status_t sampleLight_levelCb(zclIncomingAddrInfo_t *pAddrInfo, u8 cmdId, void *cmdPayload); +status_t sampleLight_colorCtrlCb(zclIncomingAddrInfo_t *pAddrInfo, u8 cmdId, void *cmdPayload); + +void sampleLight_leaveCnfHandler(nlme_leave_cnf_t *pLeaveCnf); +void sampleLight_leaveIndHandler(nlme_leave_ind_t *pLeaveInd); +void sampleLight_otaProcessMsgHandler(u8 evt, u8 status); +u8 sampleLight_nwkUpdateIndicateHandler(nwkCmd_nwkUpdate_t *pNwkUpdate); + +void sampleLight_onoff(u8 cmd); + +void zcl_sampleLightAttrsInit(void); +nv_sts_t zcl_onOffAttr_save(void); +nv_sts_t zcl_levelAttr_save(void); +nv_sts_t zcl_colorCtrlAttr_save(void); + +#if AF_TEST_ENABLE +void afTest_rx_handler(void *arg); +void afTest_dataSendConfirm(void *arg); +#endif + +#endif /* _SAMPLE_LIGHT_H_ */ diff --git a/sampleLightCtrl.c b/sampleLightCtrl.c new file mode 100644 index 0000000..270ec02 --- /dev/null +++ b/sampleLightCtrl.c @@ -0,0 +1,557 @@ +/******************************************************************************************************** + * @file sampleLightCtrl.c + * + * @brief This is the source file for sampleLightCtrl + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#if (__PROJECT_TL_DIMMABLE_LIGHT__) + +/********************************************************************** + * INCLUDES + */ +#include "tl_common.h" +#include "zcl_include.h" +#include "sampleLight.h" +#include "sampleLightCtrl.h" + + +/********************************************************************** + * LOCAL CONSTANTS + */ +#define PWM_FREQUENCY 1000 //1KHz +#define PWM_FULL_DUTYCYCLE 100 +#define PMW_MAX_TICK (PWM_CLOCK_SOURCE / PWM_FREQUENCY) + + +/********************************************************************** + * TYPEDEFS + */ + + +/********************************************************************** + * GLOBAL VARIABLES + */ + + +/********************************************************************** + * FUNCTIONS + */ +extern void sampleLight_updateOnOff(void); +extern void sampleLight_updateLevel(void); +extern void sampleLight_updateColor(void); + +extern void sampleLight_onOffInit(void); +extern void sampleLight_levelInit(void); +extern void sampleLight_colorInit(void); + +/********************************************************************* + * @fn pwmSetDuty + * + * @brief + * + * @param ch - PWM channel + * dutycycle - level * PWM_FULL_DUTYCYCLE + * + * @return None + */ +void pwmSetDuty(u8 ch, u16 dutycycle) +{ +#ifdef ZCL_LEVEL_CTRL + u32 cmp_tick = ((u32)dutycycle * PMW_MAX_TICK) / (ZCL_LEVEL_ATTR_MAX_LEVEL * PWM_FULL_DUTYCYCLE); + drv_pwm_cfg(ch, (u16)cmp_tick, PMW_MAX_TICK); +#endif +} + +/********************************************************************* + * @fn pwmInit + * + * @brief + * + * @param ch - PWM channel + * dutycycle - level * PWM_FULL_DUTYCYCLE + * + * @return None + */ +void pwmInit(u8 ch, u16 dutycycle) +{ + pwmSetDuty(ch, dutycycle); +} + +/********************************************************************* + * @fn hwLight_init + * + * @brief + * + * @param None + * + * @return None + */ +void hwLight_init(void) +{ + drv_pwm_init(); + +#if COLOR_RGB_SUPPORT + R_LIGHT_PWM_SET(); + G_LIGHT_PWM_SET(); + B_LIGHT_PWM_SET(); + pwmInit(R_LIGHT_PWM_CHANNEL, 0); + pwmInit(G_LIGHT_PWM_CHANNEL, 0); + pwmInit(B_LIGHT_PWM_CHANNEL, 0); +#else + COOL_LIGHT_PWM_SET(); + pwmInit(COOL_LIGHT_PWM_CHANNEL, 0); +#if COLOR_CCT_SUPPORT + WARM_LIGHT_PWM_SET(); + pwmInit(WARM_LIGHT_PWM_CHANNEL, 0); +#endif +#endif +} + +/********************************************************************* + * @fn hwLight_onOffUpdate + * + * @brief + * + * @param onOff - onOff attribute value + * + * @return None + */ +void hwLight_onOffUpdate(u8 onOff) +{ + if(onOff){ +#if COLOR_RGB_SUPPORT + drv_pwm_start(R_LIGHT_PWM_CHANNEL); + drv_pwm_start(G_LIGHT_PWM_CHANNEL); + drv_pwm_start(B_LIGHT_PWM_CHANNEL); +#else +#if COLOR_CCT_SUPPORT + drv_pwm_start(WARM_LIGHT_PWM_CHANNEL); +#endif + drv_pwm_start(COOL_LIGHT_PWM_CHANNEL); +#endif + }else{ +#if COLOR_RGB_SUPPORT + drv_pwm_stop(R_LIGHT_PWM_CHANNEL); + drv_pwm_stop(G_LIGHT_PWM_CHANNEL); + drv_pwm_stop(B_LIGHT_PWM_CHANNEL); +#else +#if COLOR_CCT_SUPPORT + drv_pwm_stop(WARM_LIGHT_PWM_CHANNEL); +#endif + drv_pwm_stop(COOL_LIGHT_PWM_CHANNEL); +#endif + } +} + +/********************************************************************* + * @fn hwLight_levelUpdate + * + * @brief + * + * @param level - level attribute value + * + * @return None + */ +void hwLight_levelUpdate(u8 level) +{ +#if !defined COLOR_RGB_SUPPORT || (COLOR_RGB_SUPPORT == 0) + level = (level < 0x10) ? 0x10 : level; + + u16 gammaCorrectLevel = ((u16)level * level) / ZCL_LEVEL_ATTR_MAX_LEVEL; + + pwmSetDuty(COOL_LIGHT_PWM_CHANNEL, gammaCorrectLevel * PWM_FULL_DUTYCYCLE); +#endif +} + +/********************************************************************* + * @fn temperatureToCW + * + * @brief + * + * @param [in]colorTemperatureMireds - colorTemperatureMireds attribute value + * [in]level - level attribute value + * [out]C - cool light PWM + * [out]W - warm light PWM + * + * @return None + */ +void temperatureToCW(u16 temperatureMireds, u8 level, u8 *C, u8 *W) +{ +#if COLOR_CCT_SUPPORT + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + *W = (u8)(((temperatureMireds - pColor->colorTempPhysicalMinMireds) * level) / (pColor->colorTempPhysicalMaxMireds - pColor->colorTempPhysicalMinMireds)); + *C = level - (*W); +#endif +} + +/********************************************************************* + * @fn hwLight_colorUpdate_colorTemperature + * + * @brief + * + * @param colorTemperatureMireds - colorTemperatureMireds attribute value + * level - level attribute value + * + * @return None + */ +void hwLight_colorUpdate_colorTemperature(u16 colorTemperatureMireds, u8 level) +{ +#if COLOR_CCT_SUPPORT + u8 C = 0; + u8 W = 0; + + level = (level < 0x10) ? 0x10 : level; + + temperatureToCW(colorTemperatureMireds, level, &C, &W); + + u16 gammaCorrectC = ((u16)C * C) / ZCL_LEVEL_ATTR_MAX_LEVEL; + u16 gammaCorrectW = ((u16)W * W) / ZCL_LEVEL_ATTR_MAX_LEVEL; + + pwmSetDuty(COOL_LIGHT_PWM_CHANNEL, gammaCorrectC * PWM_FULL_DUTYCYCLE); + pwmSetDuty(WARM_LIGHT_PWM_CHANNEL, gammaCorrectW * PWM_FULL_DUTYCYCLE); +#endif +} + +/********************************************************************* + * @fn hsvToRGB + * + * @brief + * + * @param [in]hue - hue attribute value + * [in]saturation - saturation attribute value + * [in]level - level attribute value + * [out]R - R light PWM + * [out]G - G light PWM + * [out]B - B light PWM + * + * @return None + */ +void hsvToRGB(u8 hue, u8 saturation, u8 level, u8 *R, u8 *G, u8 *B) +{ +#if COLOR_RGB_SUPPORT + u8 region; + u8 remainder; + u8 p, q, t; + + u16 rHue = (u16)hue * 360 / ZCL_COLOR_ATTR_HUE_MAX; + u8 rS = saturation; + u8 rV = level; + + if(saturation == 0){ + *R = rV; + *G = rV; + *B = rV; + return; + } + + if(rHue < 360){ + region = rHue / 60; + }else{ + region = 0; + } + + remainder = (rHue - (region * 60)) * 4; + + p = (rV * (255 - rS)) >> 8; + q = (rV * (255 - ((rS * remainder) >> 8))) >> 8; + t = (rV * (255 - ((rS * (255 - remainder)) >> 8))) >> 8; + + if (region == 0) { + *R = rV; + *G = t; + *B = p; + } else if (region == 1) { + *R = q; + *G = rV; + *B = p; + } else if (region == 2) { + *R = p; + *G = rV; + *B = t; + } else if (region == 3) { + *R = p; + *G = q; + *B = rV; + } else if (region == 4) { + *R = t; + *G = p; + *B = rV; + } else { + *R = rV; + *G = p; + *B = q; + } +#endif +} + +/********************************************************************* + * @fn hwLight_colorUpdate_HSV2RGB + * + * @brief + * + * @param hue - hue attribute value + * saturation - saturation attribute value + * level - level attribute value + * + * @return None + */ +void hwLight_colorUpdate_HSV2RGB(u8 hue, u8 saturation, u8 level) +{ +#if COLOR_RGB_SUPPORT + u8 R = 0; + u8 G = 0; + u8 B = 0; + + level = (level < 0x10) ? 0x10 : level; + + hsvToRGB(hue, saturation, level, &R, &G, &B); + + u16 gammaCorrectR = ((u16)R * R) / ZCL_LEVEL_ATTR_MAX_LEVEL; + u16 gammaCorrectG = ((u16)G * G) / ZCL_LEVEL_ATTR_MAX_LEVEL; + u16 gammaCorrectB = ((u16)B * B) / ZCL_LEVEL_ATTR_MAX_LEVEL; + + pwmSetDuty(PWM_R_CHANNEL, gammaCorrectR * PWM_FULL_DUTYCYCLE); + pwmSetDuty(PWM_G_CHANNEL, gammaCorrectG * PWM_FULL_DUTYCYCLE); + pwmSetDuty(PWM_B_CHANNEL, gammaCorrectB * PWM_FULL_DUTYCYCLE); +#endif +} + +/********************************************************************* + * @fn light_adjust + * + * @brief + * + * @param None + * + * @return None + */ +void light_adjust(void) +{ +#ifdef ZCL_LIGHT_COLOR_CONTROL + sampleLight_colorInit(); +#else +#ifdef ZCL_LEVEL_CTRL + sampleLight_levelInit(); +#endif +#endif + sampleLight_onOffInit(); +} + +/********************************************************************* + * @fn light_fresh + * + * @brief + * + * @param None + * + * @return None + */ +void light_fresh(void) +{ +#ifdef ZCL_LIGHT_COLOR_CONTROL + sampleLight_updateColor(); +#else +#ifdef ZCL_LEVEL_CTRL + sampleLight_updateLevel(); +#else + pwmSetDuty(COOL_LIGHT_PWM_CHANNEL, ZCL_LEVEL_ATTR_MAX_LEVEL * PWM_FULL_DUTYCYCLE); +#endif +#endif + sampleLight_updateOnOff(); + + gLightCtx.lightAttrsChanged = TRUE; +} + +/********************************************************************* + * @fn light_applyUpdate + * + * @brief + * + * @param + * + * @return None + */ +void light_applyUpdate(u8 *curLevel, u16 *curLevel256, s32 *stepLevel256, u16 *remainingTime, u8 minLevel, u8 maxLevel, bool wrap) +{ + if((*stepLevel256 > 0) && ((((s32)*curLevel256 + *stepLevel256) / 256) > maxLevel)){ + *curLevel256 = (wrap) ? ((u16)minLevel * 256 + ((*curLevel256 + *stepLevel256) - (u16)maxLevel * 256) - 256) + : ((u16)maxLevel * 256); + }else if((*stepLevel256 < 0) && ((((s32)*curLevel256 + *stepLevel256) / 256) < minLevel)){ + *curLevel256 = (wrap) ? ((u16)maxLevel * 256 - ((u16)minLevel * 256 - ((s32)*curLevel256 + *stepLevel256)) + 256) + : ((u16)minLevel * 256); + }else{ + *curLevel256 += *stepLevel256; + } + + if(*stepLevel256 > 0){ + *curLevel = (*curLevel256 + 127) / 256; + }else{ + *curLevel = *curLevel256 / 256; + } + + if(*remainingTime == 0){ + *curLevel256 = ((u16)*curLevel) * 256; + *stepLevel256 = 0; + }else if(*remainingTime != 0xFFFF){ + *remainingTime = *remainingTime -1; + } + + light_fresh(); +} + +/********************************************************************* + * @fn light_applyUpdate_16 + * + * @brief + * + * @param + * + * @return None + */ +void light_applyUpdate_16(u16 *curLevel, u32 *curLevel256, s32 *stepLevel256, u16 *remainingTime, u16 minLevel, u16 maxLevel, bool wrap) +{ + if((*stepLevel256 > 0) && ((((s32)*curLevel256 + *stepLevel256) / 256) > maxLevel)){ + *curLevel256 = (wrap) ? ((u32)minLevel * 256 + ((*curLevel256 + *stepLevel256) - (u32)maxLevel * 256) - 256) + : ((u32)maxLevel * 256); + }else if((*stepLevel256 < 0) && ((((s32)*curLevel256 + *stepLevel256) / 256) < minLevel)){ + *curLevel256 = (wrap) ? ((u32)maxLevel * 256 - ((u32)minLevel * 256 - ((s32)*curLevel256 + *stepLevel256)) + 256) + : ((u32)minLevel * 256); + }else{ + *curLevel256 += *stepLevel256; + } + + if(*stepLevel256 > 0){ + *curLevel = (*curLevel256 + 127) / 256; + }else{ + *curLevel = *curLevel256 / 256; + } + + if(*remainingTime == 0){ + *curLevel256 = ((u32)*curLevel) * 256; + *stepLevel256 = 0; + }else if(*remainingTime != 0xFFFF){ + *remainingTime = *remainingTime -1; + } + + light_fresh(); +} + +/********************************************************************* + * @fn light_blink_TimerEvtCb + * + * @brief + * + * @param arg + * + * @return 0: timer continue on; -1: timer will be canceled + */ +s32 light_blink_TimerEvtCb(void *arg) +{ + u32 interval = 0; + + if(gLightCtx.sta == gLightCtx.oriSta){ + if(gLightCtx.times){ + gLightCtx.times--; + if(gLightCtx.times <= 0){ + if(gLightCtx.oriSta){ + hwLight_onOffUpdate(ZCL_CMD_ONOFF_ON); + }else{ + hwLight_onOffUpdate(ZCL_CMD_ONOFF_OFF); + } + + gLightCtx.timerLedEvt = NULL; + return -1; + } + } + } + + gLightCtx.sta = !gLightCtx.sta; + if(gLightCtx.sta){ + hwLight_onOffUpdate(ZCL_CMD_ONOFF_ON); + interval = gLightCtx.ledOnTime; + }else{ + hwLight_onOffUpdate(ZCL_CMD_ONOFF_OFF); + interval = gLightCtx.ledOffTime; + } + + return interval; +} + +/********************************************************************* + * @fn light_blink_start + * + * @brief + * + * @param times - counts + * @param ledOnTime - on times, ms + * @param ledOffTime - off times, ms + * + * @return None + */ +void light_blink_start(u8 times, u16 ledOnTime, u16 ledOffTime) +{ + u32 interval = 0; + zcl_onOffAttr_t *pOnoff = zcl_onoffAttrGet(); + + gLightCtx.oriSta = pOnoff->onOff; + gLightCtx.times = times; + + if(!gLightCtx.timerLedEvt){ + if(gLightCtx.oriSta){ + hwLight_onOffUpdate(ZCL_CMD_ONOFF_OFF); + gLightCtx.sta = 0; + interval = ledOffTime; + }else{ + hwLight_onOffUpdate(ZCL_CMD_ONOFF_ON); + gLightCtx.sta = 1; + interval = ledOnTime; + } + gLightCtx.ledOnTime = ledOnTime; + gLightCtx.ledOffTime = ledOffTime; + + gLightCtx.timerLedEvt = TL_ZB_TIMER_SCHEDULE(light_blink_TimerEvtCb, NULL, interval); + } +} + +/********************************************************************* + * @fn light_blink_stop + * + * @brief + * + * @param None + * + * @return None + */ +void light_blink_stop(void) +{ + if(gLightCtx.timerLedEvt){ + TL_ZB_TIMER_CANCEL(&gLightCtx.timerLedEvt); + + gLightCtx.times = 0; + if(gLightCtx.oriSta){ + hwLight_onOffUpdate(ZCL_CMD_ONOFF_ON); + }else{ + hwLight_onOffUpdate(ZCL_CMD_ONOFF_OFF); + } + } +} + +#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */ diff --git a/sampleLightCtrl.h b/sampleLightCtrl.h new file mode 100644 index 0000000..f31d22d --- /dev/null +++ b/sampleLightCtrl.h @@ -0,0 +1,50 @@ +/******************************************************************************************************** + * @file sampleLightCtrl.h + * + * @brief This is the header file for sampleLightCtrl + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#ifndef _SAMPLE_LIGHT_CTRL_H_ +#define _SAMPLE_LIGHT_CTRL_H_ + + +/********************************************************************** + * CONSTANT + */ + + +/********************************************************************** + * FUNCTIONS + */ +void hwLight_init(void); +void hwLight_onOffUpdate(u8 onOff); +void hwLight_levelUpdate(u8 level); +void hwLight_colorUpdate_colorTemperature(u16 colorTemperatureMireds, u8 level); +void hwLight_colorUpdate_HSV2RGB(u8 hue, u8 saturation, u8 level); + +void light_adjust(void); +void light_fresh(void); +void light_applyUpdate(u8 *curLevel, u16 *curLevel256, s32 *stepLevel256, u16 *remainingTime, u8 minLevel, u8 maxLevel, bool wrap); +void light_applyUpdate_16(u16 *curLevel, u32 *curLevel256, s32 *stepLevel256, u16 *remainingTime, u16 minLevel, u16 maxLevel, bool wrap); + +void light_blink_start(u8 times, u16 ledOnTime, u16 ledOffTime); +void light_blink_stop(void); + +#endif /* _SAMPLE_LIGHT_CTRL_H_ */ diff --git a/sampleLightEpCfg.c b/sampleLightEpCfg.c new file mode 100644 index 0000000..2365875 --- /dev/null +++ b/sampleLightEpCfg.c @@ -0,0 +1,659 @@ +/******************************************************************************************************** + * @file sampleLightEpCfg.c + * + * @brief This is the source file for sampleLightEpCfg + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#if (__PROJECT_TL_DIMMABLE_LIGHT__) + +/********************************************************************** + * INCLUDES + */ +#include "tl_common.h" +#include "zcl_include.h" +#include "sampleLight.h" + + +/********************************************************************** + * LOCAL CONSTANTS + */ +#ifndef ZCL_BASIC_MFG_NAME +#define ZCL_BASIC_MFG_NAME {6,'T','E','L','I','N','K'} +#endif +#ifndef ZCL_BASIC_MODEL_ID +#define ZCL_BASIC_MODEL_ID {8,'T','L','S','R','8','2','x','x'} +#endif +#ifndef ZCL_BASIC_SW_BUILD_ID +#define ZCL_BASIC_SW_BUILD_ID {10,'0','1','2','2','0','5','2','0','1','7'} +#endif + + +#if COLOR_CCT_SUPPORT +#define COLOR_TEMPERATURE_PHYSICAL_MIN 0x00FA//4000K +#define COLOR_TEMPERATURE_PHYSICAL_MAX 0x01C6//2200K +#endif + +/********************************************************************** + * TYPEDEFS + */ + + +/********************************************************************** + * GLOBAL VARIABLES + */ +/** + * @brief Definition for Incoming cluster / Sever Cluster + */ +const u16 sampleLight_inClusterList[] = +{ + ZCL_CLUSTER_GEN_BASIC, + ZCL_CLUSTER_GEN_IDENTIFY, +#ifdef ZCL_GROUP + ZCL_CLUSTER_GEN_GROUPS, +#endif +#ifdef ZCL_SCENE + ZCL_CLUSTER_GEN_SCENES, +#endif +#ifdef ZCL_ON_OFF + ZCL_CLUSTER_GEN_ON_OFF, +#endif +#ifdef ZCL_LEVEL_CTRL + ZCL_CLUSTER_GEN_LEVEL_CONTROL, +#endif +#ifdef ZCL_LIGHT_COLOR_CONTROL + ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, +#endif +#ifdef ZCL_ZLL_COMMISSIONING + ZCL_CLUSTER_TOUCHLINK_COMMISSIONING, +#endif +#ifdef ZCL_WWAH + ZCL_CLUSTER_WWAH, +#endif +}; + +/** + * @brief Definition for Outgoing cluster / Client Cluster + */ +const u16 sampleLight_outClusterList[] = +{ +#ifdef ZCL_OTA + ZCL_CLUSTER_OTA, +#endif +}; + +/** + * @brief Definition for Server cluster number and Client cluster number + */ +#define SAMPLELIGHT_IN_CLUSTER_NUM (sizeof(sampleLight_inClusterList)/sizeof(sampleLight_inClusterList[0])) +#define SAMPLELIGHT_OUT_CLUSTER_NUM (sizeof(sampleLight_outClusterList)/sizeof(sampleLight_outClusterList[0])) + +/** + * @brief Definition for simple description for HA profile + */ +const af_simple_descriptor_t sampleLight_simpleDesc = +{ + HA_PROFILE_ID, /* Application profile identifier */ +#ifdef ZCL_LIGHT_COLOR_CONTROL + HA_DEV_COLOR_DIMMABLE_LIGHT, +#else + #ifdef ZCL_LEVEL_CTRL + HA_DEV_DIMMABLE_LIGHT, /* Application device identifier */ + #else + HA_DEV_ONOFF_LIGHT, /* Application device identifier */ + #endif +#endif + SAMPLE_LIGHT_ENDPOINT, /* Endpoint */ + 1, /* Application device version */ + 0, /* Reserved */ + SAMPLELIGHT_IN_CLUSTER_NUM, /* Application input cluster count */ + SAMPLELIGHT_OUT_CLUSTER_NUM, /* Application output cluster count */ + (u16 *)sampleLight_inClusterList, /* Application input cluster list */ + (u16 *)sampleLight_outClusterList, /* Application output cluster list */ +}; + +#if AF_TEST_ENABLE +/** + * @brief Definition for Incoming cluster / Sever Cluster + */ +const u16 sampleTest_inClusterList[] = +{ + ZCL_CLUSTER_TELINK_SDK_TEST_REQ, + ZCL_CLUSTER_TELINK_SDK_TEST_RSP, + ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_REQ, + ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_RSP, +}; + + +/** + * @brief Definition for Outgoing cluster / Client Cluster + */ +const u16 sampleTest_outClusterList[] = +{ + ZCL_CLUSTER_TELINK_SDK_TEST_REQ, + ZCL_CLUSTER_TELINK_SDK_TEST_RSP, + ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_REQ, + ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_RSP, +}; + +/** + * @brief Definition for Server cluster number and Client cluster number + */ +#define SAMPLE_TEST_IN_CLUSTER_NUM (sizeof(sampleTest_inClusterList)/sizeof(sampleTest_inClusterList[0])) +#define SAMPLE_TEST_OUT_CLUSTER_NUM (sizeof(sampleTest_outClusterList)/sizeof(sampleTest_outClusterList[0])) + +/** + * @brief Definition for simple description for HA profile + */ +const af_simple_descriptor_t sampleTestDesc = +{ + HA_PROFILE_ID, /* Application profile identifier */ + HA_DEV_DIMMABLE_LIGHT, /* Application device identifier */ + SAMPLE_TEST_ENDPOINT, /* Endpoint */ + 0, /* Application device version */ + 0, /* Reserved */ + SAMPLE_TEST_IN_CLUSTER_NUM, /* Application input cluster count */ + SAMPLE_TEST_OUT_CLUSTER_NUM, /* Application output cluster count */ + (u16 *)sampleTest_inClusterList, /* Application input cluster list */ + (u16 *)sampleTest_outClusterList, /* Application output cluster list */ +}; +#endif /* AF_TEST_ENABLE */ + + +/* Basic */ +zcl_basicAttr_t g_zcl_basicAttrs = +{ + .zclVersion = 0x03, + .appVersion = 0x00, + .stackVersion = 0x02, + .hwVersion = 0x00, + .manuName = ZCL_BASIC_MFG_NAME, + .modelId = ZCL_BASIC_MODEL_ID, + .powerSource = POWER_SOURCE_MAINS_1_PHASE, + .swBuildId = ZCL_BASIC_SW_BUILD_ID, + .deviceEnable = TRUE, +}; + +const zclAttrInfo_t basic_attrTbl[] = +{ + { ZCL_ATTRID_BASIC_ZCL_VER, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_basicAttrs.zclVersion}, + { ZCL_ATTRID_BASIC_APP_VER, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_basicAttrs.appVersion}, + { ZCL_ATTRID_BASIC_STACK_VER, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_basicAttrs.stackVersion}, + { ZCL_ATTRID_BASIC_HW_VER, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_basicAttrs.hwVersion}, + { ZCL_ATTRID_BASIC_MFR_NAME, ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_READ, (u8*)g_zcl_basicAttrs.manuName}, + { ZCL_ATTRID_BASIC_MODEL_ID, ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_READ, (u8*)g_zcl_basicAttrs.modelId}, + { ZCL_ATTRID_BASIC_POWER_SOURCE, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ, (u8*)&g_zcl_basicAttrs.powerSource}, + { ZCL_ATTRID_BASIC_DEV_ENABLED, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_basicAttrs.deviceEnable}, + { ZCL_ATTRID_BASIC_SW_BUILD_ID, ZCL_DATA_TYPE_CHAR_STR, ACCESS_CONTROL_READ, (u8*)&g_zcl_basicAttrs.swBuildId}, + + { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, +}; + +#define ZCL_BASIC_ATTR_NUM sizeof(basic_attrTbl) / sizeof(zclAttrInfo_t) + + +/* Identify */ +zcl_identifyAttr_t g_zcl_identifyAttrs = +{ + .identifyTime = 0x0000, +}; + +const zclAttrInfo_t identify_attrTbl[] = +{ + { ZCL_ATTRID_IDENTIFY_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_identifyAttrs.identifyTime }, + + { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, +}; + +#define ZCL_IDENTIFY_ATTR_NUM sizeof(identify_attrTbl) / sizeof(zclAttrInfo_t) + +#ifdef ZCL_GROUP +/* Group */ +zcl_groupAttr_t g_zcl_groupAttrs = +{ + .nameSupport = 0, +}; + +const zclAttrInfo_t group_attrTbl[] = +{ + { ZCL_ATTRID_GROUP_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_groupAttrs.nameSupport }, + + { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, +}; + +#define ZCL_GROUP_ATTR_NUM sizeof(group_attrTbl) / sizeof(zclAttrInfo_t) +#endif + +#ifdef ZCL_SCENE +/* Scene */ +zcl_sceneAttr_t g_zcl_sceneAttrs = +{ + .sceneCount = 0, + .currentScene = 0, + .currentGroup = 0x0000, + .sceneValid = FALSE, + .nameSupport = 0, +}; + +const zclAttrInfo_t scene_attrTbl[] = +{ + { ZCL_ATTRID_SCENE_SCENE_COUNT, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs.sceneCount }, + { ZCL_ATTRID_SCENE_CURRENT_SCENE, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs.currentScene }, + { ZCL_ATTRID_SCENE_CURRENT_GROUP, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs.currentGroup }, + { ZCL_ATTRID_SCENE_SCENE_VALID, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs.sceneValid }, + { ZCL_ATTRID_SCENE_NAME_SUPPORT, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ, (u8*)&g_zcl_sceneAttrs.nameSupport }, + + { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, +}; + +#define ZCL_SCENE_ATTR_NUM sizeof(scene_attrTbl) / sizeof(zclAttrInfo_t) +#endif + +#ifdef ZCL_ON_OFF +/* On/Off */ +zcl_onOffAttr_t g_zcl_onOffAttrs = +{ + .onOff = 0x00, + .globalSceneControl = 1, + .onTime = 0x0000, + .offWaitTime = 0x0000, + .startUpOnOff = ZCL_START_UP_ONOFF_SET_ONOFF_TO_ON, +}; + +const zclAttrInfo_t onOff_attrTbl[] = +{ + { ZCL_ATTRID_ONOFF, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_onOffAttrs.onOff}, + { ZCL_ATTRID_GLOBAL_SCENE_CONTROL, ZCL_DATA_TYPE_BOOLEAN, ACCESS_CONTROL_READ, (u8*)&g_zcl_onOffAttrs.globalSceneControl}, + { ZCL_ATTRID_ON_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs.onTime}, + { ZCL_ATTRID_OFF_WAIT_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs.offWaitTime}, + { ZCL_ATTRID_START_UP_ONOFF, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_onOffAttrs.startUpOnOff}, + + { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, +}; + +#define ZCL_ONOFF_ATTR_NUM sizeof(onOff_attrTbl) / sizeof(zclAttrInfo_t) +#endif + +#ifdef ZCL_LEVEL_CTRL +/* Level */ +zcl_levelAttr_t g_zcl_levelAttrs = +{ + .curLevel = 0xFE, + .remainingTime = 0, + .startUpCurrentLevel = ZCL_START_UP_CURRENT_LEVEL_TO_PREVIOUS, +}; + +const zclAttrInfo_t level_attrTbl[] = +{ + { ZCL_ATTRID_LEVEL_CURRENT_LEVEL, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_levelAttrs.curLevel }, + { ZCL_ATTRID_LEVEL_REMAINING_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_levelAttrs.remainingTime }, + { ZCL_ATTRID_LEVEL_START_UP_CURRENT_LEVEL, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_levelAttrs.startUpCurrentLevel }, + + { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, +}; + +#define ZCL_LEVEL_ATTR_NUM sizeof(level_attrTbl) / sizeof(zclAttrInfo_t) +#endif + +#ifdef ZCL_LIGHT_COLOR_CONTROL +/* Color Control */ +zcl_lightColorCtrlAttr_t g_zcl_colorCtrlAttrs = +{ + .colorMode = ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS, + .options = 0, + .enhancedColorMode = ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS, + .colorCapabilities = ZCL_COLOR_CAPABILITIES_BIT_COLOR_TEMPERATURE, + .numOfPrimaries = 0, +#if COLOR_RGB_SUPPORT + .currentHue = 0x00, + .currentSaturation = 0x00, + .colorLoopActive = 0x00, + .colorLoopDirection = 0x00, + .colorLoopTime = 0x0019, + .colorLoopStartEnhancedHue = 0x2300, + .colorLoopStoredEnhancedHue = 0x0000, +#elif COLOR_CCT_SUPPORT + .colorTemperatureMireds = COLOR_TEMPERATURE_PHYSICAL_MAX, + .colorTempPhysicalMinMireds = COLOR_TEMPERATURE_PHYSICAL_MIN, + .colorTempPhysicalMaxMireds = COLOR_TEMPERATURE_PHYSICAL_MAX, + .startUpColorTemperatureMireds = ZCL_START_UP_COLOR_TEMPERATURE_MIREDS_TO_PREVIOUS, +#endif +}; + +const zclAttrInfo_t lightColorCtrl_attrTbl[] = +{ + { ZCL_ATTRID_COLOR_MODE, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorMode }, + { ZCL_ATTRID_COLOR_OPTIONS, ZCL_DATA_TYPE_BITMAP8, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_colorCtrlAttrs.options }, + { ZCL_ATTRID_ENHANCED_COLOR_MODE, ZCL_DATA_TYPE_ENUM8, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.enhancedColorMode }, + { ZCL_ATTRID_COLOR_CAPABILITIES, ZCL_DATA_TYPE_BITMAP16, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorCapabilities }, + { ZCL_ATTRID_NUMBER_OF_PRIMARIES, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.numOfPrimaries }, + +#if COLOR_RGB_SUPPORT + { ZCL_ATTRID_CURRENT_HUE, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.currentHue }, + { ZCL_ATTRID_CURRENT_SATURATION, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.currentSaturation }, + { ZCL_ATTRID_COLOR_LOOP_ACTIVE, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.colorLoopActive }, + { ZCL_ATTRID_COLOR_LOOP_DIRECTION, ZCL_DATA_TYPE_UINT8, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.colorLoopDirection }, + { ZCL_ATTRID_COLOR_LOOP_TIME, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.colorLoopTime }, + { ZCL_ATTRID_COLOR_LOOP_START_ENHANCED_HUE, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorLoopStartEnhancedHue }, + { ZCL_ATTRID_COLOR_LOOP_STORED_ENHANCED_HUE, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorLoopStoredEnhancedHue }, +#elif COLOR_CCT_SUPPORT + { ZCL_ATTRID_COLOR_TEMPERATURE_MIREDS, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_REPORTABLE, (u8*)&g_zcl_colorCtrlAttrs.colorTemperatureMireds }, + { ZCL_ATTRID_COLOR_TEMP_PHYSICAL_MIN_MIREDS, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorTempPhysicalMinMireds }, + { ZCL_ATTRID_COLOR_TEMP_PHYSICAL_MAX_MIREDS, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&g_zcl_colorCtrlAttrs.colorTempPhysicalMaxMireds }, + { ZCL_ATTRID_START_UP_COLOR_TEMPERATURE_MIREDS, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE, (u8*)&g_zcl_colorCtrlAttrs.startUpColorTemperatureMireds }, +#endif + + { ZCL_ATTRID_GLOBAL_CLUSTER_REVISION, ZCL_DATA_TYPE_UINT16, ACCESS_CONTROL_READ, (u8*)&zcl_attr_global_clusterRevision}, +}; + +#define ZCL_COLOR_ATTR_NUM sizeof(lightColorCtrl_attrTbl) / sizeof(zclAttrInfo_t) +#endif + +/** + * @brief Definition for simple light ZCL specific cluster + */ +const zcl_specClusterInfo_t g_sampleLightClusterList[] = +{ + {ZCL_CLUSTER_GEN_BASIC, MANUFACTURER_CODE_NONE, ZCL_BASIC_ATTR_NUM, basic_attrTbl, zcl_basic_register, sampleLight_basicCb}, + {ZCL_CLUSTER_GEN_IDENTIFY, MANUFACTURER_CODE_NONE, ZCL_IDENTIFY_ATTR_NUM, identify_attrTbl, zcl_identify_register, sampleLight_identifyCb}, +#ifdef ZCL_GROUP + {ZCL_CLUSTER_GEN_GROUPS, MANUFACTURER_CODE_NONE, ZCL_GROUP_ATTR_NUM, group_attrTbl, zcl_group_register, NULL}, +#endif +#ifdef ZCL_SCENE + {ZCL_CLUSTER_GEN_SCENES, MANUFACTURER_CODE_NONE, ZCL_SCENE_ATTR_NUM, scene_attrTbl, zcl_scene_register, sampleLight_sceneCb}, +#endif +#ifdef ZCL_ON_OFF + {ZCL_CLUSTER_GEN_ON_OFF, MANUFACTURER_CODE_NONE, ZCL_ONOFF_ATTR_NUM, onOff_attrTbl, zcl_onOff_register, sampleLight_onOffCb}, +#endif +#ifdef ZCL_LEVEL_CTRL + {ZCL_CLUSTER_GEN_LEVEL_CONTROL, MANUFACTURER_CODE_NONE, ZCL_LEVEL_ATTR_NUM, level_attrTbl, zcl_level_register, sampleLight_levelCb}, +#endif +#ifdef ZCL_LIGHT_COLOR_CONTROL + {ZCL_CLUSTER_LIGHTING_COLOR_CONTROL, MANUFACTURER_CODE_NONE, ZCL_COLOR_ATTR_NUM, lightColorCtrl_attrTbl, zcl_lightColorCtrl_register, sampleLight_colorCtrlCb}, +#endif +}; + +u8 SAMPLELIGHT_CB_CLUSTER_NUM = (sizeof(g_sampleLightClusterList)/sizeof(g_sampleLightClusterList[0])); + + +/********************************************************************** + * FUNCTIONS + */ + + +/********************************************************************* + * @fn zcl_onOffAttr_save + * + * @brief + * + * @param None + * + * @return + */ +nv_sts_t zcl_onOffAttr_save(void) +{ + nv_sts_t st = NV_SUCC; + +#ifdef ZCL_ON_OFF +#if NV_ENABLE + zcl_nv_onOff_t zcl_nv_onOff; + + st = nv_flashReadNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_ON_OFF, sizeof(zcl_nv_onOff_t), (u8*)&zcl_nv_onOff); + + if(st == NV_SUCC){ + if((zcl_nv_onOff.onOff != g_zcl_onOffAttrs.onOff) || (zcl_nv_onOff.startUpOnOff != g_zcl_onOffAttrs.startUpOnOff)){ + zcl_nv_onOff.onOff = g_zcl_onOffAttrs.onOff; + zcl_nv_onOff.startUpOnOff = g_zcl_onOffAttrs.startUpOnOff; + + st = nv_flashWriteNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_ON_OFF, sizeof(zcl_nv_onOff_t), (u8*)&zcl_nv_onOff); + } + }else if(st == NV_ITEM_NOT_FOUND){ + zcl_nv_onOff.onOff = g_zcl_onOffAttrs.onOff; + zcl_nv_onOff.startUpOnOff = g_zcl_onOffAttrs.startUpOnOff; + + st = nv_flashWriteNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_ON_OFF, sizeof(zcl_nv_onOff_t), (u8*)&zcl_nv_onOff); + } +#else + st = NV_ENABLE_PROTECT_ERROR; +#endif +#endif + + return st; +} + +/********************************************************************* + * @fn zcl_onOffAttr_restore + * + * @brief + * + * @param None + * + * @return + */ +nv_sts_t zcl_onOffAttr_restore(void) +{ + nv_sts_t st = NV_SUCC; + +#ifdef ZCL_ON_OFF +#if NV_ENABLE + zcl_nv_onOff_t zcl_nv_onOff; + + st = nv_flashReadNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_ON_OFF, sizeof(zcl_nv_onOff_t), (u8*)&zcl_nv_onOff); + + if(st == NV_SUCC){ + g_zcl_onOffAttrs.onOff = zcl_nv_onOff.onOff; + g_zcl_onOffAttrs.startUpOnOff = zcl_nv_onOff.startUpOnOff; + } +#else + st = NV_ENABLE_PROTECT_ERROR; +#endif +#endif + + return st; +} + +/********************************************************************* + * @fn zcl_levelAttr_save + * + * @brief + * + * @param None + * + * @return + */ +nv_sts_t zcl_levelAttr_save(void) +{ + nv_sts_t st = NV_SUCC; + +#ifdef ZCL_LEVEL_CTRL +#if NV_ENABLE + zcl_nv_level_t zcl_nv_level; + + st = nv_flashReadNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_LEVEL, sizeof(zcl_nv_level_t), (u8*)&zcl_nv_level); + + if(st == NV_SUCC){ + if((zcl_nv_level.curLevel != g_zcl_levelAttrs.curLevel) || (zcl_nv_level.startUpCurLevel != g_zcl_levelAttrs.startUpCurrentLevel)){ + zcl_nv_level.curLevel = g_zcl_levelAttrs.curLevel; + zcl_nv_level.startUpCurLevel = g_zcl_levelAttrs.startUpCurrentLevel; + + st = nv_flashWriteNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_LEVEL, sizeof(zcl_nv_level_t), (u8*)&zcl_nv_level); + } + }else if(st == NV_ITEM_NOT_FOUND){ + zcl_nv_level.curLevel = g_zcl_levelAttrs.curLevel; + zcl_nv_level.startUpCurLevel = g_zcl_levelAttrs.startUpCurrentLevel; + + st = nv_flashWriteNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_LEVEL, sizeof(zcl_nv_level_t), (u8*)&zcl_nv_level); + } +#else + st = NV_ENABLE_PROTECT_ERROR; +#endif +#endif + + return st; +} + +/********************************************************************* + * @fn zcl_levelAttr_restore + * + * @brief + * + * @param None + * + * @return + */ +nv_sts_t zcl_levelAttr_restore(void) +{ + nv_sts_t st = NV_SUCC; + +#ifdef ZCL_LEVEL_CTRL +#if NV_ENABLE + zcl_nv_level_t zcl_nv_level; + + st = nv_flashReadNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_LEVEL, sizeof(zcl_nv_level_t), (u8*)&zcl_nv_level); + + if(st == NV_SUCC){ + g_zcl_levelAttrs.curLevel = zcl_nv_level.curLevel; + g_zcl_levelAttrs.startUpCurrentLevel = zcl_nv_level.startUpCurLevel; + } +#else + st = NV_ENABLE_PROTECT_ERROR; +#endif +#endif + + return st; +} + +/********************************************************************* + * @fn zcl_colorCtrlAttr_save + * + * @brief + * + * @param None + * + * @return + */ +nv_sts_t zcl_colorCtrlAttr_save(void) +{ + nv_sts_t st = NV_SUCC; + +#ifdef ZCL_LIGHT_COLOR_CONTROL +#if NV_ENABLE + bool needSave = FALSE; + zcl_nv_colorCtrl_t zcl_nv_colorCtrl; + + st = nv_flashReadNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_COLOR_CTRL, sizeof(zcl_nv_colorCtrl_t), (u8*)&zcl_nv_colorCtrl); + +#if COLOR_RGB_SUPPORT + if(st == NV_SUCC){ + if((zcl_nv_colorCtrl.currentHue != g_zcl_colorCtrlAttrs.currentHue) || (zcl_nv_colorCtrl.currentSaturation != g_zcl_colorCtrlAttrs.currentSaturation)){ + zcl_nv_colorCtrl.currentHue = g_zcl_colorCtrlAttrs.currentHue; + zcl_nv_colorCtrl.currentSaturation = g_zcl_colorCtrlAttrs.currentSaturation; + + needSave = TRUE; + } + }else if(st == NV_ITEM_NOT_FOUND){ + zcl_nv_colorCtrl.currentHue = g_zcl_colorCtrlAttrs.currentHue; + zcl_nv_colorCtrl.currentSaturation = g_zcl_colorCtrlAttrs.currentSaturation; + + needSave = TRUE; + } +#elif COLOR_CCT_SUPPORT + if(st == NV_SUCC){ + if((zcl_nv_colorCtrl.colorTemperatureMireds != g_zcl_colorCtrlAttrs.colorTemperatureMireds) || (zcl_nv_colorCtrl.startUpColorTemperatureMireds != g_zcl_colorCtrlAttrs.startUpColorTemperatureMireds)){ + zcl_nv_colorCtrl.colorTemperatureMireds = g_zcl_colorCtrlAttrs.colorTemperatureMireds; + zcl_nv_colorCtrl.startUpColorTemperatureMireds = g_zcl_colorCtrlAttrs.startUpColorTemperatureMireds; + + needSave = TRUE; + } + }else if(st == NV_ITEM_NOT_FOUND){ + zcl_nv_colorCtrl.colorTemperatureMireds = g_zcl_colorCtrlAttrs.colorTemperatureMireds; + zcl_nv_colorCtrl.startUpColorTemperatureMireds = g_zcl_colorCtrlAttrs.startUpColorTemperatureMireds; + + needSave = TRUE; + } +#endif + + if(needSave){ + st = nv_flashWriteNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_COLOR_CTRL, sizeof(zcl_nv_colorCtrl_t), (u8*)&zcl_nv_colorCtrl); + } + +#else + st = NV_ENABLE_PROTECT_ERROR; +#endif +#endif + + return st; +} + +/********************************************************************* + * @fn zcl_colorCtrlAttr_restore + * + * @brief + * + * @param None + * + * @return + */ +nv_sts_t zcl_colorCtrlAttr_restore(void) +{ + nv_sts_t st = NV_SUCC; + +#ifdef ZCL_LIGHT_COLOR_CONTROL +#if NV_ENABLE + zcl_nv_colorCtrl_t zcl_nv_colorCtrl; + + st = nv_flashReadNew(1, NV_MODULE_ZCL, NV_ITEM_ZCL_COLOR_CTRL, sizeof(zcl_nv_colorCtrl_t), (u8*)&zcl_nv_colorCtrl); + +#if COLOR_RGB_SUPPORT + if(st == NV_SUCC){ + g_zcl_colorCtrlAttrs.currentHue = zcl_nv_colorCtrl.currentHue; + g_zcl_colorCtrlAttrs.currentSaturation = zcl_nv_colorCtrl.currentSaturation; + } +#elif COLOR_CCT_SUPPORT + if(st == NV_SUCC){ + g_zcl_colorCtrlAttrs.colorTemperatureMireds = zcl_nv_colorCtrl.colorTemperatureMireds; + g_zcl_colorCtrlAttrs.startUpColorTemperatureMireds = zcl_nv_colorCtrl.startUpColorTemperatureMireds; + } +#endif + +#else + st = NV_ENABLE_PROTECT_ERROR; +#endif +#endif + + return st; +} + +/********************************************************************* + * @fn zcl_sampleLightAttrsInit + * + * @brief + * + * @param None + * + * @return + */ +void zcl_sampleLightAttrsInit(void) +{ + zcl_onOffAttr_restore(); + zcl_levelAttr_restore(); + zcl_colorCtrlAttr_restore(); +} + +#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */ diff --git a/stack_cfg.h b/stack_cfg.h new file mode 100644 index 0000000..67fd2d6 --- /dev/null +++ b/stack_cfg.h @@ -0,0 +1,93 @@ +/******************************************************************************************************** + * @file stack_cfg.h + * + * @brief This is the header file for stack_cfg + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#pragma once + + +/** + * @brief Working channel + * Valid value: 11 ~ 26 + */ +#define DEFAULT_CHANNEL 20 + +/** + * @brief NVRAM + */ +#define NV_ENABLE 1 + +/** + * @brief Security + */ +#define SECURITY_ENABLE 1 + + +/********************************************************************** + * Following parameter need user to adjust according the app requirement + */ +/** + * @brief ZCL: MAX number of cluster list, in cluster number add + out cluster number + * + */ +#define ZCL_CLUSTER_NUM_MAX 11 + +/** + * @brief ZCL: maximum number for zcl reporting table + * + */ +#define ZCL_REPORTING_TABLE_NUM 4 + +/** + * @brief ZCL: maximum number for zcl scene table + * + */ +#define ZCL_SCENE_TABLE_NUM 8 + + +/** + * @brief APS: MAX number of groups size in the group table + * In each group entry, there is 8 endpoints existed. + */ +#define APS_GROUP_TABLE_NUM 8 + +/** + * @brief APS: MAX number of binding table size + */ +#define APS_BINDING_TABLE_NUM 8 + + +/********************************************************************** + * Following configuration will calculated automatically + */ + +/** + Auto definition for the role + */ +#if (COORDINATOR) + #define ZB_ROUTER_ROLE 1 + #define ZB_COORDINATOR_ROLE 1 +#elif (ROUTER) + #define ZB_ROUTER_ROLE 1 +#elif (END_DEVICE) + #define ZB_ED_ROLE 1 +#endif + diff --git a/version_cfg.h b/version_cfg.h new file mode 100644 index 0000000..df8f417 --- /dev/null +++ b/version_cfg.h @@ -0,0 +1,58 @@ +/******************************************************************************************************** + * @file version_cfg.h + * + * @brief This is the header file for version_cfg + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#pragma once + +#include "../common/comm_cfg.h" + +#if defined(MCU_CORE_826x) + #if (CHIP_8269) + #define CHIP_TYPE TLSR_8269 + #else + #define CHIP_TYPE TLSR_8267 + #endif +#elif defined(MCU_CORE_8258) + #define CHIP_TYPE TLSR_8258_512K//TLSR_8258_1M +#elif defined(MCU_CORE_8278) + #define CHIP_TYPE TLSR_8278 +#elif defined(MCU_CORE_B91) + #define CHIP_TYPE TLSR_9518 +#endif + +#define APP_RELEASE 0x10//app release 1.0 +#define APP_BUILD 0x01//app build 01 +#define STACK_RELEASE 0x30//stack release 3.0 +#define STACK_BUILD 0x01//stack build 01 + +/********************************************************************************************* + * During OTA upgrade, the upgraded device will check the rules of the following three fields. + * Refer to ZCL OTA specification for details. + */ +#define MANUFACTURER_CODE_TELINK 0x1141//Telink ID +#define IMAGE_TYPE ((CHIP_TYPE << 8) | IMAGE_TYPE_LIGHT) +#define FILE_VERSION ((APP_RELEASE << 24) | (APP_BUILD << 16) | (STACK_RELEASE << 8) | STACK_BUILD) + +/* Pre-compiled link configuration. */ +#define IS_BOOT_LOADER_IMAGE 0 +#define RESV_FOR_APP_RAM_CODE_SIZE 0 +#define IMAGE_OFFSET APP_IMAGE_ADDR diff --git a/zb_afTestCb.c b/zb_afTestCb.c new file mode 100644 index 0000000..e02c24e --- /dev/null +++ b/zb_afTestCb.c @@ -0,0 +1,145 @@ +/******************************************************************************************************** + * @file zb_afTestCb.c + * + * @brief This is the source file for zb_afTestCb + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#if (__PROJECT_TL_DIMMABLE_LIGHT__) + +/********************************************************************** + * INCLUDES + */ +#include "tl_common.h" +#include "zb_api.h" +#include "zcl_include.h" +#include "sampleLight.h" +#if ZBHCI_EN +#include "zbhci.h" +#endif + +#if AF_TEST_ENABLE +/********************************************************************** + * LOCAL CONSTANTS + */ + + +/********************************************************************** + * TYPEDEFS + */ + + +/********************************************************************** + * LOCAL FUNCTIONS + */ + +/********************************************************************** + * GLOBAL VARIABLES + */ + + +/********************************************************************** + * LOCAL VARIABLES + */ +u16 g_afTest_rcvReqCnt = 0; + +/********************************************************************** + * FUNCTIONS + */ +static void afTest_testReqPrc(apsdeDataInd_t *pApsdeInd) +{ + epInfo_t dstEp; + TL_SETSTRUCTCONTENT(dstEp, 0); + + dstEp.dstEp = pApsdeInd->indInfo.src_ep; + dstEp.profileId = pApsdeInd->indInfo.profile_id; + dstEp.dstAddrMode = APS_SHORT_DSTADDR_WITHEP; + dstEp.dstAddr.shortAddr = pApsdeInd->indInfo.src_short_addr; + + u8 dataLen = 50; + u8 *pBuf = (u8 *)ev_buf_allocate(dataLen); + if(pBuf){ + u8 *pData = pBuf; + + *pData++ = LO_UINT16(g_afTest_rcvReqCnt); + *pData++ = HI_UINT16(g_afTest_rcvReqCnt); + + for(u8 i = 0; i < dataLen - 2; i++){ + *pData++ = i; + } + + u8 apsCnt = 0; +#if ZBHCI_EN + zbhciTx(ZCL_CLUSTER_TELINK_SDK_TEST_RSP, pApsdeInd->asduLen, (u8 *)pApsdeInd->asdu); +#else + af_dataSend(pApsdeInd->indInfo.dst_ep, &dstEp, ZCL_CLUSTER_TELINK_SDK_TEST_RSP, dataLen, pBuf, &apsCnt); +#endif + + ev_buf_free(pBuf); + } +} + +static void afTest_testClearReqPrc(apsdeDataInd_t *pApsdeInd) +{ + epInfo_t dstEp; + TL_SETSTRUCTCONTENT(dstEp, 0); + + dstEp.dstEp = pApsdeInd->indInfo.src_ep; + dstEp.profileId = pApsdeInd->indInfo.profile_id; + dstEp.dstAddrMode = APS_SHORT_DSTADDR_WITHEP; + dstEp.dstAddr.shortAddr = pApsdeInd->indInfo.src_short_addr; + + u8 st = SUCCESS; + + u8 apsCnt = 0; + af_dataSend(pApsdeInd->indInfo.dst_ep, &dstEp, ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_RSP, 1, &st, &apsCnt); +} + +void afTest_rx_handler(void *arg) +{ + apsdeDataInd_t *pApsdeInd = (apsdeDataInd_t *)arg; + + switch(pApsdeInd->indInfo.cluster_id){ + case ZCL_CLUSTER_TELINK_SDK_TEST_CLEAR_REQ: + g_afTest_rcvReqCnt = 0; + afTest_testClearReqPrc(pApsdeInd); + break; + case ZCL_CLUSTER_TELINK_SDK_TEST_REQ: + g_afTest_rcvReqCnt++; + afTest_testReqPrc(pApsdeInd); + break; + case ZCL_CLUSTER_TELINK_SDK_TEST_RSP: + + break; + default: + break; + } + + /* Must be free here. */ + ev_buf_free((u8 *)arg); +} + +void afTest_dataSendConfirm(void *arg) +{ +// apsdeDataConf_t *pApsDataCnf = (apsdeDataConf_t *)arg; + +} + +#endif /* AF_TEST_ENABLE */ +#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */ diff --git a/zb_appCb.c b/zb_appCb.c new file mode 100644 index 0000000..48782bb --- /dev/null +++ b/zb_appCb.c @@ -0,0 +1,287 @@ +/******************************************************************************************************** + * @file zb_appCb.c + * + * @brief This is the source file for zb_appCb + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#if (__PROJECT_TL_DIMMABLE_LIGHT__) + +/********************************************************************** + * INCLUDES + */ +#include "tl_common.h" +#include "zb_api.h" +#include "zcl_include.h" +#include "bdb.h" +#include "ota.h" +#include "sampleLight.h" +#include "sampleLightCtrl.h" + +/********************************************************************** + * LOCAL CONSTANTS + */ +#define DEBUG_HEART 0 + +/********************************************************************** + * TYPEDEFS + */ + + +/********************************************************************** + * LOCAL FUNCTIONS + */ +void zbdemo_bdbInitCb(u8 status, u8 joinedNetwork); +void zbdemo_bdbCommissioningCb(u8 status, void *arg); +void zbdemo_bdbIdentifyCb(u8 endpoint, u16 srcAddr, u16 identifyTime); + + +/********************************************************************** + * GLOBAL VARIABLES + */ +bdb_appCb_t g_zbDemoBdbCb = {zbdemo_bdbInitCb, zbdemo_bdbCommissioningCb, zbdemo_bdbIdentifyCb, NULL}; + +#ifdef ZCL_OTA +ota_callBack_t sampleLight_otaCb = +{ + sampleLight_otaProcessMsgHandler, +}; +#endif + +/********************************************************************** + * LOCAL VARIABLES + */ +u32 heartInterval = 0; + +#if DEBUG_HEART +ev_timer_event_t *heartTimerEvt = NULL; +#endif + +/********************************************************************** + * FUNCTIONS + */ +#if DEBUG_HEART +static s32 heartTimerCb(void *arg){ + if(heartInterval == 0){ + heartTimerEvt = NULL; + return -1; + } + + gpio_toggle(LED_POWER); + + return heartInterval; +} +#endif + +s32 sampleLight_bdbNetworkSteerStart(void *arg){ + bdb_networkSteerStart(); + + return -1; +} + +#if FIND_AND_BIND_SUPPORT +s32 sampleLight_bdbFindAndBindStart(void *arg){ + bdb_findAndBindStart(BDB_COMMISSIONING_ROLE_TARGET); + + return -1; +} +#endif + +/********************************************************************* + * @fn zbdemo_bdbInitCb + * + * @brief application callback for bdb initiation + * + * @param status - the status of bdb init BDB_INIT_STATUS_SUCCESS or BDB_INIT_STATUS_FAILURE + * + * @param joinedNetwork - 1: node is on a network, 0: node isn't on a network + * + * @return None + */ +void zbdemo_bdbInitCb(u8 status, u8 joinedNetwork){ + if(status == BDB_INIT_STATUS_SUCCESS){ + /* + * start bdb commissioning + * */ + if(joinedNetwork){ + heartInterval = 1000; + +#ifdef ZCL_OTA + ota_queryStart(OTA_PERIODIC_QUERY_INTERVAL); +#endif + }else{ + heartInterval = 500; + +#if (!ZBHCI_EN) + u16 jitter = 0; + do{ + jitter = zb_random() % 0x0fff; + }while(jitter == 0); + TL_ZB_TIMER_SCHEDULE(sampleLight_bdbNetworkSteerStart, NULL, jitter); +#endif + } + }else{ + heartInterval = 200; + } + +#if DEBUG_HEART + if(heartTimerEvt){ + TL_ZB_TIMER_CANCEL(&heartTimerEvt); + } + heartTimerEvt = TL_ZB_TIMER_SCHEDULE(heartTimerCb, NULL, heartInterval); +#endif +} + +/********************************************************************* + * @fn zbdemo_bdbCommissioningCb + * + * @brief application callback for bdb commissioning + * + * @param status - the status of bdb commissioning + * + * @param arg + * + * @return None + */ +void zbdemo_bdbCommissioningCb(u8 status, void *arg){ + if(status == BDB_COMMISSION_STA_SUCCESS){ + heartInterval = 1000; + +#if FIND_AND_BIND_SUPPORT + if(!gLightCtx.bdbFindBindFlg){ + gLightCtx.bdbFindBindFlg = TRUE; +#endif + + light_blink_start(2, 200, 200); + +#ifdef ZCL_OTA + ota_queryStart(OTA_PERIODIC_QUERY_INTERVAL); +#endif + +#if FIND_AND_BIND_SUPPORT + //start Finding & Binding + TL_ZB_TIMER_SCHEDULE(sampleLight_bdbFindAndBindStart, NULL, 1000); + } +#endif + }else if(status == BDB_COMMISSION_STA_IN_PROGRESS){ + + }else if(status == BDB_COMMISSION_STA_NOT_AA_CAPABLE){ + + }else if((status == BDB_COMMISSION_STA_NO_NETWORK)||(status == BDB_COMMISSION_STA_TCLK_EX_FAILURE)){ + u16 jitter = 0; + do{ + jitter = zb_random() % 0x0fff; + }while(jitter == 0); + TL_ZB_TIMER_SCHEDULE(sampleLight_bdbNetworkSteerStart, NULL, jitter); + }else if(status == BDB_COMMISSION_STA_TARGET_FAILURE){ + + }else if(status == BDB_COMMISSION_STA_FORMATION_FAILURE){ + + }else if(status == BDB_COMMISSION_STA_NO_IDENTIFY_QUERY_RESPONSE){ + + }else if(status == BDB_COMMISSION_STA_BINDING_TABLE_FULL){ + + }else if(status == BDB_COMMISSION_STA_NO_SCAN_RESPONSE){ + + }else if(status == BDB_COMMISSION_STA_NOT_PERMITTED){ + + }else if(status == BDB_COMMISSION_STA_REJOIN_FAILURE){ + zb_rejoinReq(NLME_REJOIN_METHOD_REJOIN, zb_apsChannelMaskGet()); + }else if(status == BDB_COMMISSION_STA_FORMATION_DONE){ +#if ZBHCI_EN + +#else + tl_zbMacChannelSet(DEFAULT_CHANNEL); //set default channel +#endif + } +} + + +extern void sampleLight_zclIdentifyCmdHandler(u8 endpoint, u16 srcAddr, u16 identifyTime); +void zbdemo_bdbIdentifyCb(u8 endpoint, u16 srcAddr, u16 identifyTime){ +#if FIND_AND_BIND_SUPPORT + sampleLight_zclIdentifyCmdHandler(endpoint, srcAddr, identifyTime); +#endif +} + + + +#ifdef ZCL_OTA +void sampleLight_otaProcessMsgHandler(u8 evt, u8 status) +{ + if(evt == OTA_EVT_START){ + if(status == ZCL_STA_SUCCESS){ + + }else{ + + } + }else if(evt == OTA_EVT_COMPLETE){ + if(status == ZCL_STA_SUCCESS){ + ota_mcuReboot(); + }else{ + ota_queryStart(OTA_PERIODIC_QUERY_INTERVAL); + } + } +} +#endif + +s32 sampleLight_softReset(void *arg){ + SYSTEM_RESET(); + + return -1; +} + +/********************************************************************* + * @fn sampleLight_leaveCnfHandler + * + * @brief Handler for ZDO Leave Confirm message. + * + * @param pRsp - parameter of leave confirm + * + * @return None + */ +void sampleLight_leaveCnfHandler(nlme_leave_cnf_t *pLeaveCnf) +{ + if(pLeaveCnf->status == SUCCESS){ + light_blink_start(3, 200, 200); + + //waiting blink over + TL_ZB_TIMER_SCHEDULE(sampleLight_softReset, NULL, 2 * 1000); + } +} + +/********************************************************************* + * @fn sampleLight_leaveIndHandler + * + * @brief Handler for ZDO leave indication message. + * + * @param pInd - parameter of leave indication + * + * @return None + */ +void sampleLight_leaveIndHandler(nlme_leave_ind_t *pLeaveInd) +{ + +} + +u8 sampleLight_nwkUpdateIndicateHandler(nwkCmd_nwkUpdate_t *pNwkUpdate){ + return FAILURE; +} + +#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */ diff --git a/zcl_colorCtrlCb.c b/zcl_colorCtrlCb.c new file mode 100644 index 0000000..47b01fe --- /dev/null +++ b/zcl_colorCtrlCb.c @@ -0,0 +1,1101 @@ +/******************************************************************************************************** + * @file zcl_colorCtrlCb.c + * + * @brief This is the source file for zcl_colorCtrlCb + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#if (__PROJECT_TL_DIMMABLE_LIGHT__) +/********************************************************************** + * INCLUDES + */ +#include "tl_common.h" +#include "zb_api.h" +#include "zcl_include.h" +#include "sampleLight.h" +#include "sampleLightCtrl.h" + +#ifdef ZCL_LIGHT_COLOR_CONTROL + +/********************************************************************** + * LOCAL CONSTANTS + */ +#define ZCL_COLOR_CHANGE_INTERVAL 100 + + + +/********************************************************************** + * TYPEDEFS + */ +typedef struct{ +#if COLOR_RGB_SUPPORT + s32 stepHue256; + u16 currentHue256; + u16 hueRemainingTime; + + s32 stepSaturation256; + u16 currentSaturation256; + u16 saturationRemainingTime; + +#elif COLOR_CCT_SUPPORT + s32 stepColorTemp256; + u32 currentColorTemp256; + u16 colorTempRemainingTime; + u16 colorTempMinMireds; + u16 colorTempMaxMireds; +#endif +}zcl_colorInfo_t; + +/********************************************************************** + * LOCAL VARIABLES + */ +static zcl_colorInfo_t colorInfo = { +#if COLOR_RGB_SUPPORT + .stepHue256 = 0, + .currentHue256 = 0, + .hueRemainingTime = 0, + + .stepSaturation256 = 0, + .currentSaturation256 = 0, + .saturationRemainingTime = 0, + +#elif COLOR_CCT_SUPPORT + .stepColorTemp256 = 0, + .currentColorTemp256 = 0, + .colorTempRemainingTime = 0, + .colorTempMinMireds = 0, + .colorTempMaxMireds = 0, +#endif +}; + +static ev_timer_event_t *colorTimerEvt = NULL; +#if COLOR_RGB_SUPPORT +static ev_timer_event_t *colorLoopTimerEvt = NULL; +#endif + + +/********************************************************************** + * FUNCTIONS + */ +void sampleLight_updateColorMode(u8 colorMode); + + +/********************************************************************* + * @fn sampleLight_colorInit + * + * @brief + * + * @param None + * + * @return None + */ +void sampleLight_colorInit(void) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + +#if COLOR_RGB_SUPPORT + pColor->colorCapabilities = ZCL_COLOR_CAPABILITIES_BIT_HUE_SATURATION; + pColor->colorMode = ZCL_COLOR_MODE_CURRENT_HUE_SATURATION; + pColor->enhancedColorMode = ZCL_COLOR_MODE_CURRENT_HUE_SATURATION; + + colorInfo.currentHue256 = (u16)(pColor->currentHue) << 8; + colorInfo.currentSaturation256 = (u16)(pColor->currentSaturation) << 8; + + colorInfo.hueRemainingTime = 0; + colorInfo.saturationRemainingTime = 0; + + light_applyUpdate(&pColor->currentHue, &colorInfo.currentHue256, &colorInfo.stepHue256, &colorInfo.hueRemainingTime, + ZCL_COLOR_ATTR_HUE_MIN, ZCL_COLOR_ATTR_HUE_MAX, TRUE); + + light_applyUpdate(&pColor->currentSaturation, &colorInfo.currentSaturation256, &colorInfo.stepSaturation256, &colorInfo.saturationRemainingTime, + ZCL_COLOR_ATTR_SATURATION_MIN, ZCL_COLOR_ATTR_SATURATION_MAX, FALSE); +#elif COLOR_CCT_SUPPORT + pColor->colorCapabilities = ZCL_COLOR_CAPABILITIES_BIT_COLOR_TEMPERATURE; + pColor->colorMode = ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS; + pColor->enhancedColorMode = ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS; + + colorInfo.currentColorTemp256 = (u32)(pColor->colorTemperatureMireds) << 8; + colorInfo.colorTempRemainingTime = 0; + + light_applyUpdate_16(&pColor->colorTemperatureMireds, &colorInfo.currentColorTemp256, &colorInfo.stepColorTemp256, &colorInfo.colorTempRemainingTime, + pColor->colorTempPhysicalMinMireds, pColor->colorTempPhysicalMaxMireds, FALSE); +#endif +} + +/********************************************************************* + * @fn sampleLight_updateColorMode + * + * @brief + * + * @param ZCL_COLOR_MODE_CURRENT_HUE_SATURATION + * ZCL_COLOR_MODE_CURRENT_X_Y + * ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS + * ZCL_ENHANCED_COLOR_MODE_CURRENT_HUE_SATURATION + * + * @return None + */ +void sampleLight_updateColorMode(u8 colorMode) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + if(colorMode != pColor->colorMode){ + if(colorMode == ZCL_COLOR_MODE_CURRENT_X_Y){ + + }else if(colorMode == ZCL_COLOR_MODE_CURRENT_HUE_SATURATION){ + + }else if(colorMode == ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS){ + + } + } +} + +/********************************************************************* + * @fn sampleLight_updateColor + * + * @brief + * + * @param None + * + * @return None + */ +void sampleLight_updateColor(void) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + zcl_levelAttr_t *pLevel = zcl_levelAttrGet(); + +#if COLOR_RGB_SUPPORT + hwLight_colorUpdate_HSV2RGB(pColor->currentHue, pColor->currentSaturation, pLevel->curLevel); +#elif COLOR_CCT_SUPPORT + hwLight_colorUpdate_colorTemperature(pColor->colorTemperatureMireds, pLevel->curLevel); +#endif +} + +/********************************************************************* + * @fn sampleLight_colorTimerEvtCb + * + * @brief + * + * @param arg + * + * @return 0: timer continue on; -1: timer will be canceled + */ +static s32 sampleLight_colorTimerEvtCb(void *arg) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + +#if COLOR_RGB_SUPPORT + if( (pColor->enhancedColorMode == ZCL_COLOR_MODE_CURRENT_HUE_SATURATION) || + (pColor->enhancedColorMode == ZCL_ENHANCED_COLOR_MODE_CURRENT_HUE_SATURATION) ){ + if(colorInfo.saturationRemainingTime){ + light_applyUpdate(&pColor->currentSaturation, &colorInfo.currentSaturation256, &colorInfo.stepSaturation256, &colorInfo.saturationRemainingTime, + ZCL_COLOR_ATTR_SATURATION_MIN, ZCL_COLOR_ATTR_SATURATION_MAX, FALSE); + } + + if(colorInfo.hueRemainingTime){ + light_applyUpdate(&pColor->currentHue, &colorInfo.currentHue256, &colorInfo.stepHue256, &colorInfo.hueRemainingTime, + ZCL_COLOR_ATTR_HUE_MIN, ZCL_COLOR_ATTR_HUE_MAX, TRUE); + } + } +#elif COLOR_CCT_SUPPORT + if(pColor->enhancedColorMode == ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS){ + if(colorInfo.colorTempRemainingTime){ + light_applyUpdate_16(&pColor->colorTemperatureMireds, &colorInfo.currentColorTemp256, &colorInfo.stepColorTemp256, &colorInfo.colorTempRemainingTime, + colorInfo.colorTempMinMireds, colorInfo.colorTempMaxMireds, FALSE); + } + } +#endif + +#if COLOR_RGB_SUPPORT + if(colorInfo.saturationRemainingTime || colorInfo.hueRemainingTime){ +#elif COLOR_CCT_SUPPORT + if(colorInfo.colorTempRemainingTime){ +#endif + return 0; + }else{ + colorTimerEvt = NULL; + return -1; + } +} + +/********************************************************************* + * @fn sampleLight_colorTimerStop + * + * @brief + * + * @param None + * + * @return None + */ +static void sampleLight_colorTimerStop(void) +{ + if(colorTimerEvt){ + TL_ZB_TIMER_CANCEL(&colorTimerEvt); + } +} + +#if COLOR_RGB_SUPPORT +/********************************************************************* + * @fn sampleLight_colorLoopTimerEvtCb + * + * @brief + * + * @param arg + * + * @return 0: timer continue on; -1: timer will be canceled + */ +static s32 sampleLight_colorLoopTimerEvtCb(void *arg) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + if(pColor->colorLoopActive){ + + }else{ + colorLoopTimerEvt = NULL; + return -1; + } + + return 0; +} + +/********************************************************************* + * @fn sampleLight_colorLoopTimerStop + * + * @brief + * + * @param None + * + * @return None + */ +static void sampleLight_colorLoopTimerStop(void) +{ + if(colorLoopTimerEvt){ + TL_ZB_TIMER_CANCEL(&colorLoopTimerEvt); + } +} + + +/********************************************************************* + * @fn sampleLight_moveToHueProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_moveToHueProcess(zcl_colorCtrlMoveToHueCmd_t *cmd) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + sampleLight_updateColorMode(ZCL_COLOR_MODE_CURRENT_HUE_SATURATION); + + pColor->colorMode = ZCL_COLOR_MODE_CURRENT_HUE_SATURATION; + pColor->enhancedColorMode = ZCL_COLOR_MODE_CURRENT_HUE_SATURATION; + + colorInfo.currentHue256 = (u16)(pColor->currentHue) << 8; + + s16 hueDiff = (s16)cmd->hue - pColor->currentHue; + + switch(cmd->direction){ + case COLOR_CTRL_DIRECTION_SHORTEST_DISTANCE: + if(hueDiff > (ZCL_COLOR_ATTR_HUE_MAX / 2)){ + hueDiff -= (ZCL_COLOR_ATTR_HUE_MAX + 1); + }else if(hueDiff < -ZCL_COLOR_ATTR_HUE_MAX / 2){ + hueDiff += (ZCL_COLOR_ATTR_HUE_MAX + 1); + } + break; + case COLOR_CTRL_DIRECTION_LONGEST_DISTANCE: + if((hueDiff > 0) && (hueDiff < (ZCL_COLOR_ATTR_HUE_MAX / 2))){ + hueDiff -= (ZCL_COLOR_ATTR_HUE_MAX + 1); + }else if((hueDiff < 0) && (hueDiff > -ZCL_COLOR_ATTR_HUE_MAX / 2)){ + hueDiff += (ZCL_COLOR_ATTR_HUE_MAX + 1); + } + break; + case COLOR_CTRL_DIRECTION_UP: + if(hueDiff < 0){ + hueDiff += ZCL_COLOR_ATTR_HUE_MAX; + } + break; + case COLOR_CTRL_DIRECTION_DOWN: + if(hueDiff > 0){ + hueDiff -= ZCL_COLOR_ATTR_HUE_MAX; + } + break; + default: + break; + } + + colorInfo.hueRemainingTime = (cmd->transitionTime == 0) ? 1 : cmd->transitionTime; + colorInfo.stepHue256 = ((s32)hueDiff) << 8; + colorInfo.stepHue256 /= (s32)colorInfo.hueRemainingTime; + + light_applyUpdate(&pColor->currentHue, &colorInfo.currentHue256, &colorInfo.stepHue256, &colorInfo.hueRemainingTime, + ZCL_COLOR_ATTR_HUE_MIN, ZCL_COLOR_ATTR_HUE_MAX, TRUE); + + if(colorInfo.hueRemainingTime){ + sampleLight_colorTimerStop(); + colorTimerEvt = TL_ZB_TIMER_SCHEDULE(sampleLight_colorTimerEvtCb, NULL, ZCL_COLOR_CHANGE_INTERVAL); + }else{ + sampleLight_colorTimerStop(); + } +} + +/********************************************************************* + * @fn sampleLight_moveHueProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_moveHueProcess(zcl_colorCtrlMoveHueCmd_t *cmd) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + sampleLight_updateColorMode(ZCL_COLOR_MODE_CURRENT_HUE_SATURATION); + + pColor->colorMode = ZCL_COLOR_MODE_CURRENT_HUE_SATURATION; + pColor->enhancedColorMode = ZCL_COLOR_MODE_CURRENT_HUE_SATURATION; + + colorInfo.currentHue256 = (u16)(pColor->currentHue) << 8; + + switch(cmd->moveMode){ + case COLOR_CTRL_MOVE_STOP: + colorInfo.stepHue256 = 0; + colorInfo.hueRemainingTime = 0; + break; + case COLOR_CTRL_MOVE_UP: + colorInfo.stepHue256 = (((s32)cmd->rate) << 8) / 10; + colorInfo.hueRemainingTime = 0xFFFF; + break; + case COLOR_CTRL_MOVE_DOWN: + colorInfo.stepHue256 = ((-(s32)cmd->rate) << 8) / 10; + colorInfo.hueRemainingTime = 0xFFFF; + break; + default: + break; + } + + light_applyUpdate(&pColor->currentHue, &colorInfo.currentHue256, &colorInfo.stepHue256, &colorInfo.hueRemainingTime, + ZCL_COLOR_ATTR_HUE_MIN, ZCL_COLOR_ATTR_HUE_MAX, TRUE); + + if(colorInfo.hueRemainingTime){ + sampleLight_colorTimerStop(); + colorTimerEvt = TL_ZB_TIMER_SCHEDULE(sampleLight_colorTimerEvtCb, NULL, ZCL_COLOR_CHANGE_INTERVAL); + }else{ + sampleLight_colorTimerStop(); + } +} + +/********************************************************************* + * @fn sampleLight_stepHueProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_stepHueProcess(zcl_colorCtrlStepHueCmd_t *cmd) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + sampleLight_updateColorMode(ZCL_COLOR_MODE_CURRENT_HUE_SATURATION); + + pColor->colorMode = ZCL_COLOR_MODE_CURRENT_HUE_SATURATION; + pColor->enhancedColorMode = ZCL_COLOR_MODE_CURRENT_HUE_SATURATION; + + colorInfo.currentHue256 = (u16)(pColor->currentHue) << 8; + + colorInfo.hueRemainingTime = (cmd->transitionTime == 0) ? 1 : cmd->transitionTime; + + colorInfo.stepHue256 = (((s32)cmd->stepSize) << 8) / colorInfo.hueRemainingTime; + + switch(cmd->stepMode){ + case COLOR_CTRL_STEP_MODE_UP: + break; + case COLOR_CTRL_STEP_MODE_DOWN: + colorInfo.stepHue256 = -colorInfo.stepHue256; + break; + default: + break; + } + + light_applyUpdate(&pColor->currentHue, &colorInfo.currentHue256, &colorInfo.stepHue256, &colorInfo.hueRemainingTime, + ZCL_COLOR_ATTR_HUE_MIN, ZCL_COLOR_ATTR_HUE_MAX, TRUE); + + if(colorInfo.hueRemainingTime){ + sampleLight_colorTimerStop(); + colorTimerEvt = TL_ZB_TIMER_SCHEDULE(sampleLight_colorTimerEvtCb, NULL, ZCL_COLOR_CHANGE_INTERVAL); + }else{ + sampleLight_colorTimerStop(); + } +} + +/********************************************************************* + * @fn sampleLight_moveToSaturationProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_moveToSaturationProcess(zcl_colorCtrlMoveToSaturationCmd_t *cmd) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + sampleLight_updateColorMode(ZCL_COLOR_MODE_CURRENT_HUE_SATURATION); + + pColor->colorMode = ZCL_COLOR_MODE_CURRENT_HUE_SATURATION; + pColor->enhancedColorMode = ZCL_COLOR_MODE_CURRENT_HUE_SATURATION; + + colorInfo.currentSaturation256 = (u16)(pColor->currentSaturation) << 8; + + colorInfo.saturationRemainingTime = (cmd->transitionTime == 0) ? 1 : cmd->transitionTime; + + colorInfo.stepSaturation256 = ((s32)(cmd->saturation - pColor->currentSaturation)) << 8; + colorInfo.stepSaturation256 /= (s32)colorInfo.saturationRemainingTime; + + light_applyUpdate(&pColor->currentSaturation, &colorInfo.currentSaturation256, &colorInfo.stepSaturation256, &colorInfo.saturationRemainingTime, + ZCL_COLOR_ATTR_SATURATION_MIN, ZCL_COLOR_ATTR_SATURATION_MAX, FALSE); + + if(colorInfo.saturationRemainingTime){ + sampleLight_colorTimerStop(); + colorTimerEvt = TL_ZB_TIMER_SCHEDULE(sampleLight_colorTimerEvtCb, NULL, ZCL_COLOR_CHANGE_INTERVAL); + }else{ + sampleLight_colorTimerStop(); + } +} + +/********************************************************************* + * @fn sampleLight_moveSaturationProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_moveSaturationProcess(zcl_colorCtrlMoveSaturationCmd_t *cmd) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + sampleLight_updateColorMode(ZCL_COLOR_MODE_CURRENT_HUE_SATURATION); + + pColor->colorMode = ZCL_COLOR_MODE_CURRENT_HUE_SATURATION; + pColor->enhancedColorMode = ZCL_COLOR_MODE_CURRENT_HUE_SATURATION; + + colorInfo.currentSaturation256 = (u16)(pColor->currentSaturation) << 8; + + switch(cmd->moveMode){ + case COLOR_CTRL_MOVE_STOP: + colorInfo.stepSaturation256 = 0; + colorInfo.saturationRemainingTime = 0; + break; + case COLOR_CTRL_MOVE_UP: + colorInfo.stepSaturation256 = (((s32)cmd->rate) << 8) / 10; + colorInfo.saturationRemainingTime = 0xFFFF; + break; + case COLOR_CTRL_MOVE_DOWN: + colorInfo.stepSaturation256 = ((-(s32)cmd->rate) << 8) / 10; + colorInfo.saturationRemainingTime = 0xFFFF; + break; + default: + break; + } + + light_applyUpdate(&pColor->currentSaturation, &colorInfo.currentSaturation256, &colorInfo.stepSaturation256, &colorInfo.saturationRemainingTime, + ZCL_COLOR_ATTR_SATURATION_MIN, ZCL_COLOR_ATTR_SATURATION_MAX, FALSE); + + if(colorInfo.saturationRemainingTime){ + sampleLight_colorTimerStop(); + colorTimerEvt = TL_ZB_TIMER_SCHEDULE(sampleLight_colorTimerEvtCb, NULL, ZCL_COLOR_CHANGE_INTERVAL); + }else{ + sampleLight_colorTimerStop(); + } +} + +/********************************************************************* + * @fn sampleLight_stepSaturationProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_stepSaturationProcess(zcl_colorCtrlStepSaturationCmd_t *cmd) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + sampleLight_updateColorMode(ZCL_COLOR_MODE_CURRENT_HUE_SATURATION); + + pColor->colorMode = ZCL_COLOR_MODE_CURRENT_HUE_SATURATION; + pColor->enhancedColorMode = ZCL_COLOR_MODE_CURRENT_HUE_SATURATION; + + colorInfo.currentSaturation256 = (u16)(pColor->currentSaturation) << 8; + + colorInfo.saturationRemainingTime = (cmd->transitionTime == 0) ? 1 : cmd->transitionTime; + + colorInfo.stepSaturation256 = (((s32)cmd->stepSize) << 8) / colorInfo.saturationRemainingTime; + + switch(cmd->stepMode){ + case COLOR_CTRL_STEP_MODE_UP: + break; + case COLOR_CTRL_STEP_MODE_DOWN: + colorInfo.stepSaturation256 = -colorInfo.stepSaturation256; + break; + default: + break; + } + + light_applyUpdate(&pColor->currentSaturation, &colorInfo.currentSaturation256, &colorInfo.stepSaturation256, &colorInfo.saturationRemainingTime, + ZCL_COLOR_ATTR_SATURATION_MIN, ZCL_COLOR_ATTR_SATURATION_MAX, FALSE); + + if(colorInfo.saturationRemainingTime){ + sampleLight_colorTimerStop(); + colorTimerEvt = TL_ZB_TIMER_SCHEDULE(sampleLight_colorTimerEvtCb, NULL, ZCL_COLOR_CHANGE_INTERVAL); + }else{ + sampleLight_colorTimerStop(); + } +} + +/********************************************************************* + * @fn sampleLight_moveToHueAndSaturationProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_moveToHueAndSaturationProcess(zcl_colorCtrlMoveToHueAndSaturationCmd_t *cmd) +{ + zcl_colorCtrlMoveToHueCmd_t moveToHueCmd; + zcl_colorCtrlMoveToSaturationCmd_t moveToSaturationCmd; + + moveToHueCmd.hue = cmd->hue; + moveToHueCmd.direction = COLOR_CTRL_DIRECTION_SHORTEST_DISTANCE; + moveToHueCmd.transitionTime = cmd->transitionTime; + + moveToSaturationCmd.saturation = cmd->saturation; + moveToSaturationCmd.transitionTime = cmd->transitionTime; + + sampleLight_moveToHueProcess(&moveToHueCmd); + sampleLight_moveToSaturationProcess(&moveToSaturationCmd); +} + +/********************************************************************* + * @fn sampleLight_moveToColorProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_moveToColorProcess(zcl_colorCtrlMoveToColorCmd_t *cmd) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + sampleLight_updateColorMode(ZCL_COLOR_MODE_CURRENT_X_Y); + + pColor->colorMode = ZCL_COLOR_MODE_CURRENT_X_Y; + pColor->enhancedColorMode = ZCL_COLOR_MODE_CURRENT_X_Y; + + +} + +/********************************************************************* + * @fn sampleLight_moveColorProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_moveColorProcess(zcl_colorCtrlMoveColorCmd_t *cmd) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + sampleLight_updateColorMode(ZCL_COLOR_MODE_CURRENT_X_Y); + + pColor->colorMode = ZCL_COLOR_MODE_CURRENT_X_Y; + pColor->enhancedColorMode = ZCL_COLOR_MODE_CURRENT_X_Y; + + +} + +/********************************************************************* + * @fn sampleLight_stepColorProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_stepColorProcess(zcl_colorCtrlStepColorCmd_t *cmd) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + sampleLight_updateColorMode(ZCL_COLOR_MODE_CURRENT_X_Y); + + pColor->colorMode = ZCL_COLOR_MODE_CURRENT_X_Y; + pColor->enhancedColorMode = ZCL_COLOR_MODE_CURRENT_X_Y; + + +} + +/********************************************************************* + * @fn sampleLight_enhancedMoveToHueProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_enhancedMoveToHueProcess(zcl_colorCtrlEnhancedMoveToHueCmd_t *cmd) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + sampleLight_updateColorMode(ZCL_COLOR_MODE_CURRENT_HUE_SATURATION); + + pColor->colorMode = ZCL_COLOR_MODE_CURRENT_HUE_SATURATION; + pColor->enhancedColorMode = ZCL_ENHANCED_COLOR_MODE_CURRENT_HUE_SATURATION; + + switch(cmd->direction){ + case COLOR_CTRL_DIRECTION_SHORTEST_DISTANCE: + break; + case COLOR_CTRL_DIRECTION_LONGEST_DISTANCE: + break; + case COLOR_CTRL_DIRECTION_UP: + break; + case COLOR_CTRL_DIRECTION_DOWN: + break; + default: + break; + } + + +} + +/********************************************************************* + * @fn sampleLight_enhancedMoveHueProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_enhancedMoveHueProcess(zcl_colorCtrlEnhancedMoveHueCmd_t *cmd) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + sampleLight_updateColorMode(ZCL_COLOR_MODE_CURRENT_HUE_SATURATION); + + pColor->colorMode = ZCL_COLOR_MODE_CURRENT_HUE_SATURATION; + pColor->enhancedColorMode = ZCL_ENHANCED_COLOR_MODE_CURRENT_HUE_SATURATION; + + switch(cmd->moveMode){ + case COLOR_CTRL_MOVE_STOP: + break; + case COLOR_CTRL_MOVE_UP: + break; + case COLOR_CTRL_MOVE_DOWN: + break; + default: + break; + } + + +} + +/********************************************************************* + * @fn sampleLight_enhancedStepHueProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_enhancedStepHueProcess(zcl_colorCtrlEnhancedStepHueCmd_t *cmd) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + sampleLight_updateColorMode(ZCL_COLOR_MODE_CURRENT_HUE_SATURATION); + + pColor->colorMode = ZCL_COLOR_MODE_CURRENT_HUE_SATURATION; + pColor->enhancedColorMode = ZCL_ENHANCED_COLOR_MODE_CURRENT_HUE_SATURATION; + + switch(cmd->stepMode){ + case COLOR_CTRL_STEP_MODE_UP: + break; + case COLOR_CTRL_STEP_MODE_DOWN: + break; + default: + break; + } + + +} + +/********************************************************************* + * @fn sampleLight_enhancedMoveToHueAndSaturationProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_enhancedMoveToHueAndSaturationProcess(zcl_colorCtrlEnhancedMoveToHueAndSaturationCmd_t *cmd) +{ + zcl_colorCtrlEnhancedMoveToHueCmd_t enhancedMoveToHueCmd; + zcl_colorCtrlMoveToSaturationCmd_t moveToSaturationCmd; + + enhancedMoveToHueCmd.enhancedHue = cmd->enhancedHue; + enhancedMoveToHueCmd.direction = COLOR_CTRL_DIRECTION_SHORTEST_DISTANCE; + enhancedMoveToHueCmd.transitionTime = cmd->transitionTime; + + moveToSaturationCmd.saturation = cmd->saturation; + moveToSaturationCmd.transitionTime = cmd->transitionTime; + + sampleLight_enhancedMoveToHueProcess(&enhancedMoveToHueCmd); + sampleLight_moveToSaturationProcess(&moveToSaturationCmd); +} + +/********************************************************************* + * @fn sampleLight_colorLoopSetProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_colorLoopSetProcess(zcl_colorCtrlColorLoopSetCmd_t *cmd) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + if(cmd->updateFlags.bits.direction){ + pColor->colorLoopDirection = cmd->direction; + } + + if(cmd->updateFlags.bits.time){ + pColor->colorLoopTime = cmd->time; + } + + if(cmd->updateFlags.bits.startHue){ + pColor->colorLoopStartEnhancedHue = cmd->startHue; + } + + if(cmd->updateFlags.bits.action){ + switch(cmd->action){ + case COLOR_LOOP_SET_DEACTION: + break; + case COLOR_LOOP_SET_ACTION_FROM_COLOR_LOOP_START_ENHANCED_HUE: + break; + case COLOR_LOOP_SET_ACTION_FROM_ENHANCED_CURRENT_HUE: + break; + default: + break; + } + } +} + +#elif COLOR_CCT_SUPPORT + +/********************************************************************* + * @fn sampleLight_moveToColorTemperatureProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_moveToColorTemperatureProcess(zcl_colorCtrlMoveToColorTemperatureCmd_t *cmd) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + sampleLight_updateColorMode(ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS); + + pColor->colorMode = ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS; + pColor->enhancedColorMode = ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS; + + colorInfo.colorTempMinMireds = pColor->colorTempPhysicalMinMireds; + colorInfo.colorTempMaxMireds = pColor->colorTempPhysicalMaxMireds; + + colorInfo.currentColorTemp256 = (u32)(pColor->colorTemperatureMireds) << 8; + + colorInfo.colorTempRemainingTime = (cmd->transitionTime == 0) ? 1 : cmd->transitionTime; + + colorInfo.stepColorTemp256 = ((s32)(cmd->colorTemperature - pColor->colorTemperatureMireds)) << 8; + colorInfo.stepColorTemp256 /= (s32)colorInfo.colorTempRemainingTime; + + light_applyUpdate_16(&pColor->colorTemperatureMireds, &colorInfo.currentColorTemp256, &colorInfo.stepColorTemp256, &colorInfo.colorTempRemainingTime, + colorInfo.colorTempMinMireds, colorInfo.colorTempMaxMireds, FALSE); + + if(colorInfo.colorTempRemainingTime){ + sampleLight_colorTimerStop(); + colorTimerEvt = TL_ZB_TIMER_SCHEDULE(sampleLight_colorTimerEvtCb, NULL, ZCL_COLOR_CHANGE_INTERVAL); + }else{ + sampleLight_colorTimerStop(); + } +} + +/********************************************************************* + * @fn sampleLight_moveColorTemperatureProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_moveColorTemperatureProcess(zcl_colorCtrlMoveColorTemperatureCmd_t *cmd) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + sampleLight_updateColorMode(ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS); + + pColor->colorMode = ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS; + pColor->enhancedColorMode = ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS; + + if(cmd->colorTempMinMireds){ + colorInfo.colorTempMinMireds = (cmd->colorTempMinMireds < pColor->colorTempPhysicalMinMireds) ? pColor->colorTempPhysicalMinMireds + : cmd->colorTempMinMireds; + }else{ + colorInfo.colorTempMinMireds = pColor->colorTempPhysicalMinMireds; + } + + if(cmd->colorTempMaxMireds){ + colorInfo.colorTempMaxMireds = (cmd->colorTempMaxMireds > pColor->colorTempPhysicalMaxMireds) ? pColor->colorTempPhysicalMaxMireds + : cmd->colorTempMaxMireds; + }else{ + colorInfo.colorTempMaxMireds = pColor->colorTempPhysicalMaxMireds; + } + + colorInfo.currentColorTemp256 = (u32)(pColor->colorTemperatureMireds) << 8; + + switch(cmd->moveMode){ + case COLOR_CTRL_MOVE_STOP: + colorInfo.stepColorTemp256 = 0; + colorInfo.colorTempRemainingTime = 0; + break; + case COLOR_CTRL_MOVE_UP: + colorInfo.stepColorTemp256 = (((s32)cmd->rate) << 8) / 10; + colorInfo.colorTempRemainingTime = 0xFFFF; + break; + case COLOR_CTRL_MOVE_DOWN: + colorInfo.stepColorTemp256 = ((-(s32)cmd->rate) << 8) / 10; + colorInfo.colorTempRemainingTime = 0xFFFF; + break; + default: + break; + } + + light_applyUpdate_16(&pColor->colorTemperatureMireds, &colorInfo.currentColorTemp256, &colorInfo.stepColorTemp256, &colorInfo.colorTempRemainingTime, + colorInfo.colorTempMinMireds, colorInfo.colorTempMaxMireds, FALSE); + + if(colorInfo.colorTempRemainingTime){ + sampleLight_colorTimerStop(); + colorTimerEvt = TL_ZB_TIMER_SCHEDULE(sampleLight_colorTimerEvtCb, NULL, ZCL_COLOR_CHANGE_INTERVAL); + }else{ + sampleLight_colorTimerStop(); + } +} + +/********************************************************************* + * @fn sampleLight_stepColorTemperatureProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_stepColorTemperatureProcess(zcl_colorCtrlStepColorTemperatureCmd_t *cmd) +{ + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + sampleLight_updateColorMode(ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS); + + pColor->colorMode = ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS; + pColor->enhancedColorMode = ZCL_COLOR_MODE_COLOR_TEMPERATURE_MIREDS; + + if(cmd->colorTempMinMireds){ + colorInfo.colorTempMinMireds = (cmd->colorTempMinMireds < pColor->colorTempPhysicalMinMireds) ? pColor->colorTempPhysicalMinMireds + : cmd->colorTempMinMireds; + }else{ + colorInfo.colorTempMinMireds = pColor->colorTempPhysicalMinMireds; + } + + if(cmd->colorTempMaxMireds){ + colorInfo.colorTempMaxMireds = (cmd->colorTempMaxMireds > pColor->colorTempPhysicalMaxMireds) ? pColor->colorTempPhysicalMaxMireds + : cmd->colorTempMaxMireds; + }else{ + colorInfo.colorTempMaxMireds = pColor->colorTempPhysicalMaxMireds; + } + + colorInfo.currentColorTemp256 = (u32)(pColor->colorTemperatureMireds) << 8; + + colorInfo.colorTempRemainingTime = (cmd->transitionTime == 0) ? 1 : cmd->transitionTime; + + colorInfo.stepColorTemp256 = (((s32)cmd->stepSize) << 8) / colorInfo.colorTempRemainingTime; + + switch(cmd->stepMode){ + case COLOR_CTRL_STEP_MODE_UP: + break; + case COLOR_CTRL_STEP_MODE_DOWN: + colorInfo.stepColorTemp256 = -colorInfo.stepColorTemp256; + break; + default: + break; + } + + light_applyUpdate_16(&pColor->colorTemperatureMireds, &colorInfo.currentColorTemp256, &colorInfo.stepColorTemp256, &colorInfo.colorTempRemainingTime, + colorInfo.colorTempMinMireds, colorInfo.colorTempMaxMireds, FALSE); + + if(colorInfo.colorTempRemainingTime){ + sampleLight_colorTimerStop(); + colorTimerEvt = TL_ZB_TIMER_SCHEDULE(sampleLight_colorTimerEvtCb, NULL, ZCL_COLOR_CHANGE_INTERVAL); + }else{ + sampleLight_colorTimerStop(); + } +} + +#endif + +/********************************************************************* + * @fn sampleLight_stopMoveStepProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_stopMoveStepProcess(void) +{ + //zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + +#if COLOR_RGB_SUPPORT + colorInfo.hueRemainingTime = 0; + colorInfo.saturationRemainingTime = 0; +#elif COLOR_CCT_SUPPORT + colorInfo.colorTempRemainingTime = 0; +#endif + + sampleLight_colorTimerStop(); +} + +/********************************************************************* + * @fn sampleLight_colorCtrlCb + * + * @brief Handler for ZCL COLOR CONTROL command. This function will set Color Control attribute first. + * + * @param pAddrInfo + * @param cmdId - color cluster command id + * @param cmdPayload + * + * @return status_t + */ +status_t sampleLight_colorCtrlCb(zclIncomingAddrInfo_t *pAddrInfo, u8 cmdId, void *cmdPayload) +{ + if(pAddrInfo->dstEp == SAMPLE_LIGHT_ENDPOINT){ + switch(cmdId){ +#if COLOR_RGB_SUPPORT + case ZCL_CMD_LIGHT_COLOR_CONTROL_MOVE_TO_HUE: + sampleLight_moveToHueProcess((zcl_colorCtrlMoveToHueCmd_t *)cmdPayload); + break; + case ZCL_CMD_LIGHT_COLOR_CONTROL_MOVE_HUE: + sampleLight_moveHueProcess((zcl_colorCtrlMoveHueCmd_t *)cmdPayload); + break; + case ZCL_CMD_LIGHT_COLOR_CONTROL_STEP_HUE: + sampleLight_stepHueProcess((zcl_colorCtrlStepHueCmd_t *)cmdPayload); + break; + case ZCL_CMD_LIGHT_COLOR_CONTROL_MOVE_TO_SATURATION: + sampleLight_moveToSaturationProcess((zcl_colorCtrlMoveToSaturationCmd_t *)cmdPayload); + break; + case ZCL_CMD_LIGHT_COLOR_CONTROL_MOVE_SATURATION: + sampleLight_moveSaturationProcess((zcl_colorCtrlMoveSaturationCmd_t *)cmdPayload); + break; + case ZCL_CMD_LIGHT_COLOR_CONTROL_STEP_SATURATION: + sampleLight_stepSaturationProcess((zcl_colorCtrlStepSaturationCmd_t *)cmdPayload); + break; + case ZCL_CMD_LIGHT_COLOR_CONTROL_MOVE_TO_HUE_AND_SATURATION: + sampleLight_moveToHueAndSaturationProcess((zcl_colorCtrlMoveToHueAndSaturationCmd_t *)cmdPayload); + break; + case ZCL_CMD_LIGHT_COLOR_CONTROL_MOVE_TO_COLOR: + sampleLight_moveToColorProcess((zcl_colorCtrlMoveToColorCmd_t *)cmdPayload); + break; + case ZCL_CMD_LIGHT_COLOR_CONTROL_MOVE_COLOR: + sampleLight_moveColorProcess((zcl_colorCtrlMoveColorCmd_t *)cmdPayload); + break; + case ZCL_CMD_LIGHT_COLOR_CONTROL_STEP_COLOR: + sampleLight_stepColorProcess((zcl_colorCtrlStepColorCmd_t *)cmdPayload); + break; + case ZCL_CMD_LIGHT_COLOR_CONTROL_ENHANCED_MOVE_TO_HUE: + sampleLight_enhancedMoveToHueProcess((zcl_colorCtrlEnhancedMoveToHueCmd_t *)cmdPayload); + break; + case ZCL_CMD_LIGHT_COLOR_CONTROL_ENHANCED_MOVE_HUE: + sampleLight_enhancedMoveHueProcess((zcl_colorCtrlEnhancedMoveHueCmd_t *)cmdPayload); + break; + case ZCL_CMD_LIGHT_COLOR_CONTROL_ENHANCED_STEP_HUE: + sampleLight_enhancedStepHueProcess((zcl_colorCtrlEnhancedStepHueCmd_t *)cmdPayload); + break; + case ZCL_CMD_LIGHT_COLOR_CONTROL_ENHANCED_MOVE_TO_HUE_AND_SATURATION: + sampleLight_enhancedMoveToHueAndSaturationProcess((zcl_colorCtrlEnhancedMoveToHueAndSaturationCmd_t *)cmdPayload); + break; + case ZCL_CMD_LIGHT_COLOR_CONTROL_COLOR_LOOP_SET: + sampleLight_colorLoopSetProcess((zcl_colorCtrlColorLoopSetCmd_t *)cmdPayload); + break; +#elif COLOR_CCT_SUPPORT + case ZCL_CMD_LIGHT_COLOR_CONTROL_MOVE_TO_COLOR_TEMPERATURE: + sampleLight_moveToColorTemperatureProcess((zcl_colorCtrlMoveToColorTemperatureCmd_t *)cmdPayload); + break; + case ZCL_CMD_LIGHT_COLOR_CONTROL_MOVE_COLOR_TEMPERATURE: + sampleLight_moveColorTemperatureProcess((zcl_colorCtrlMoveColorTemperatureCmd_t *)cmdPayload); + break; + case ZCL_CMD_LIGHT_COLOR_CONTROL_STEP_COLOR_TEMPERATURE: + sampleLight_stepColorTemperatureProcess((zcl_colorCtrlStepColorTemperatureCmd_t *)cmdPayload); + break; +#endif + case ZCL_CMD_LIGHT_COLOR_CONTROL_STOP_MOVE_STEP: + sampleLight_stopMoveStepProcess(); + break; + default: + break; + } + } + + return ZCL_STA_SUCCESS; +} + +#endif /* ZCL_LIGHT_COLOR_CONTROL */ + +#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */ diff --git a/zcl_levelCb.c b/zcl_levelCb.c new file mode 100644 index 0000000..6321a34 --- /dev/null +++ b/zcl_levelCb.c @@ -0,0 +1,354 @@ +/******************************************************************************************************** + * @file zcl_levelCb.c + * + * @brief This is the source file for zcl_levelCb + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#if (__PROJECT_TL_DIMMABLE_LIGHT__) +/********************************************************************** + * INCLUDES + */ +#include "tl_common.h" +#include "zb_api.h" +#include "zcl_include.h" +#include "sampleLight.h" +#include "sampleLightCtrl.h" + +#ifdef ZCL_LEVEL_CTRL + +/********************************************************************** + * LOCAL CONSTANTS + */ +#define ZCL_LEVEL_CHANGE_INTERVAL 100 + +/********************************************************************** + * TYPEDEFS + */ +typedef struct{ + s32 stepLevel256; + u16 currentLevel256; + u8 withOnOff; +}zcl_levelInfo_t; + +/********************************************************************** + * LOCAL VARIABLES + */ +static zcl_levelInfo_t levelInfo = { + .stepLevel256 = 0, + .currentLevel256 = 0, + .withOnOff = 0, +}; + +static ev_timer_event_t *levelTimerEvt = NULL; + +/********************************************************************** + * FUNCTIONS + */ + +/********************************************************************* + * @fn sampleLight_levelInit + * + * @brief + * + * @param None + * + * @return None + */ +void sampleLight_levelInit(void) +{ + zcl_levelAttr_t *pLevel = zcl_levelAttrGet(); + + pLevel->remainingTime = 0; + + levelInfo.currentLevel256 = (u16)(pLevel->curLevel) << 8; + + light_applyUpdate(&pLevel->curLevel, &levelInfo.currentLevel256, &levelInfo.stepLevel256, &pLevel->remainingTime, + ZCL_LEVEL_ATTR_MIN_LEVEL, ZCL_LEVEL_ATTR_MAX_LEVEL, FALSE); +} + +/********************************************************************* + * @fn sampleLight_updateLevel + * + * @brief + * + * @param None + * + * @return None + */ +void sampleLight_updateLevel(void) +{ + zcl_levelAttr_t *pLevel = zcl_levelAttrGet(); + + hwLight_levelUpdate(pLevel->curLevel); +} + +/********************************************************************* + * @fn sampleLight_levelTimerEvtCb + * + * @brief timer event to process the level command + * + * @param arg + * + * @return 0: timer continue on; -1: timer will be canceled + */ +static s32 sampleLight_levelTimerEvtCb(void * arg) +{ + zcl_levelAttr_t *pLevel = zcl_levelAttrGet(); + + if(pLevel->remainingTime){ + light_applyUpdate(&pLevel->curLevel, &levelInfo.currentLevel256, &levelInfo.stepLevel256, &pLevel->remainingTime, + ZCL_LEVEL_ATTR_MIN_LEVEL, ZCL_LEVEL_ATTR_MAX_LEVEL, FALSE); + } + + if(levelInfo.withOnOff){ + if(pLevel->curLevel == ZCL_LEVEL_ATTR_MIN_LEVEL){ + sampleLight_onoff(ZCL_CMD_ONOFF_OFF); + } + } + + if(pLevel->remainingTime){ + return 0; + }else{ + levelTimerEvt = NULL; + return -1; + } +} + +/********************************************************************* + * @fn sampleLight_LevelTimerStop + * + * @brief force to stop the level timer + * + * @param + * + * @return + */ +static void sampleLight_LevelTimerStop(void) +{ + if(levelTimerEvt){ + TL_ZB_TIMER_CANCEL(&levelTimerEvt); + } +} + +/********************************************************************* + * @fn sampleLight_moveToLevelProcess + * + * @brief + * + * @param cmdId + * @param cmd + * + * @return None + */ +static void sampleLight_moveToLevelProcess(u8 cmdId, moveToLvl_t *cmd) +{ + zcl_levelAttr_t *pLevel = zcl_levelAttrGet(); + + pLevel->remainingTime = ((cmd->transitionTime == 0) || (cmd->transitionTime == 0xFFFF)) ? 1 : cmd->transitionTime; + + levelInfo.withOnOff = (cmdId == ZCL_CMD_LEVEL_MOVE_TO_LEVEL_WITH_ON_OFF) ? TRUE : FALSE; + levelInfo.currentLevel256 = (u16)(pLevel->curLevel) << 8; + levelInfo.stepLevel256 = ((s32)(cmd->level - pLevel->curLevel)) << 8; + levelInfo.stepLevel256 /= (s32)pLevel->remainingTime; + + light_applyUpdate(&pLevel->curLevel, &levelInfo.currentLevel256, &levelInfo.stepLevel256, &pLevel->remainingTime, + ZCL_LEVEL_ATTR_MIN_LEVEL, ZCL_LEVEL_ATTR_MAX_LEVEL, FALSE); + + if(levelInfo.withOnOff){ + if(levelInfo.stepLevel256 > 0){ + sampleLight_onoff(ZCL_CMD_ONOFF_ON); + }else if(pLevel->curLevel == ZCL_LEVEL_ATTR_MIN_LEVEL){ + sampleLight_onoff(ZCL_CMD_ONOFF_OFF); + } + } + + if(pLevel->remainingTime){ + sampleLight_LevelTimerStop(); + levelTimerEvt = TL_ZB_TIMER_SCHEDULE(sampleLight_levelTimerEvtCb, NULL, ZCL_LEVEL_CHANGE_INTERVAL); + }else{ + sampleLight_LevelTimerStop(); + } +} + +/********************************************************************* + * @fn sampleLight_moveProcess + * + * @brief + * + * @param cmdId + * @param cmd + * + * @return None + */ +static void sampleLight_moveProcess(u8 cmdId, move_t *cmd) +{ + zcl_levelAttr_t *pLevel = zcl_levelAttrGet(); + + levelInfo.withOnOff = (cmdId == ZCL_CMD_LEVEL_MOVE_WITH_ON_OFF) ? TRUE : FALSE; + levelInfo.currentLevel256 = (u16)(pLevel->curLevel) << 8; + + u32 rate = (u32)cmd->rate * 100; + u8 newLevel; + u8 deltaLevel; + if(cmd->moveMode == LEVEL_MOVE_UP){ + newLevel = ZCL_LEVEL_ATTR_MAX_LEVEL; + deltaLevel = ZCL_LEVEL_ATTR_MAX_LEVEL - pLevel->curLevel; + }else{ + newLevel = ZCL_LEVEL_ATTR_MIN_LEVEL; + deltaLevel = pLevel->curLevel - ZCL_LEVEL_ATTR_MIN_LEVEL; + } + pLevel->remainingTime = ((u32)deltaLevel * 1000) / rate; + if(pLevel->remainingTime == 0){ + pLevel->remainingTime = 1; + } + + levelInfo.stepLevel256 = ((s32)(newLevel - pLevel->curLevel)) << 8; + levelInfo.stepLevel256 /= (s32)pLevel->remainingTime; + + if(cmd->moveMode == LEVEL_MOVE_UP){ + if(levelInfo.withOnOff){ + sampleLight_onoff(ZCL_CMD_ONOFF_ON); + } + } + + light_applyUpdate(&pLevel->curLevel, &levelInfo.currentLevel256, &levelInfo.stepLevel256, &pLevel->remainingTime, + ZCL_LEVEL_ATTR_MIN_LEVEL, ZCL_LEVEL_ATTR_MAX_LEVEL, FALSE); + + if(levelInfo.withOnOff){ + if(pLevel->curLevel == ZCL_LEVEL_ATTR_MIN_LEVEL){ + sampleLight_onoff(ZCL_CMD_ONOFF_OFF); + } + } + + if(pLevel->remainingTime){ + sampleLight_LevelTimerStop(); + levelTimerEvt = TL_ZB_TIMER_SCHEDULE(sampleLight_levelTimerEvtCb, NULL, ZCL_LEVEL_CHANGE_INTERVAL); + }else{ + sampleLight_LevelTimerStop(); + } +} + +/********************************************************************* + * @fn sampleLight_stepProcess + * + * @brief + * + * @param cmdId + * @param cmd + * + * @return None + */ +static void sampleLight_stepProcess(u8 cmdId, step_t *cmd) +{ + zcl_levelAttr_t *pLevel = zcl_levelAttrGet(); + + pLevel->remainingTime = ((cmd->transitionTime == 0) || (cmd->transitionTime == 0xFFFF)) ? 1 : cmd->transitionTime; + + levelInfo.withOnOff = (cmdId == ZCL_CMD_LEVEL_STEP_WITH_ON_OFF) ? TRUE : FALSE; + levelInfo.currentLevel256 = (u16)(pLevel->curLevel) << 8; + levelInfo.stepLevel256 = (((s32)cmd->stepSize) << 8) / pLevel->remainingTime; + + if(cmd->stepMode == LEVEL_STEP_UP){ + if(levelInfo.withOnOff){ + sampleLight_onoff(ZCL_CMD_ONOFF_ON); + } + }else{ + levelInfo.stepLevel256 = -levelInfo.stepLevel256; + } + + light_applyUpdate(&pLevel->curLevel, &levelInfo.currentLevel256, &levelInfo.stepLevel256, &pLevel->remainingTime, + ZCL_LEVEL_ATTR_MIN_LEVEL, ZCL_LEVEL_ATTR_MAX_LEVEL, FALSE); + + if(levelInfo.withOnOff){ + if(pLevel->curLevel == ZCL_LEVEL_ATTR_MIN_LEVEL){ + sampleLight_onoff(ZCL_CMD_ONOFF_OFF); + } + } + + if(pLevel->remainingTime){ + sampleLight_LevelTimerStop(); + levelTimerEvt = TL_ZB_TIMER_SCHEDULE(sampleLight_levelTimerEvtCb, NULL, ZCL_LEVEL_CHANGE_INTERVAL); + }else{ + sampleLight_LevelTimerStop(); + } +} + +/********************************************************************* + * @fn sampleLight_stopProcess + * + * @brief + * + * @param cmdId + * @param cmd + * + * @return None + */ +static void sampleLight_stopProcess(u8 cmdId, stop_t *cmd) +{ + zcl_levelAttr_t *pLevel = zcl_levelAttrGet(); + + sampleLight_LevelTimerStop(); + pLevel->remainingTime = 0; + + levelInfo.currentLevel256 = ((s32)pLevel->curLevel) << 8; +} + +/********************************************************************* + * @fn sampleLight_levelCb + * + * @brief Handler for ZCL LEVEL command. This function will set LEVEL attribute first. + * + * @param pAddrInfo + * @param cmd - level cluster command id + * @param cmdPayload + * + * @return status_t + */ +status_t sampleLight_levelCb(zclIncomingAddrInfo_t *pAddrInfo, u8 cmdId, void *cmdPayload) +{ + if(pAddrInfo->dstEp == SAMPLE_LIGHT_ENDPOINT){ + switch(cmdId){ + case ZCL_CMD_LEVEL_MOVE_TO_LEVEL: + case ZCL_CMD_LEVEL_MOVE_TO_LEVEL_WITH_ON_OFF: + sampleLight_moveToLevelProcess(cmdId, (moveToLvl_t *)cmdPayload); + break; + case ZCL_CMD_LEVEL_MOVE: + case ZCL_CMD_LEVEL_MOVE_WITH_ON_OFF: + sampleLight_moveProcess(cmdId, (move_t *)cmdPayload); + break; + case ZCL_CMD_LEVEL_STEP: + case ZCL_CMD_LEVEL_STEP_WITH_ON_OFF: + sampleLight_stepProcess(cmdId, (step_t *)cmdPayload); + break; + case ZCL_CMD_LEVEL_STOP: + case ZCL_CMD_LEVEL_STOP_WITH_ON_OFF: + sampleLight_stopProcess(cmdId, (stop_t *)cmdPayload); + break; + default: + break; + } + } + + return ZCL_STA_SUCCESS; +} + +#endif /* ZCL_LEVEL_CTRL */ + +#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */ diff --git a/zcl_onOffCb.c b/zcl_onOffCb.c new file mode 100644 index 0000000..6203556 --- /dev/null +++ b/zcl_onOffCb.c @@ -0,0 +1,289 @@ +/******************************************************************************************************** + * @file zcl_onOffCb.c + * + * @brief This is the source file for zcl_onOffCb + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#if (__PROJECT_TL_DIMMABLE_LIGHT__) + +/********************************************************************** + * INCLUDES + */ +#include "tl_common.h" +#include "zb_api.h" +#include "zcl_include.h" +#include "sampleLight.h" +#include "sampleLightCtrl.h" + +/********************************************************************** + * LOCAL CONSTANTS + */ +#define ZCL_ONOFF_TIMER_INTERVAL 100 //the timer interval to change the offWaitTime/onTime attribute of the ONOFF cluster + +/********************************************************************** + * LOCAL VARIABLES + */ +static ev_timer_event_t *onWithTimedOffTimerEvt = NULL; + +/********************************************************************** + * FUNCTIONS + */ + +/********************************************************************* + * @fn sampleLight_onOffInit + * + * @brief + * + * @param None + * + * @return None + */ +void sampleLight_onOffInit(void) +{ + zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet(); + + sampleLight_onoff(pOnOff->onOff); +} + +/********************************************************************* + * @fn sampleLight_updateOnOff + * + * @brief + * + * @param None + * + * @return None + */ +void sampleLight_updateOnOff(void) +{ + zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet(); + + hwLight_onOffUpdate(pOnOff->onOff); +} + +/********************************************************************* + * @fn sampleLight_onoff + * + * @brief + * + * @param ZCL_CMD_ONOFF_ON / ZCL_ONOFF_STATUS_OFF + * + * @return None + */ +void sampleLight_onoff(u8 cmd) +{ + zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet(); + + if(cmd == ZCL_CMD_ONOFF_ON){ + pOnOff->globalSceneControl = TRUE; + + pOnOff->onOff = ZCL_ONOFF_STATUS_ON; + if(pOnOff->onTime == 0){ + pOnOff->offWaitTime = 0; + } + }else if(cmd == ZCL_CMD_ONOFF_OFF){ + pOnOff->onOff = ZCL_ONOFF_STATUS_OFF; + pOnOff->onTime = 0; + }else{ + if(pOnOff->onOff == ZCL_ONOFF_STATUS_OFF){ + pOnOff->globalSceneControl = TRUE; + + pOnOff->onOff = ZCL_ONOFF_STATUS_ON; + if(pOnOff->onTime == 0){ + pOnOff->offWaitTime = 0; + } + }else{ + pOnOff->onOff = ZCL_ONOFF_STATUS_OFF; + pOnOff->onTime = 0; + } + } + + light_fresh(); + +#ifdef ZCL_SCENE + zcl_sceneAttr_t *pScene = zcl_sceneAttrGet(); + pScene->sceneValid = 0; +#endif +} + +/********************************************************************* + * @fn sampleLight_OnWithTimedOffTimerCb + * + * @brief timer event to process the ON_WITH_TIMED_OFF command + * + * @param arg + * + * @return 0: timer continue on; -1: timer will be canceled + */ +static s32 sampleLight_OnWithTimedOffTimerCb(void *arg) +{ + zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet(); + + if((pOnOff->onOff == ZCL_ONOFF_STATUS_ON) && pOnOff->onTime){ + pOnOff->onTime--; + if(pOnOff->onTime <= 0){ + pOnOff->offWaitTime = 0; + sampleLight_onoff(ZCL_CMD_ONOFF_OFF); + } + } + + if((pOnOff->onOff == ZCL_ONOFF_STATUS_OFF) && pOnOff->offWaitTime){ + pOnOff->offWaitTime--; + if(pOnOff->offWaitTime <= 0){ + onWithTimedOffTimerEvt = NULL; + return -1; + } + } + + if(pOnOff->onTime || pOnOff->offWaitTime){ + return 0; + }else{ + onWithTimedOffTimerEvt = NULL; + return -1; + } +} + +/********************************************************************* + * @fn sampleLight_OnWithTimedOffTimerStop + * + * @brief force to stop the OnWithTimedOff timer + * + * @param + * + * @return + */ +static void sampleLight_OnWithTimedOffTimerStop(void) +{ + if(onWithTimedOffTimerEvt){ + TL_ZB_TIMER_CANCEL(&onWithTimedOffTimerEvt); + } +} + +/********************************************************************* + * @fn sampleLight_onoff_onWithTimedOffProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_onoff_onWithTimedOffProcess(zcl_onoff_onWithTimeOffCmd_t *cmd) +{ + zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet(); + + if(cmd->onOffCtrl.bits.acceptOnlyWhenOn && (pOnOff->onOff == ZCL_ONOFF_STATUS_OFF)){ + return; + } + + if(pOnOff->offWaitTime && (pOnOff->onOff == ZCL_ONOFF_STATUS_OFF)){ + pOnOff->offWaitTime = min2(pOnOff->offWaitTime, cmd->offWaitTime); + }else{ + pOnOff->onTime = max2(pOnOff->onTime, cmd->onTime); + pOnOff->offWaitTime = cmd->offWaitTime; + sampleLight_onoff(ZCL_CMD_ONOFF_ON); + } + + if((pOnOff->onTime < 0xFFFF) && (pOnOff->offWaitTime < 0xFFFF)){ + if(pOnOff->onTime || pOnOff->offWaitTime){ + sampleLight_OnWithTimedOffTimerStop(); + onWithTimedOffTimerEvt = TL_ZB_TIMER_SCHEDULE(sampleLight_OnWithTimedOffTimerCb, NULL, ZCL_ONOFF_TIMER_INTERVAL); + } + } +} + +/********************************************************************* + * @fn sampleLight_onoff_offWithEffectProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_onoff_offWithEffectProcess(zcl_onoff_offWithEffectCmd_t *cmd) +{ + //TODO: FIXED ME + + sampleLight_onoff(ZCL_CMD_ONOFF_OFF); +} + +/********************************************************************* + * @fn sampleLight_onoff_onWithRecallGlobalSceneProcess + * + * @brief + * + * @param cmd + * + * @return None + */ +static void sampleLight_onoff_onWithRecallGlobalSceneProcess(void) +{ + +} + +/********************************************************************* + * @fn sampleLight_onOffCb + * + * @brief Handler for ZCL ONOFF command. This function will set ONOFF attribute first. + * + * @param pAddrInfo + * @param cmdId - onoff cluster command id + * @param cmdPayload + * + * @return status_t + */ +status_t sampleLight_onOffCb(zclIncomingAddrInfo_t *pAddrInfo, u8 cmdId, void *cmdPayload) +{ + zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet(); + + if(pAddrInfo->dstEp == SAMPLE_LIGHT_ENDPOINT){ + switch(cmdId){ + case ZCL_CMD_ONOFF_ON: + case ZCL_CMD_ONOFF_OFF: + case ZCL_CMD_ONOFF_TOGGLE: + sampleLight_onoff(cmdId); + break; + case ZCL_CMD_OFF_WITH_EFFECT: + if(pOnOff->globalSceneControl == TRUE){ + /* TODO: store its settings in its global scene */ + + pOnOff->globalSceneControl = FALSE; + } + sampleLight_onoff_offWithEffectProcess((zcl_onoff_offWithEffectCmd_t *)cmdPayload); + break; + case ZCL_CMD_ON_WITH_RECALL_GLOBAL_SCENE: + if(pOnOff->globalSceneControl == FALSE){ + sampleLight_onoff_onWithRecallGlobalSceneProcess(); + pOnOff->globalSceneControl = TRUE; + } + break; + case ZCL_CMD_ON_WITH_TIMED_OFF: + sampleLight_onoff_onWithTimedOffProcess((zcl_onoff_onWithTimeOffCmd_t *)cmdPayload); + break; + default: + break; + } + } + + return ZCL_STA_SUCCESS; +} + +#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */ diff --git a/zcl_sampleLightCb.c b/zcl_sampleLightCb.c new file mode 100644 index 0000000..d045af4 --- /dev/null +++ b/zcl_sampleLightCb.c @@ -0,0 +1,397 @@ +/******************************************************************************************************** + * @file zcl_sampleLightCb.c + * + * @brief This is the source file for zcl_sampleLightCb + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#if (__PROJECT_TL_DIMMABLE_LIGHT__) + +/********************************************************************** + * INCLUDES + */ +#include "tl_common.h" +#include "zb_api.h" +#include "zcl_include.h" +#include "ota.h" +#include "sampleLight.h" +#include "sampleLightCtrl.h" + +/********************************************************************** + * LOCAL CONSTANTS + */ + + + +/********************************************************************** + * TYPEDEFS + */ + + +/********************************************************************** + * LOCAL FUNCTIONS + */ +#ifdef ZCL_READ +static void sampleLight_zclReadRspCmd(zclReadRspCmd_t *pReadRspCmd); +#endif +#ifdef ZCL_WRITE +static void sampleLight_zclWriteReqCmd(u16 clusterId, zclWriteCmd_t *pWriteReqCmd); +static void sampleLight_zclWriteRspCmd(zclWriteRspCmd_t *pWriteRspCmd); +#endif +#ifdef ZCL_REPORT +static void sampleLight_zclCfgReportCmd(zclCfgReportCmd_t *pCfgReportCmd); +static void sampleLight_zclCfgReportRspCmd(zclCfgReportRspCmd_t *pCfgReportRspCmd); +static void sampleLight_zclReportCmd(zclReportCmd_t *pReportCmd); +#endif +static void sampleLight_zclDfltRspCmd(zclDefaultRspCmd_t *pDftRspCmd); + + +/********************************************************************** + * GLOBAL VARIABLES + */ + + +/********************************************************************** + * LOCAL VARIABLES + */ +#ifdef ZCL_IDENTIFY +static ev_timer_event_t *identifyTimerEvt = NULL; +#endif + + +/********************************************************************** + * FUNCTIONS + */ + +/********************************************************************* + * @fn sampleLight_zclProcessIncomingMsg + * + * @brief Process ZCL Foundation incoming message. + * + * @param pInMsg - pointer to the received message + * + * @return None + */ +void sampleLight_zclProcessIncomingMsg(zclIncoming_t *pInHdlrMsg) +{ +// printf("sampleLight_zclProcessIncomingMsg\n"); + + switch(pInHdlrMsg->hdr.cmd) + { +#ifdef ZCL_READ + case ZCL_CMD_READ_RSP: + sampleLight_zclReadRspCmd(pInHdlrMsg->attrCmd); + break; +#endif +#ifdef ZCL_WRITE + case ZCL_CMD_WRITE: + sampleLight_zclWriteReqCmd(pInHdlrMsg->msg->indInfo.cluster_id, pInHdlrMsg->attrCmd); + break; + case ZCL_CMD_WRITE_RSP: + sampleLight_zclWriteRspCmd(pInHdlrMsg->attrCmd); + break; +#endif +#ifdef ZCL_REPORT + case ZCL_CMD_CONFIG_REPORT: + sampleLight_zclCfgReportCmd(pInHdlrMsg->attrCmd); + break; + case ZCL_CMD_CONFIG_REPORT_RSP: + sampleLight_zclCfgReportRspCmd(pInHdlrMsg->attrCmd); + break; + case ZCL_CMD_REPORT: + sampleLight_zclReportCmd(pInHdlrMsg->attrCmd); + break; +#endif + case ZCL_CMD_DEFAULT_RSP: + sampleLight_zclDfltRspCmd(pInHdlrMsg->attrCmd); + break; + default: + break; + } +} + +#ifdef ZCL_READ +/********************************************************************* + * @fn sampleLight_zclReadRspCmd + * + * @brief Handler for ZCL Read Response command. + * + * @param pInHdlrMsg - incoming message to process + * + * @return None + */ +static void sampleLight_zclReadRspCmd(zclReadRspCmd_t *pReadRspCmd) +{ +// printf("sampleLight_zclReadRspCmd\n"); + +} +#endif + +#ifdef ZCL_WRITE +/********************************************************************* + * @fn sampleLight_zclWriteReqCmd + * + * @brief Handler for ZCL Write Request command. + * + * @param + * + * @return None + */ +static void sampleLight_zclWriteReqCmd(u16 clusterId, zclWriteCmd_t *pWriteReqCmd) +{ + u8 numAttr = pWriteReqCmd->numAttr; + zclWriteRec_t *attr = pWriteReqCmd->attrList; + + if(clusterId == ZCL_CLUSTER_GEN_ON_OFF){ + for(u8 i = 0; i < numAttr; i++){ + if(attr[i].attrID == ZCL_ATTRID_START_UP_ONOFF){ + zcl_onOffAttr_save(); + } + } + } +} + +/********************************************************************* + * @fn sampleLight_zclWriteRspCmd + * + * @brief Handler for ZCL Write Response command. + * + * @param pInHdlrMsg - incoming message to process + * + * @return None + */ +static void sampleLight_zclWriteRspCmd(zclWriteRspCmd_t *pWriteRspCmd) +{ +// printf("sampleLight_zclWriteRspCmd\n"); + +} +#endif + + +/********************************************************************* + * @fn sampleLight_zclDfltRspCmd + * + * @brief Handler for ZCL Default Response command. + * + * @param pInHdlrMsg - incoming message to process + * + * @return None + */ +static void sampleLight_zclDfltRspCmd(zclDefaultRspCmd_t *pDftRspCmd) +{ +// printf("sampleLight_zclDfltRspCmd\n"); +#ifdef ZCL_OTA + if( (pDftRspCmd->commandID == ZCL_CMD_OTA_UPGRADE_END_REQ) && + (pDftRspCmd->statusCode == ZCL_STA_ABORT) ){ + if(zcl_attr_imageUpgradeStatus == IMAGE_UPGRADE_STATUS_DOWNLOAD_COMPLETE){ + ota_upgradeAbort(); + } + } +#endif +} + +#ifdef ZCL_REPORT +/********************************************************************* + * @fn sampleLight_zclCfgReportCmd + * + * @brief Handler for ZCL Configure Report command. + * + * @param pInHdlrMsg - incoming message to process + * + * @return None + */ +static void sampleLight_zclCfgReportCmd(zclCfgReportCmd_t *pCfgReportCmd) +{ +// printf("sampleLight_zclCfgReportCmd\n"); + +} + +/********************************************************************* + * @fn sampleLight_zclCfgReportRspCmd + * + * @brief Handler for ZCL Configure Report Response command. + * + * @param pInHdlrMsg - incoming message to process + * + * @return None + */ +static void sampleLight_zclCfgReportRspCmd(zclCfgReportRspCmd_t *pCfgReportRspCmd) +{ +// printf("sampleLight_zclCfgReportRspCmd\n"); + +} + +/********************************************************************* + * @fn sampleLight_zclReportCmd + * + * @brief Handler for ZCL Report command. + * + * @param pInHdlrMsg - incoming message to process + * + * @return None + */ +static void sampleLight_zclReportCmd(zclReportCmd_t *pReportCmd) +{ +// printf("sampleLight_zclReportCmd\n"); + +} +#endif + +#ifdef ZCL_BASIC +/********************************************************************* + * @fn sampleLight_basicCb + * + * @brief Handler for ZCL Basic Reset command. + * + * @param pAddrInfo + * @param cmdId + * @param cmdPayload + * + * @return status_t + */ +status_t sampleLight_basicCb(zclIncomingAddrInfo_t *pAddrInfo, u8 cmdId, void *cmdPayload) +{ + if(cmdId == ZCL_CMD_BASIC_RESET_FAC_DEFAULT){ + //Reset all the attributes of all its clusters to factory defaults + //zcl_nv_attr_reset(); + } + + return ZCL_STA_SUCCESS; +} +#endif + +#ifdef ZCL_IDENTIFY +s32 sampleLight_zclIdentifyTimerCb(void *arg) +{ + if(g_zcl_identifyAttrs.identifyTime <= 0){ + light_blink_stop(); + + identifyTimerEvt = NULL; + return -1; + } + g_zcl_identifyAttrs.identifyTime--; + return 0; +} + +void sampleLight_zclIdentifyTimerStop(void) +{ + if(identifyTimerEvt){ + TL_ZB_TIMER_CANCEL(&identifyTimerEvt); + } +} + +/********************************************************************* + * @fn sampleLight_zclIdentifyCmdHandler + * + * @brief Handler for ZCL Identify command. This function will set blink LED. + * + * @param endpoint + * @param srcAddr + * @param identifyTime - identify time + * + * @return None + */ +void sampleLight_zclIdentifyCmdHandler(u8 endpoint, u16 srcAddr, u16 identifyTime) +{ + g_zcl_identifyAttrs.identifyTime = identifyTime; + + if(identifyTime == 0){ + sampleLight_zclIdentifyTimerStop(); + light_blink_stop(); + }else{ + if(!identifyTimerEvt){ + light_blink_start(identifyTime, 500, 500); + identifyTimerEvt = TL_ZB_TIMER_SCHEDULE(sampleLight_zclIdentifyTimerCb, NULL, 1000); + } + } +} + +/********************************************************************* + * @fn sampleLight_zcltriggerCmdHandler + * + * @brief Handler for ZCL trigger command. + * + * @param pTriggerEffect + * + * @return None + */ +static void sampleLight_zcltriggerCmdHandler(zcl_triggerEffect_t *pTriggerEffect) +{ + u8 effectId = pTriggerEffect->effectId; +// u8 effectVariant = pTriggerEffect->effectVariant; + + switch(effectId){ + case IDENTIFY_EFFECT_BLINK: + light_blink_start(1, 500, 500); + break; + case IDENTIFY_EFFECT_BREATHE: + light_blink_start(15, 300, 700); + break; + case IDENTIFY_EFFECT_OKAY: + light_blink_start(2, 250, 250); + break; + case IDENTIFY_EFFECT_CHANNEL_CHANGE: + light_blink_start(1, 500, 7500); + break; + case IDENTIFY_EFFECT_FINISH_EFFECT: + light_blink_start(1, 300, 700); + break; + case IDENTIFY_EFFECT_STOP_EFFECT: + light_blink_stop(); + break; + default: + break; + } +} + +/********************************************************************* + * @fn sampleLight_identifyCb + * + * @brief Handler for ZCL Identify command. + * + * @param pAddrInfo + * @param cmdId + * @param cmdPayload + * + * @return status_t + */ +status_t sampleLight_identifyCb(zclIncomingAddrInfo_t *pAddrInfo, u8 cmdId, void *cmdPayload) +{ + if(pAddrInfo->dstEp == SAMPLE_LIGHT_ENDPOINT){ + if(pAddrInfo->dirCluster == ZCL_FRAME_CLIENT_SERVER_DIR){ + switch(cmdId){ + case ZCL_CMD_IDENTIFY: + sampleLight_zclIdentifyCmdHandler(pAddrInfo->dstEp, pAddrInfo->srcAddr, ((zcl_identifyCmd_t *)cmdPayload)->identifyTime); + break; + case ZCL_CMD_TRIGGER_EFFECT: + sampleLight_zcltriggerCmdHandler((zcl_triggerEffect_t *)cmdPayload); + break; + default: + break; + } + } + } + + return ZCL_STA_SUCCESS; +} +#endif + +#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */ + + diff --git a/zcl_sceneCb.c b/zcl_sceneCb.c new file mode 100644 index 0000000..51f77c1 --- /dev/null +++ b/zcl_sceneCb.c @@ -0,0 +1,183 @@ +/******************************************************************************************************** + * @file zcl_sceneCb.c + * + * @brief This is the source file for zcl_sceneCb + * + * @author Zigbee Group + * @date 2021 + * + * @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************************************/ + +#if (__PROJECT_TL_DIMMABLE_LIGHT__) + + +/********************************************************************** + * INCLUDES + */ +#include "tl_common.h" +#include "zb_api.h" +#include "zcl_include.h" +#include "sampleLight.h" + + +/********************************************************************* + * @fn sampleLight_sceneRecallReqHandler + * + * @brief Handler for ZCL scene recall command. This function will recall scene. + * + * @param pApsdeInd + * @param pScene + * + * @return None + */ +static void sampleLight_sceneRecallReqHandler(zclIncomingAddrInfo_t *pAddrInfo, zcl_sceneEntry_t *pScene) +{ + u8 extLen = 0; + +#ifdef ZCL_ON_OFF + zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet(); + + pOnOff->onOff = pScene->extField[extLen+3]; + extLen += 4; +#endif + +#ifdef ZCL_LEVEL_CTRL + u8 level = pScene->extField[extLen+3]; + extLen += 4; +#endif + +#ifdef ZCL_LIGHT_COLOR_CONTROL +#if COLOR_RGB_SUPPORT + u8 hue = pScene->extField[extLen+3]; + u8 saturation = pScene->extField[extLen+4]; + extLen += 5; +#elif COLOR_CCT_SUPPORT + u16 colorTemperatureMireds = BUILD_U16(pScene->extField[extLen+3], pScene->extField[extLen+4]); + extLen += 5; +#endif +#endif + +#ifdef ZCL_LEVEL_CTRL + moveToLvl_t moveToLevel; + moveToLevel.level = level; + moveToLevel.transitionTime = pScene->transTime; + moveToLevel.optPresent = 0; + + sampleLight_levelCb(pAddrInfo, ZCL_CMD_LEVEL_MOVE_TO_LEVEL, &moveToLevel); +#endif + +#ifdef ZCL_LIGHT_COLOR_CONTROL +#if COLOR_RGB_SUPPORT + zcl_colorCtrlMoveToHueAndSaturationCmd_t move2HueAndSat; + move2HueAndSat.hue = hue; + move2HueAndSat.saturation = saturation; + move2HueAndSat.transitionTime = pScene->transTime; + move2HueAndSat.optPresent = 0; + + sampleLight_colorCtrlCb(pAddrInfo, ZCL_CMD_LIGHT_COLOR_CONTROL_MOVE_TO_HUE_AND_SATURATION, &move2HueAndSat); +#elif COLOR_CCT_SUPPORT + zcl_colorCtrlMoveToColorTemperatureCmd_t move2ColorTemp; + move2ColorTemp.colorTemperature = colorTemperatureMireds; + move2ColorTemp.transitionTime = pScene->transTime; + move2ColorTemp.optPresent = 0; + + sampleLight_colorCtrlCb(pAddrInfo, ZCL_CMD_LIGHT_COLOR_CONTROL_MOVE_TO_COLOR_TEMPERATURE, &move2ColorTemp); +#endif +#endif +} + +/********************************************************************* + * @fn sampleLight_sceneStoreReqHandler + * + * @brief Handler for ZCL scene store command. This function will set scene attribute first. + * + * @param pApsdeInd + * @param pScene + * + * @return None + */ +static void sampleLight_sceneStoreReqHandler(zcl_sceneEntry_t *pScene) +{ + /* receive Store Scene Request command, get the latest Scene info to save */ + u8 extLen = 0; + +#ifdef ZCL_ON_OFF + zcl_onOffAttr_t *pOnOff = zcl_onoffAttrGet(); + + pScene->extField[extLen++] = LO_UINT16(ZCL_CLUSTER_GEN_ON_OFF); + pScene->extField[extLen++] = HI_UINT16(ZCL_CLUSTER_GEN_ON_OFF); + pScene->extField[extLen++] = 1; + pScene->extField[extLen++] = pOnOff->onOff; +#endif + +#ifdef ZCL_LEVEL_CTRL + zcl_levelAttr_t *pLevel = zcl_levelAttrGet(); + + pScene->extField[extLen++] = LO_UINT16(ZCL_CLUSTER_GEN_LEVEL_CONTROL); + pScene->extField[extLen++] = HI_UINT16(ZCL_CLUSTER_GEN_LEVEL_CONTROL); + pScene->extField[extLen++] = 1; + pScene->extField[extLen++] = pLevel->curLevel; +#endif + +#ifdef ZCL_LIGHT_COLOR_CONTROL + zcl_lightColorCtrlAttr_t *pColor = zcl_colorAttrGet(); + + pScene->extField[extLen++] = LO_UINT16(ZCL_CLUSTER_LIGHTING_COLOR_CONTROL); + pScene->extField[extLen++] = HI_UINT16(ZCL_CLUSTER_LIGHTING_COLOR_CONTROL); +#if COLOR_RGB_SUPPORT + pScene->extField[extLen++] = 2; + pScene->extField[extLen++] = pColor->currentHue; + pScene->extField[extLen++] = pColor->currentSaturation; +#elif COLOR_CCT_SUPPORT + pScene->extField[extLen++] = 2; + pScene->extField[extLen++] = LO_UINT16(pColor->colorTemperatureMireds); + pScene->extField[extLen++] = HI_UINT16(pColor->colorTemperatureMireds); +#endif +#endif + + pScene->extFieldLen = extLen; +} + +/********************************************************************* + * @fn sampleLight_sceneCb + * + * @brief Handler for ZCL Scene command. + * + * @param pApsdeInd + * + * @return None + */ +status_t sampleLight_sceneCb(zclIncomingAddrInfo_t *pAddrInfo, u8 cmdId, void *cmdPayload) +{ + if(pAddrInfo->dstEp == SAMPLE_LIGHT_ENDPOINT){ + if(pAddrInfo->dirCluster == ZCL_FRAME_CLIENT_SERVER_DIR){ + switch(cmdId){ + case ZCL_CMD_SCENE_STORE_SCENE: + sampleLight_sceneStoreReqHandler((zcl_sceneEntry_t *)cmdPayload); + break; + case ZCL_CMD_SCENE_RECALL_SCENE: + sampleLight_sceneRecallReqHandler(pAddrInfo, (zcl_sceneEntry_t *)cmdPayload); + break; + default: + break; + } + } + } + + return ZCL_STA_SUCCESS; +} + +#endif /* __PROJECT_TL_DIMMABLE_LIGHT__ */