├── CC2530DB ├── GenericApp.dep ├── GenericApp.ewd ├── GenericApp.ewp ├── GenericApp.ewt ├── GenericApp.eww └── settings │ ├── GenericApp.CHDTECH_DEV.cspy.bat │ ├── GenericApp.CHDTECH_DEV.cspy.ps1 │ ├── GenericApp.CHDTECH_DEV.driver.xcl │ ├── GenericApp.CHDTECH_DEV.general.xcl │ ├── GenericApp.DIYRuZ_Flower.cspy.bat │ ├── GenericApp.DIYRuZ_Flower.cspy.ps1 │ ├── GenericApp.DIYRuZ_Flower.driver.xcl │ ├── GenericApp.DIYRuZ_Flower.general.xcl │ ├── GenericApp.DIYRuZ_Motion.cspy.bat │ ├── GenericApp.DIYRuZ_Motion.cspy.ps1 │ ├── GenericApp.DIYRuZ_Motion.driver.xcl │ ├── GenericApp.DIYRuZ_Motion.general.xcl │ ├── GenericApp.DIYRuZ_Motion_Router.cspy.bat │ ├── GenericApp.DIYRuZ_Motion_Router.cspy.ps1 │ ├── GenericApp.DIYRuZ_Motion_Router.driver.xcl │ ├── GenericApp.DIYRuZ_Motion_Router.general.xcl │ ├── GenericApp.dbgdt │ ├── GenericApp.dnx │ ├── GenericApp.reggroups │ ├── GenericApp.wsdt │ └── GenericApp_EditorBookmarks.xml ├── README.md ├── Source ├── OSAL_App.c ├── bh1750.c ├── bh1750.h ├── bme280spi.c ├── bme280spi.h ├── hal_board_cfg.h ├── preinclude.h ├── stdint.h ├── version.c ├── version.h ├── zcl_app.c ├── zcl_app.h └── zcl_app_data.c ├── converters ├── DIYRuZ_Motion.js ├── DIYRuZ_Motion_150724.js └── DIYRuZ_Motion_HA.js ├── firmwares └── README.md ├── hardware ├── AAA │ ├── BOM_PCB_zigbee_pir_share_036_AAA_2021-07-14.csv │ ├── Gerber_PCB_zigbee_pir_share_036_AAA_2021-07-14.zip │ └── zigbee_pir_share_AAA.pdf ├── CR2 │ ├── BOM_zigbee_multipurpose_sensor_cr2450_v4.2_CR2_2021-07-14.csv │ ├── Gerber_zigbee_multipurpose_sensor_cr2450_v4.2_CR2_2021-07-14.zip │ └── zigbee_pir_share_CR2.pdf └── datasheet │ └── 1 ├── images ├── diyruz_motion.jpg ├── diyruz_motion_1.jpg ├── diyruz_motion_2.jpg ├── diyruz_motion_3.jpg ├── diyruz_motion_4.jpg ├── diyruz_motion_5.png ├── diyruz_motion_6.jpg ├── diyruz_motion_sheme.jpg ├── motion_AAA.jpg ├── motion_CR2.jpg ├── photo_2021-07-11_18-00-41.jpg └── photo_2021-07-11_18-02-03.jpg ├── jsons2csv.py ├── ver.py └── zstack-lib ├── Debug.c ├── Debug.h ├── LICENSE ├── README.md ├── battery.h ├── bettery.c ├── commissioning.c ├── commissioning.h ├── ds18b20.c ├── ds18b20.h ├── f8wConfig.cfg ├── factory_reset.c ├── factory_reset.h ├── hal_i2c.c ├── hal_i2c.h ├── hal_key.c ├── hal_key.h ├── mhz19.c ├── mhz19.h ├── senseair.c ├── senseair.h ├── stdint.h ├── tl_resetter.c ├── tl_resetter.h ├── utils.c └── utils.h /CC2530DB/GenericApp.eww: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $WS_DIR$\GenericApp.ewp 5 | 6 | 7 | 8 | ALL 9 | 10 | GenericApp 11 | DIYRuZ_Flower_555 12 | 13 | 14 | GenericApp 15 | DIYRuZ_Flower_PWM 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.CHDTECH_DEV.cspy.bat: -------------------------------------------------------------------------------- 1 | @REM This batch file has been generated by the IAR Embedded Workbench 2 | @REM C-SPY Debugger, as an aid to preparing a command line for running 3 | @REM the cspybat command line utility using the appropriate settings. 4 | @REM 5 | @REM Note that this file is generated every time a new debug session 6 | @REM is initialized, so you may want to move or rename the file before 7 | @REM making changes. 8 | @REM 9 | @REM You can launch cspybat by typing the name of this batch file followed 10 | @REM by the name of the debug file (usually an ELF/DWARF or UBROF file). 11 | @REM 12 | @REM Read about available command line parameters in the C-SPY Debugging 13 | @REM Guide. Hints about additional command line parameters that may be 14 | @REM useful in specific cases: 15 | @REM --download_only Downloads a code image without starting a debug 16 | @REM session afterwards. 17 | @REM --silent Omits the sign-on message. 18 | @REM --timeout Limits the maximum allowed execution time. 19 | @REM 20 | 21 | 22 | @echo off 23 | 24 | if not "%~1" == "" goto debugFile 25 | 26 | @echo on 27 | 28 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\common\bin\cspybat" -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\flower-2.0.3_bme_spi\CC2530DB\settings\GenericApp.CHDTECH_DEV.general.xcl" --backend -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\flower-2.0.3_bme_spi\CC2530DB\settings\GenericApp.CHDTECH_DEV.driver.xcl" 29 | 30 | @echo off 31 | goto end 32 | 33 | :debugFile 34 | 35 | @echo on 36 | 37 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\common\bin\cspybat" -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\flower-2.0.3_bme_spi\CC2530DB\settings\GenericApp.CHDTECH_DEV.general.xcl" "--debug_file=%~1" --backend -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\flower-2.0.3_bme_spi\CC2530DB\settings\GenericApp.CHDTECH_DEV.driver.xcl" 38 | 39 | @echo off 40 | :end -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.CHDTECH_DEV.cspy.ps1: -------------------------------------------------------------------------------- 1 | param([String]$debugfile = ""); 2 | 3 | # This powershell file has been generated by the IAR Embedded Workbench 4 | # C - SPY Debugger, as an aid to preparing a command line for running 5 | # the cspybat command line utility using the appropriate settings. 6 | # 7 | # Note that this file is generated every time a new debug session 8 | # is initialized, so you may want to move or rename the file before 9 | # making changes. 10 | # 11 | # You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed 12 | # by the name of the debug file (usually an ELF / DWARF or UBROF file). 13 | # 14 | # Read about available command line parameters in the C - SPY Debugging 15 | # Guide. Hints about additional command line parameters that may be 16 | # useful in specific cases : 17 | # --download_only Downloads a code image without starting a debug 18 | # session afterwards. 19 | # --silent Omits the sign - on message. 20 | # --timeout Limits the maximum allowed execution time. 21 | # 22 | 23 | 24 | if ($debugfile -eq "") 25 | { 26 | & "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\common\bin\cspybat" -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\flower-2.0.3_bme_spi\CC2530DB\settings\GenericApp.CHDTECH_DEV.general.xcl" --backend -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\flower-2.0.3_bme_spi\CC2530DB\settings\GenericApp.CHDTECH_DEV.driver.xcl" 27 | } 28 | else 29 | { 30 | & "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\common\bin\cspybat" -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\flower-2.0.3_bme_spi\CC2530DB\settings\GenericApp.CHDTECH_DEV.general.xcl" --debug_file=$debugfile --backend -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\flower-2.0.3_bme_spi\CC2530DB\settings\GenericApp.CHDTECH_DEV.driver.xcl" 31 | } 32 | -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.CHDTECH_DEV.driver.xcl: -------------------------------------------------------------------------------- 1 | "--proc_core" 2 | 3 | "plain" 4 | 5 | "--proc_code_model" 6 | 7 | "banked" 8 | 9 | "--proc_nr_virtual_regs" 10 | 11 | "24" 12 | 13 | "--proc_pdata_bank_reg_addr" 14 | 15 | "0x93" 16 | 17 | "--proc_dptr_nr_of" 18 | 19 | "1" 20 | 21 | "--proc_codebank_reg" 22 | 23 | "0x9F" 24 | 25 | "--proc_codebank_start" 26 | 27 | "0x8000" 28 | 29 | "--proc_codebank_end" 30 | 31 | "0xFFFF" 32 | 33 | "--proc_codebank_mask" 34 | 35 | "0xFF" 36 | 37 | "--proc_data_model" 38 | 39 | "large" 40 | 41 | "-p" 42 | 43 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\8051\config\devices\Texas Instruments\ioCC2530F256.ddf" 44 | 45 | "--proc_driver" 46 | 47 | "sim" 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.CHDTECH_DEV.general.xcl: -------------------------------------------------------------------------------- 1 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\8051\bin\8051proc.dll" 2 | 3 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\8051\bin\8051sim.dll" 4 | 5 | "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\flower-2.0.3_bme_spi\CC2530DB\CHDTECH_DEV\Exe\GenericApp.d51" 6 | 7 | --plugin="C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\8051\bin\8051bat.dll" 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.DIYRuZ_Flower.cspy.bat: -------------------------------------------------------------------------------- 1 | @REM This batch file has been generated by the IAR Embedded Workbench 2 | @REM C-SPY Debugger, as an aid to preparing a command line for running 3 | @REM the cspybat command line utility using the appropriate settings. 4 | @REM 5 | @REM Note that this file is generated every time a new debug session 6 | @REM is initialized, so you may want to move or rename the file before 7 | @REM making changes. 8 | @REM 9 | @REM You can launch cspybat by typing the name of this batch file followed 10 | @REM by the name of the debug file (usually an ELF/DWARF or UBROF file). 11 | @REM 12 | @REM Read about available command line parameters in the C-SPY Debugging 13 | @REM Guide. Hints about additional command line parameters that may be 14 | @REM useful in specific cases: 15 | @REM --download_only Downloads a code image without starting a debug 16 | @REM session afterwards. 17 | @REM --silent Omits the sign-on message. 18 | @REM --timeout Limits the maximum allowed execution time. 19 | @REM 20 | 21 | 22 | @echo off 23 | 24 | if not "%~1" == "" goto debugFile 25 | 26 | @echo on 27 | 28 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\common\bin\cspybat" -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion_bme280spi_magnet_ldr_bh1750\CC2530DB\settings\GenericApp.DIYRuZ_Flower.general.xcl" --backend -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion_bme280spi_magnet_ldr_bh1750\CC2530DB\settings\GenericApp.DIYRuZ_Flower.driver.xcl" 29 | 30 | @echo off 31 | goto end 32 | 33 | :debugFile 34 | 35 | @echo on 36 | 37 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\common\bin\cspybat" -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion_bme280spi_magnet_ldr_bh1750\CC2530DB\settings\GenericApp.DIYRuZ_Flower.general.xcl" "--debug_file=%~1" --backend -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion_bme280spi_magnet_ldr_bh1750\CC2530DB\settings\GenericApp.DIYRuZ_Flower.driver.xcl" 38 | 39 | @echo off 40 | :end -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.DIYRuZ_Flower.cspy.ps1: -------------------------------------------------------------------------------- 1 | param([String]$debugfile = ""); 2 | 3 | # This powershell file has been generated by the IAR Embedded Workbench 4 | # C - SPY Debugger, as an aid to preparing a command line for running 5 | # the cspybat command line utility using the appropriate settings. 6 | # 7 | # Note that this file is generated every time a new debug session 8 | # is initialized, so you may want to move or rename the file before 9 | # making changes. 10 | # 11 | # You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed 12 | # by the name of the debug file (usually an ELF / DWARF or UBROF file). 13 | # 14 | # Read about available command line parameters in the C - SPY Debugging 15 | # Guide. Hints about additional command line parameters that may be 16 | # useful in specific cases : 17 | # --download_only Downloads a code image without starting a debug 18 | # session afterwards. 19 | # --silent Omits the sign - on message. 20 | # --timeout Limits the maximum allowed execution time. 21 | # 22 | 23 | 24 | if ($debugfile -eq "") 25 | { 26 | & "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\common\bin\cspybat" -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion_bme280spi_magnet_ldr_bh1750\CC2530DB\settings\GenericApp.DIYRuZ_Flower.general.xcl" --backend -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion_bme280spi_magnet_ldr_bh1750\CC2530DB\settings\GenericApp.DIYRuZ_Flower.driver.xcl" 27 | } 28 | else 29 | { 30 | & "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\common\bin\cspybat" -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion_bme280spi_magnet_ldr_bh1750\CC2530DB\settings\GenericApp.DIYRuZ_Flower.general.xcl" --debug_file=$debugfile --backend -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion_bme280spi_magnet_ldr_bh1750\CC2530DB\settings\GenericApp.DIYRuZ_Flower.driver.xcl" 31 | } 32 | -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.DIYRuZ_Flower.driver.xcl: -------------------------------------------------------------------------------- 1 | "--proc_core" 2 | 3 | "plain" 4 | 5 | "--proc_code_model" 6 | 7 | "banked" 8 | 9 | "--proc_nr_virtual_regs" 10 | 11 | "24" 12 | 13 | "--proc_pdata_bank_reg_addr" 14 | 15 | "0x93" 16 | 17 | "--proc_dptr_nr_of" 18 | 19 | "1" 20 | 21 | "--proc_codebank_reg" 22 | 23 | "0x9F" 24 | 25 | "--proc_codebank_start" 26 | 27 | "0x8000" 28 | 29 | "--proc_codebank_end" 30 | 31 | "0xFFFF" 32 | 33 | "--proc_codebank_mask" 34 | 35 | "0xFF" 36 | 37 | "--proc_data_model" 38 | 39 | "large" 40 | 41 | "-p" 42 | 43 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\8051\config\devices\Texas Instruments\ioCC2530F256.ddf" 44 | 45 | "--proc_driver" 46 | 47 | "sim" 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.DIYRuZ_Flower.general.xcl: -------------------------------------------------------------------------------- 1 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\8051\bin\8051proc.dll" 2 | 3 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\8051\bin\8051sim.dll" 4 | 5 | "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion_bme280spi_magnet_ldr_bh1750\CC2530DB\DIYRuZ_Flower\Exe\GenericApp.d51" 6 | 7 | --plugin="C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\8051\bin\8051bat.dll" 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.DIYRuZ_Motion.cspy.bat: -------------------------------------------------------------------------------- 1 | @REM This batch file has been generated by the IAR Embedded Workbench 2 | @REM C-SPY Debugger, as an aid to preparing a command line for running 3 | @REM the cspybat command line utility using the appropriate settings. 4 | @REM 5 | @REM Note that this file is generated every time a new debug session 6 | @REM is initialized, so you may want to move or rename the file before 7 | @REM making changes. 8 | @REM 9 | @REM You can launch cspybat by typing the name of this batch file followed 10 | @REM by the name of the debug file (usually an ELF/DWARF or UBROF file). 11 | @REM 12 | @REM Read about available command line parameters in the C-SPY Debugging 13 | @REM Guide. Hints about additional command line parameters that may be 14 | @REM useful in specific cases: 15 | @REM --download_only Downloads a code image without starting a debug 16 | @REM session afterwards. 17 | @REM --silent Omits the sign-on message. 18 | @REM --timeout Limits the maximum allowed execution time. 19 | @REM 20 | 21 | 22 | @echo off 23 | 24 | if not "%~1" == "" goto debugFile 25 | 26 | @echo on 27 | 28 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\common\bin\cspybat" -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\settings\GenericApp.DIYRuZ_Motion.general.xcl" --backend -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\settings\GenericApp.DIYRuZ_Motion.driver.xcl" 29 | 30 | @echo off 31 | goto end 32 | 33 | :debugFile 34 | 35 | @echo on 36 | 37 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\common\bin\cspybat" -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\settings\GenericApp.DIYRuZ_Motion.general.xcl" "--debug_file=%~1" --backend -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\settings\GenericApp.DIYRuZ_Motion.driver.xcl" 38 | 39 | @echo off 40 | :end -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.DIYRuZ_Motion.cspy.ps1: -------------------------------------------------------------------------------- 1 | param([String]$debugfile = ""); 2 | 3 | # This powershell file has been generated by the IAR Embedded Workbench 4 | # C - SPY Debugger, as an aid to preparing a command line for running 5 | # the cspybat command line utility using the appropriate settings. 6 | # 7 | # Note that this file is generated every time a new debug session 8 | # is initialized, so you may want to move or rename the file before 9 | # making changes. 10 | # 11 | # You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed 12 | # by the name of the debug file (usually an ELF / DWARF or UBROF file). 13 | # 14 | # Read about available command line parameters in the C - SPY Debugging 15 | # Guide. Hints about additional command line parameters that may be 16 | # useful in specific cases : 17 | # --download_only Downloads a code image without starting a debug 18 | # session afterwards. 19 | # --silent Omits the sign - on message. 20 | # --timeout Limits the maximum allowed execution time. 21 | # 22 | 23 | 24 | if ($debugfile -eq "") 25 | { 26 | & "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\common\bin\cspybat" -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\settings\GenericApp.DIYRuZ_Motion.general.xcl" --backend -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\settings\GenericApp.DIYRuZ_Motion.driver.xcl" 27 | } 28 | else 29 | { 30 | & "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\common\bin\cspybat" -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\settings\GenericApp.DIYRuZ_Motion.general.xcl" --debug_file=$debugfile --backend -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\settings\GenericApp.DIYRuZ_Motion.driver.xcl" 31 | } 32 | -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.DIYRuZ_Motion.driver.xcl: -------------------------------------------------------------------------------- 1 | "--proc_core" 2 | 3 | "plain" 4 | 5 | "--proc_code_model" 6 | 7 | "banked" 8 | 9 | "--proc_nr_virtual_regs" 10 | 11 | "24" 12 | 13 | "--proc_pdata_bank_reg_addr" 14 | 15 | "0x93" 16 | 17 | "--proc_dptr_nr_of" 18 | 19 | "1" 20 | 21 | "--proc_codebank_reg" 22 | 23 | "0x9F" 24 | 25 | "--proc_codebank_start" 26 | 27 | "0x8000" 28 | 29 | "--proc_codebank_end" 30 | 31 | "0xFFFF" 32 | 33 | "--proc_codebank_mask" 34 | 35 | "0xFF" 36 | 37 | "--proc_data_model" 38 | 39 | "large" 40 | 41 | "-p" 42 | 43 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\8051\config\devices\Texas Instruments\ioCC2530F256.ddf" 44 | 45 | "--proc_driver" 46 | 47 | "sim" 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.DIYRuZ_Motion.general.xcl: -------------------------------------------------------------------------------- 1 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\8051\bin\8051proc.dll" 2 | 3 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\8051\bin\8051sim.dll" 4 | 5 | "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\DIYRuZ_Motion\Exe\GenericApp.d51" 6 | 7 | --plugin="C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\8051\bin\8051bat.dll" 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.DIYRuZ_Motion_Router.cspy.bat: -------------------------------------------------------------------------------- 1 | @REM This batch file has been generated by the IAR Embedded Workbench 2 | @REM C-SPY Debugger, as an aid to preparing a command line for running 3 | @REM the cspybat command line utility using the appropriate settings. 4 | @REM 5 | @REM Note that this file is generated every time a new debug session 6 | @REM is initialized, so you may want to move or rename the file before 7 | @REM making changes. 8 | @REM 9 | @REM You can launch cspybat by typing the name of this batch file followed 10 | @REM by the name of the debug file (usually an ELF/DWARF or UBROF file). 11 | @REM 12 | @REM Read about available command line parameters in the C-SPY Debugging 13 | @REM Guide. Hints about additional command line parameters that may be 14 | @REM useful in specific cases: 15 | @REM --download_only Downloads a code image without starting a debug 16 | @REM session afterwards. 17 | @REM --silent Omits the sign-on message. 18 | @REM --timeout Limits the maximum allowed execution time. 19 | @REM 20 | 21 | 22 | @echo off 23 | 24 | if not "%~1" == "" goto debugFile 25 | 26 | @echo on 27 | 28 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\common\bin\cspybat" -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\settings\GenericApp.DIYRuZ_Motion_Router.general.xcl" --backend -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\settings\GenericApp.DIYRuZ_Motion_Router.driver.xcl" 29 | 30 | @echo off 31 | goto end 32 | 33 | :debugFile 34 | 35 | @echo on 36 | 37 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\common\bin\cspybat" -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\settings\GenericApp.DIYRuZ_Motion_Router.general.xcl" "--debug_file=%~1" --backend -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\settings\GenericApp.DIYRuZ_Motion_Router.driver.xcl" 38 | 39 | @echo off 40 | :end -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.DIYRuZ_Motion_Router.cspy.ps1: -------------------------------------------------------------------------------- 1 | param([String]$debugfile = ""); 2 | 3 | # This powershell file has been generated by the IAR Embedded Workbench 4 | # C - SPY Debugger, as an aid to preparing a command line for running 5 | # the cspybat command line utility using the appropriate settings. 6 | # 7 | # Note that this file is generated every time a new debug session 8 | # is initialized, so you may want to move or rename the file before 9 | # making changes. 10 | # 11 | # You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed 12 | # by the name of the debug file (usually an ELF / DWARF or UBROF file). 13 | # 14 | # Read about available command line parameters in the C - SPY Debugging 15 | # Guide. Hints about additional command line parameters that may be 16 | # useful in specific cases : 17 | # --download_only Downloads a code image without starting a debug 18 | # session afterwards. 19 | # --silent Omits the sign - on message. 20 | # --timeout Limits the maximum allowed execution time. 21 | # 22 | 23 | 24 | if ($debugfile -eq "") 25 | { 26 | & "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\common\bin\cspybat" -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\settings\GenericApp.DIYRuZ_Motion_Router.general.xcl" --backend -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\settings\GenericApp.DIYRuZ_Motion_Router.driver.xcl" 27 | } 28 | else 29 | { 30 | & "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\common\bin\cspybat" -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\settings\GenericApp.DIYRuZ_Motion_Router.general.xcl" --debug_file=$debugfile --backend -f "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\settings\GenericApp.DIYRuZ_Motion_Router.driver.xcl" 31 | } 32 | -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.DIYRuZ_Motion_Router.driver.xcl: -------------------------------------------------------------------------------- 1 | "--proc_core" 2 | 3 | "plain" 4 | 5 | "--proc_code_model" 6 | 7 | "banked" 8 | 9 | "--proc_nr_virtual_regs" 10 | 11 | "24" 12 | 13 | "--proc_pdata_bank_reg_addr" 14 | 15 | "0x93" 16 | 17 | "--proc_dptr_nr_of" 18 | 19 | "1" 20 | 21 | "--proc_codebank_reg" 22 | 23 | "0x9F" 24 | 25 | "--proc_codebank_start" 26 | 27 | "0x8000" 28 | 29 | "--proc_codebank_end" 30 | 31 | "0xFFFF" 32 | 33 | "--proc_codebank_mask" 34 | 35 | "0xFF" 36 | 37 | "--proc_data_model" 38 | 39 | "large" 40 | 41 | "-p" 42 | 43 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\8051\config\devices\Texas Instruments\ioCC2530F256.ddf" 44 | 45 | "--proc_driver" 46 | 47 | "sim" 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.DIYRuZ_Motion_Router.general.xcl: -------------------------------------------------------------------------------- 1 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\8051\bin\8051proc.dll" 2 | 3 | "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\8051\bin\8051sim.dll" 4 | 5 | "C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\motion\CC2530DB\DIYRuZ_Motion_Router\Exe\GenericApp.d51" 6 | 7 | --plugin="C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.1\8051\bin\8051bat.dll" 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.dnx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 0 5 | 1 6 | 90 7 | 1 8 | 1 9 | 1 10 | main 11 | 0 12 | 50 13 | 14 | 15 | 965769633 16 | 17 | 18 | _ 0 19 | 20 | 21 | 1 22 | 0 23 | 24 | 25 | 0 26 | 27 | 28 | 1 1 29 | 4 0 30 | 31 | 32 | 0 33 | 1 34 | 0 35 | 0 36 | 37 | 38 | 39 | 0 40 | 41 | 42 | 1 43 | 44 | 45 | _ 0 46 | _ "" 47 | 48 | 49 | _ 0 50 | _ "" 51 | _ 0 52 | 53 | 54 | 0 55 | 0 56 | 1 57 | 0 58 | 1 59 | 0 60 | 61 | 62 | 0 63 | 0 64 | 1 65 | 0 66 | 1 67 | 68 | 69 | 0 70 | 71 | 72 | 1 73 | 74 | 75 | 0 76 | 0 77 | 0 78 | 1 79 | 1 80 | 1 81 | 82 | 83 | 0 84 | 1 85 | 86 | 87 | 0 88 | 0 89 | 90 | 91 | 50000000 92 | 0 93 | 94 | 95 | -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp.reggroups: -------------------------------------------------------------------------------- 1 | group = "io", "P0" 2 | group = "Unnamed2", "P1" 3 | -------------------------------------------------------------------------------- /CC2530DB/settings/GenericApp_EditorBookmarks.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | C:\Texas Instruments\Z-Stack 3.0.2\Projects\zstack\HomeAutomation\flower-2.0.3_bme_spi_motion\Source\zcl_app_data.c 5 | 125 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # How to join: 2 | ### If device in FN(factory new) state: 3 | 1. Press and hold button (1) for 2-3 seconds, until device start flashing led 4 | 2. Wait, in case of successfull join, device will flash led 5 times 5 | 3. If join failed, device will flash led 3 times 6 | 7 | ### If device in a network: 8 | 1. Hold button (1) for 10 seconds, this will reset device to FN(factory new) status 9 | 2. Go to step 1 for FN device 10 | 11 | # Hardware 12 | ![](/images/photo_2021-07-11_18-00-41.jpg) 13 | ![](/images/photo_2021-07-11_18-02-03.jpg) 14 | ### 2AAA version 15 | ![](/images/motion_AAA.jpg) 16 | - Gerber, BOM, Scheme [2AAA](hardware/AAA/) 17 | 18 | ### CR2 version 19 | ![](/images/motion_CR2.jpg) 20 | - Gerber, BOM, Scheme [CR2](hardware/CR2/) 21 | - Attention! Do not use CR2032 and CR2450 with a motion sensor (AM312 / BS312), as at low battery voltage (<3v) false alarms occur. 22 | 23 | # Firmwares 24 | - Downalod from github [releases](https://github.com/koptserg/motion/releases) 25 | 26 | ![](/images/diyruz_motion_1.jpg) 27 | - Settings can be changed without restarting zigbee2mqtt 28 | ![](/images/diyruz_motion_2.jpg) 29 | ![](/images/diyruz_motion_3.jpg) 30 | - Bind 31 | ![](/images/diyruz_motion_4.jpg) 32 | 33 | - [Converters](converters/) 34 | 35 | ![](/images/diyruz_motion_5.png) 36 | 37 | ![](/images/diyruz_motion_6.jpg) 38 | 39 | # Thanks for the help 40 | - firmware github [diyruz](https://github.com/diyruz) by [@anonymass](https://t.me/anonymass) 41 | - hardware and testing by [@ring04](https://t.me/ring04) 42 | - telegram channel [Zigdev](https://t.me/zigdev) 43 | -------------------------------------------------------------------------------- /Source/OSAL_App.c: -------------------------------------------------------------------------------- 1 | #include "OSAL.h" 2 | #include "OSAL_Tasks.h" 3 | #include "ZComDef.h" 4 | #include "hal_drivers.h" 5 | 6 | #include "APS.h" 7 | #include "ZDApp.h" 8 | #include "nwk.h" 9 | 10 | #include "bdb_interface.h" 11 | #include "zcl_app.h" 12 | #include "factory_reset.h" 13 | #include "commissioning.h" 14 | #include "Debug.h" 15 | 16 | #if defined ( MT_TASK ) 17 | #include "MT.h" 18 | #include "MT_TASK.h" 19 | #endif 20 | 21 | const pTaskEventHandlerFn tasksArr[] = {macEventLoop, 22 | nwk_event_loop, 23 | Hal_ProcessEvent, 24 | #if defined( MT_TASK ) 25 | MT_ProcessEvent, 26 | #endif 27 | APS_event_loop, 28 | ZDApp_event_loop, 29 | zcl_event_loop, 30 | bdb_event_loop, 31 | zclApp_event_loop, 32 | zclFactoryResetter_loop, 33 | zclCommissioning_event_loop 34 | }; 35 | 36 | const uint8 tasksCnt = sizeof(tasksArr) / sizeof(tasksArr[0]); 37 | uint16 *tasksEvents; 38 | 39 | void osalInitTasks(void) { 40 | DebugInit(); 41 | uint8 taskID = 0; 42 | 43 | tasksEvents = (uint16 *)osal_mem_alloc(sizeof(uint16) * tasksCnt); 44 | osal_memset(tasksEvents, 0, (sizeof(uint16) * tasksCnt)); 45 | macTaskInit(taskID++); 46 | nwk_init(taskID++); 47 | Hal_Init(taskID++); 48 | #if defined( MT_TASK ) 49 | MT_TaskInit( taskID++ ); 50 | #endif 51 | APS_Init(taskID++); 52 | ZDApp_Init(taskID++); 53 | zcl_Init(taskID++); 54 | bdb_Init(taskID++); 55 | zclApp_Init(taskID++); 56 | zclFactoryResetter_Init(taskID++); 57 | zclCommissioning_Init(taskID++); 58 | } 59 | 60 | /********************************************************************* 61 | *********************************************************************/ 62 | -------------------------------------------------------------------------------- /Source/bh1750.c: -------------------------------------------------------------------------------- 1 | /************************************************************************************************** 2 | This is a library for the BH1750FVI Digital Light Sensor breakout board. 3 | 4 | The BH1750 board uses I2C for communication. Two pins are required to 5 | interface to the device. Configuring the I2C bus is expected to be done 6 | in user code. The BH1750 library doesn't do this automatically. 7 | 8 | Written by Christopher Laws, March, 2013. 9 | **************************************************************************************************/ 10 | #include "bh1750.h" 11 | #include "Debug.h" 12 | #include 13 | #include "hal_i2c.h" 14 | 15 | uint8 bh1750_MTreg = (uint8)BH1750_DEFAULT_MTREG; 16 | uint8 bh1750_mode = CONTINUOUS_HIGH_RES_MODE; 17 | 18 | /** 19 | * Configure BH1750 with specified mode 20 | * @param mode Measurement mode 21 | */ 22 | bool bh1750_init(uint8 mode) { 23 | // LREPMaster("[BH1750] INIT: start\r\n"); 24 | bh1850_Write(BH1750_RESET); 25 | 26 | bh1850_Write(BH1750_POWER_ON); 27 | 28 | bh1850_Write(ONE_TIME_LOW_RES_MODE); 29 | bh1750_WaitMs(30); 30 | float initread = bh1850_Read(); 31 | // LREP("[BH1750] initread 0x%X \r\n", (uint16)initread); 32 | if((uint16)initread != 0xD554){ 33 | bh1750_mode = mode; 34 | bh1850_Write(mode); 35 | bh1750_setMTreg(bh1750_MTreg); 36 | 37 | bh1850_PowerDown(); 38 | LREPMaster("[BH1750] INIT\r\n"); 39 | return 1; 40 | } 41 | LREPMaster("[BH1750] ERROR: NOT BH1750\r\n"); 42 | return 0; 43 | } 44 | 45 | /** 46 | * Configure BH1750 MTreg value 47 | * MT reg = Measurement Time register 48 | * @param MTreg a value between 32 and 254. Default: 69 49 | * @return bool true if MTReg successful set 50 | * false if MTreg not changed or parameter out of range 51 | */ 52 | bool bh1750_setMTreg(uint8 MTreg) { 53 | bh1750_MTreg = MTreg; 54 | //Bug: lowest value seems to be 32! 55 | if (MTreg <= 31 || MTreg > 254) { 56 | LREPMaster("[BH1750] ERROR: MTreg out of range\r\n"); 57 | return 0; 58 | } 59 | // Send MTreg and the current mode to the sensor 60 | // High bit: 01000_MT[7,6,5] 61 | // Low bit: 011_MT[4,3,2,1,0] 62 | bh1850_Write((0x08 << 3) | (MTreg >> 5)); 63 | bh1850_Write((0x03 << 5) | (MTreg & 0x1F)); 64 | 65 | // Wait a few moments to wake up 66 | bh1750_WaitMs(10); 67 | 68 | return 0; 69 | } 70 | 71 | void bh1850_PowerDown(void) { 72 | if (bh1750_mode == CONTINUOUS_HIGH_RES_MODE || bh1750_mode == CONTINUOUS_HIGH_RES_MODE_2 || bh1750_mode == CONTINUOUS_LOW_RES_MODE) { 73 | bh1850_Write(BH1750_POWER_DOWN); 74 | } 75 | } 76 | 77 | float bh1850_Read(void) { 78 | uint8 address = ((BH1750_I2CADDR << 1) | OCM_READ); 79 | uint8 buf[] = {0x00, 0x00}; 80 | HalI2CReceive(address, buf, 2); 81 | uint16 value16 = ((buf[0] << 8) | buf[1]); 82 | float level = 0; 83 | level = value16; 84 | if (bh1750_MTreg != BH1750_DEFAULT_MTREG) { 85 | level *= (float)((uint8)BH1750_DEFAULT_MTREG/(float)bh1750_MTreg); 86 | } 87 | if (bh1750_mode == ONE_TIME_HIGH_RES_MODE_2 || bh1750_mode == CONTINUOUS_HIGH_RES_MODE_2) { 88 | level /= 2; 89 | } 90 | // Convert raw value to lux 91 | level /= BH1750_CONV_FACTOR; 92 | LREP("[BH1750] level %d \r\n", (uint16)level); 93 | return level; 94 | } 95 | 96 | void bh1850_Write(uint8 mode) { 97 | // begin the write sequence with the address byte 98 | uint8 address = ((BH1750_I2CADDR << 1) | OCM_WRITE); 99 | uint8 buf[] = {mode}; 100 | HalI2CSend(address, buf, 1); 101 | switch (mode) { 102 | case CONTINUOUS_HIGH_RES_MODE: 103 | case CONTINUOUS_HIGH_RES_MODE_2: 104 | case CONTINUOUS_LOW_RES_MODE: 105 | case ONE_TIME_HIGH_RES_MODE: 106 | case ONE_TIME_HIGH_RES_MODE_2: 107 | case ONE_TIME_LOW_RES_MODE: 108 | // LREP("[BH1750] mode %d \r\n", mode); 109 | bh1750_mode = mode; 110 | break; 111 | default: 112 | // LREP("[BH1750] command %d \r\n", mode); 113 | break; 114 | 115 | } 116 | } 117 | 118 | void bh1750_WaitUs(uint16 microSecs) { 119 | while(microSecs--) { 120 | /* 32 NOPs == 1 usecs */ 121 | asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); 122 | asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); 123 | asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); 124 | asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); 125 | asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); 126 | asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); 127 | asm("nop"); asm("nop"); 128 | } 129 | } 130 | 131 | void bh1750_WaitMs(uint32_t period) { bh1750_WaitUs(period * 1000); } -------------------------------------------------------------------------------- /Source/bh1750.h: -------------------------------------------------------------------------------- 1 | #ifndef BH1750_H 2 | #define BH1750_H 3 | 4 | // No active state 5 | #define BH1750_POWER_DOWN 0x00 6 | 7 | // Waiting for measurement command 8 | #define BH1750_POWER_ON 0x01 9 | 10 | // Reset data register value - not accepted in POWER_DOWN mode 11 | #define BH1750_RESET 0x07 12 | 13 | // Default MTreg value 14 | #define BH1750_DEFAULT_MTREG 69 15 | 16 | #define UNCONFIGURED 0 17 | // Measurement at 1 lux resolution. Measurement time is approx 120ms. 18 | #define CONTINUOUS_HIGH_RES_MODE 0x10 19 | // Measurement at 0.5 lux resolution. Measurement time is approx 120ms. 20 | #define CONTINUOUS_HIGH_RES_MODE_2 0x11 21 | // Measurement at 4 lux resolution. Measurement time is approx 16ms. 22 | #define CONTINUOUS_LOW_RES_MODE 0x13 23 | // Measurement at 1 lux resolution. Measurement time is approx 120ms. 24 | #define ONE_TIME_HIGH_RES_MODE 0x20 25 | // Measurement at 0.5 lux resolution. Measurement time is approx 120ms. 26 | #define ONE_TIME_HIGH_RES_MODE_2 0x21 27 | // Measurement at 4 lux resolution. Measurement time is approx 16ms. 28 | #define ONE_TIME_LOW_RES_MODE 0x23 29 | 30 | #define BH1750_CONV_FACTOR 1.2 31 | 32 | #define BH1750_I2CADDR 0x23 33 | 34 | //extern uint8 bh1750_mode = CONTINUOUS_HIGH_RES_MODE; 35 | //extern uint8 bh1750_addr = BH1750_I2CADDR; 36 | //extern uint8 bh1750_mode; 37 | //extern uint8 bh1750_addr; 38 | 39 | extern bool bh1750_init(uint8 mode); 40 | extern bool bh1750_setMTreg(uint8 MTreg); 41 | extern float bh1850_Read(void); 42 | extern void bh1850_Write(uint8 mode); 43 | extern void bh1850_PowerDown(void); 44 | 45 | void bh1750_WaitUs(uint16 microSecs); 46 | void bh1750_WaitMs(uint32_t period); 47 | 48 | //const float BH1750_CONV_FACTOR = 1.2; 49 | #endif -------------------------------------------------------------------------------- /Source/bme280spi.c: -------------------------------------------------------------------------------- 1 | #include "bme280spi.h" 2 | #include "Debug.h" 3 | 4 | #include 5 | 6 | /************************************************************************************************** 7 | * CONSTANTS 8 | **************************************************************************************************/ 9 | /* 10 | LCD pins 11 | 12 | //control 13 | P0.0 - LCD_MODE (DC) 14 | P1.1 - LCD_FLASH_RESET (RST) 15 | P1.2 - LCD_CS (CS) 16 | 17 | //spi 18 | P1.5 - CLK 19 | P1.6 - MOSI 20 | P1.7 - MISO 21 | */ 22 | 23 | /* LCD Control lines */ 24 | //#define HAL_LCD_MODE_PORT 0 25 | //#define HAL_LCD_MODE_PIN 0 26 | 27 | //#define HAL_LCD_RESET_PORT 1 28 | //#define HAL_LCD_RESET_PIN 1 29 | 30 | #define HAL_LCD_CS_PORT 1 31 | #define HAL_LCD_CS_PIN 2 32 | 33 | /* LCD SPI lines */ 34 | #define HAL_LCD_CLK_PORT 1 35 | #define HAL_LCD_CLK_PIN 5 36 | 37 | #define HAL_LCD_MOSI_PORT 1 38 | #define HAL_LCD_MOSI_PIN 6 39 | 40 | #define HAL_LCD_MISO_PORT 1 41 | #define HAL_LCD_MISO_PIN 7 42 | 43 | /* SPI settings */ 44 | #define HAL_SPI_CLOCK_POL_LO 0x00 // CPOL 0 0x00, CPOL 1 0x80 45 | #define HAL_SPI_CLOCK_PHA_0 0x00 // CPHA 0 0x00, CPHA 1 0x40 46 | #define HAL_SPI_TRANSFER_MSB_FIRST 0x20 // ORDER 0 0x00 LSB first, ORDER 1 0x20 MSB first 47 | 48 | #define HAL_IO_SET(port, pin, val) HAL_IO_SET_PREP(port, pin, val) 49 | #define HAL_IO_SET_PREP(port, pin, val) st( P##port##_##pin = val; ) 50 | 51 | #define HAL_CONFIG_IO_OUTPUT(port, pin, val) HAL_CONFIG_IO_OUTPUT_PREP(port, pin, val) 52 | #define HAL_CONFIG_IO_OUTPUT_PREP(port, pin, val) st( P##port##SEL &= ~BV(pin); \ 53 | P##port##_##pin = val; \ 54 | P##port##DIR |= BV(pin); ) 55 | 56 | #define HAL_CONFIG_IO_INPUT(port, pin, val) HAL_CONFIG_IO_INPUT_PREP(port, pin, val) 57 | #define HAL_CONFIG_IO_INPUT_PREP(port, pin, val) st( P##port##SEL &= ~BV(pin); \ 58 | P##port##_##pin = val; \ 59 | P##port##DIR &= ~BV(pin); ) 60 | 61 | #define HAL_CONFIG_IO_PERIPHERAL(port, pin) HAL_CONFIG_IO_PERIPHERAL_PREP(port, pin) 62 | #define HAL_CONFIG_IO_PERIPHERAL_PREP(port, pin) st( P##port##SEL |= BV(pin); ) 63 | 64 | #define HAL_CONFIG_IO_GP(port, pin) HAL_CONFIG_IO_GP_PREP(port, pin) 65 | #define HAL_CONFIG_IO_GP_PREP(port, pin) st( P##port##SEL &= ~BV(pin); ) 66 | 67 | 68 | /* SPI interface control */ 69 | #define LCD_SPI_BEGIN() HAL_IO_SET(HAL_LCD_CS_PORT, HAL_LCD_CS_PIN, 0); /* chip select */ 70 | #define LCD_SPI_END() \ 71 | { \ 72 | asm("NOP"); \ 73 | asm("NOP"); \ 74 | asm("NOP"); \ 75 | asm("NOP"); \ 76 | HAL_IO_SET(HAL_LCD_CS_PORT, HAL_LCD_CS_PIN, 1); /* chip select */ \ 77 | } 78 | /* clear the received and transmit byte status, write tx data to buffer, wait till transmit done */ 79 | #define LCD_SPI_TX(x) { U1CSR &= ~(BV(2) | BV(1)); U1DBUF = x; while( !(U1CSR & BV(1)) ); } 80 | #define LCD_SPI_WAIT_RXRDY() { while(!(U1CSR & BV(1))); } 81 | 82 | 83 | /* Control macros */ 84 | //#define LCD_DO_WRITE() HAL_IO_SET(HAL_LCD_MODE_PORT, HAL_LCD_MODE_PIN, 1); 85 | //#define LCD_DO_CONTROL() HAL_IO_SET(HAL_LCD_MODE_PORT, HAL_LCD_MODE_PIN, 0); 86 | 87 | //#define LCD_ACTIVATE_RESET() HAL_IO_SET(HAL_LCD_RESET_PORT, HAL_LCD_RESET_PIN, 0); 88 | //#define LCD_RELEASE_RESET() HAL_IO_SET(HAL_LCD_RESET_PORT, HAL_LCD_RESET_PIN, 1); 89 | 90 | void bme_HW_WaitUs(uint16 i); 91 | void bme280_write8(uint8 reg, uint8 data); 92 | uint8 bme280_read8(uint8 reg); 93 | bool bme280_isReadingCalibration(void); 94 | void bme280_readCoefficients(void); 95 | uint8 LCD_SPI_WAIT_RX(void); 96 | uint16 bme280_read16(uint8 reg); 97 | uint16 bme280_read16_LE(uint8 reg); 98 | int16 bme280_readS16(uint8 reg); 99 | uint32 bme280_read24(uint8 reg); 100 | float bme280_readTemperature(void); 101 | float bme280_readHumidity(void); 102 | float bme280_readPressure(void); 103 | void bme280_takeForcedMeasurement(void); 104 | 105 | int32 t_fine; 106 | 107 | /**************************************************************************/ 108 | /*! 109 | @brief calibration data 110 | */ 111 | /**************************************************************************/ 112 | uint16 bme280_dig_T1; ///< temperature compensation value 113 | int16 bme280_dig_T2; ///< temperature compensation value 114 | int16 bme280_dig_T3; ///< temperature compensation value 115 | 116 | uint16 bme280_dig_P1; ///< pressure compensation value 117 | int16 bme280_dig_P2; ///< pressure compensation value 118 | int16 bme280_dig_P3; ///< pressure compensation value 119 | int16 bme280_dig_P4; ///< pressure compensation value 120 | int16 bme280_dig_P5; ///< pressure compensation value 121 | int16 bme280_dig_P6; ///< pressure compensation value 122 | int16 bme280_dig_P7; ///< pressure compensation value 123 | int16 bme280_dig_P8; ///< pressure compensation value 124 | int16 bme280_dig_P9; ///< pressure compensation value 125 | 126 | uint8 bme280_dig_H1; ///< humidity compensation value 127 | int16 bme280_dig_H2; ///< humidity compensation value 128 | uint8 bme280_dig_H3; ///< humidity compensation value 129 | int16 bme280_dig_H4; ///< humidity compensation value 130 | int16 bme280_dig_H5; ///< humidity compensation value 131 | int8 bme280_dig_H6; ///< humidity compensation value 132 | 133 | 134 | uint8 LCD_SPI_WAIT_RX(void) { 135 | while(!(U1CSR & BV(1))); 136 | return U1DBUF; 137 | } 138 | 139 | bool BME280Init(void) { 140 | 141 | /* Initialize LCD IO lines */ 142 | bme_ConfigIO(); 143 | 144 | /* Initialize SPI */ 145 | bme_ConfigSPI(); 146 | 147 | 148 | // check if sensor, i.e. the chip ID is correct 149 | uint8 chip = bme280_read8(BME280_REGISTER_CHIPID); 150 | LREP("BME280_REGISTER_CHIPID=%d\r\n", chip);; 151 | if (chip != 0x60) { 152 | LREPMaster("NOT BME280\r\n"); 153 | /* Initialize GPIO */ 154 | bme_ConfigIOInput(); 155 | bme_ConfigGP(); 156 | return 0; 157 | } 158 | 159 | // reset the device using soft-reset 160 | // this makes sure the IIR is off, etc. 161 | bme280_write8(BME280_REGISTER_SOFTRESET, 0xB6); 162 | 163 | // wait for chip to wake up. 164 | bme_HW_WaitUs(10); 165 | 166 | // if chip is still reading calibration, delay 167 | while (bme280_isReadingCalibration()) 168 | bme_HW_WaitUs(10); 169 | 170 | bme280_readCoefficients(); // read trimming parameters, see DS 4.2.2 171 | 172 | // bme280_setSampling(MODE_NORMAL, SAMPLING_X16, SAMPLING_X16, SAMPLING_X16, FILTER_OFF, STANDBY_MS_0_5); // use defaults 173 | bme280_setSampling(MODE_FORCED, SAMPLING_X2, SAMPLING_X16, SAMPLING_X1, FILTER_X16, STANDBY_MS_62_5); // air 174 | 175 | bme_HW_WaitUs(100); 176 | 177 | // float temperature = bme280_readTemperature(); 178 | // LREP("Temperature=%d\r\n", temperature); 179 | 180 | return 1; 181 | } 182 | 183 | void bme_ConfigIO(void) 184 | { 185 | /* GPIO configuration */ 186 | // HAL_CONFIG_IO_OUTPUT(HAL_LCD_MODE_PORT, HAL_LCD_MODE_PIN, 1); 187 | // HAL_CONFIG_IO_OUTPUT(HAL_LCD_RESET_PORT, HAL_LCD_RESET_PIN, 1); 188 | HAL_CONFIG_IO_OUTPUT(HAL_LCD_CS_PORT, HAL_LCD_CS_PIN, 1); 189 | } 190 | 191 | void bme_ConfigIOInput(void) 192 | { 193 | /* GPIO configuration */ 194 | HAL_CONFIG_IO_INPUT(HAL_LCD_CS_PORT, HAL_LCD_CS_PIN, 0); 195 | } 196 | 197 | void bme_ConfigSPI(void) 198 | { 199 | /* UART/SPI Peripheral configuration */ 200 | 201 | uint8 baud_exponent; 202 | uint8 baud_mantissa; 203 | 204 | /* Set SPI on UART 1 alternative 2 */ 205 | PERCFG |= 0x02; 206 | 207 | /* Configure clk, master out and master in lines */ 208 | HAL_CONFIG_IO_PERIPHERAL(HAL_LCD_CLK_PORT, HAL_LCD_CLK_PIN); 209 | HAL_CONFIG_IO_PERIPHERAL(HAL_LCD_MOSI_PORT, HAL_LCD_MOSI_PIN); 210 | HAL_CONFIG_IO_PERIPHERAL(HAL_LCD_MISO_PORT, HAL_LCD_MISO_PIN); 211 | 212 | 213 | /* Set SPI speed to 1 MHz (the values assume system clk of 32MHz) 214 | * Confirm on board that this results in 1MHz spi clk. 215 | */ 216 | baud_exponent = 15; 217 | baud_mantissa = 0; 218 | 219 | /* Configure SPI */ 220 | U1UCR = 0x00; /* Flush and goto IDLE state. 8-N-1. */ 221 | U1CSR = 0x00; /* SPI mode, master. */ 222 | U1GCR = HAL_SPI_TRANSFER_MSB_FIRST | HAL_SPI_CLOCK_PHA_0 | HAL_SPI_CLOCK_POL_LO | baud_exponent; 223 | U1BAUD = baud_mantissa; 224 | } 225 | 226 | void bme_ConfigGP(void) 227 | { 228 | /* Set SPI on UART 1 alternative 2 */ 229 | PERCFG &= ~0x02; 230 | 231 | /* Configure clk, master out and master in lines */ 232 | HAL_CONFIG_IO_GP(HAL_LCD_CLK_PORT, HAL_LCD_CLK_PIN); 233 | HAL_CONFIG_IO_GP(HAL_LCD_MOSI_PORT, HAL_LCD_MOSI_PIN); 234 | HAL_CONFIG_IO_GP(HAL_LCD_MISO_PORT, HAL_LCD_MISO_PIN); 235 | } 236 | 237 | void bme_HW_WaitUs(uint16 microSecs) 238 | { 239 | while(microSecs--) 240 | { 241 | /* 32 NOPs == 1 usecs */ 242 | asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); 243 | asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); 244 | asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); 245 | asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); 246 | asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); 247 | asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop"); 248 | asm("nop"); asm("nop"); 249 | } 250 | } 251 | 252 | void bme280_write8(uint8 reg, uint8 data) 253 | { 254 | LCD_SPI_BEGIN(); 255 | LCD_SPI_TX(reg & ~0x80); 256 | LCD_SPI_WAIT_RXRDY(); 257 | LCD_SPI_TX(data); 258 | LCD_SPI_WAIT_RXRDY(); 259 | LCD_SPI_END(); 260 | } 261 | 262 | uint8 bme280_read8(uint8 reg) 263 | { 264 | uint8 value = 0; 265 | LCD_SPI_BEGIN(); 266 | LCD_SPI_TX(reg | 0x80); 267 | LCD_SPI_WAIT_RXRDY(); 268 | LCD_SPI_TX(0); 269 | LCD_SPI_WAIT_RXRDY(); 270 | value = LCD_SPI_WAIT_RX(); 271 | LCD_SPI_END(); 272 | return value; 273 | } 274 | 275 | bool bme280_isReadingCalibration(void) { 276 | uint8 const rStatus = bme280_read8(BME280_REGISTER_STATUS); 277 | LREP("BME280_REGISTER_STATUS=%d\r\n", rStatus);; 278 | return (rStatus & (1 << 0)) != 0; 279 | } 280 | 281 | void bme280_readCoefficients(void) { 282 | bme280_dig_T1 = bme280_read16_LE(BME280_REGISTER_DIG_T1); 283 | bme280_dig_T2 = bme280_readS16_LE(BME280_REGISTER_DIG_T2); 284 | bme280_dig_T3 = bme280_readS16_LE(BME280_REGISTER_DIG_T3); 285 | 286 | bme280_dig_P1 = bme280_read16_LE(BME280_REGISTER_DIG_P1); 287 | bme280_dig_P2 = bme280_readS16_LE(BME280_REGISTER_DIG_P2); 288 | bme280_dig_P3 = bme280_readS16_LE(BME280_REGISTER_DIG_P3); 289 | bme280_dig_P4 = bme280_readS16_LE(BME280_REGISTER_DIG_P4); 290 | bme280_dig_P5 = bme280_readS16_LE(BME280_REGISTER_DIG_P5); 291 | bme280_dig_P6 = bme280_readS16_LE(BME280_REGISTER_DIG_P6); 292 | bme280_dig_P7 = bme280_readS16_LE(BME280_REGISTER_DIG_P7); 293 | bme280_dig_P8 = bme280_readS16_LE(BME280_REGISTER_DIG_P8); 294 | bme280_dig_P9 = bme280_readS16_LE(BME280_REGISTER_DIG_P9); 295 | 296 | bme280_dig_H1 = bme280_read8(BME280_REGISTER_DIG_H1); 297 | bme280_dig_H2 = bme280_readS16_LE(BME280_REGISTER_DIG_H2); 298 | bme280_dig_H3 = bme280_read8(BME280_REGISTER_DIG_H3); 299 | bme280_dig_H4 = ((int8)bme280_read8(BME280_REGISTER_DIG_H4) << 4) | 300 | (bme280_read8(BME280_REGISTER_DIG_H4 + 1) & 0xF); 301 | bme280_dig_H5 = ((int8)bme280_read8(BME280_REGISTER_DIG_H5 + 1) << 4) | 302 | (bme280_read8(BME280_REGISTER_DIG_H5) >> 4); 303 | bme280_dig_H6 = (int8)bme280_read8(BME280_REGISTER_DIG_H6); 304 | } 305 | 306 | 307 | uint16 bme280_read16(uint8 reg) { 308 | uint16 value16; 309 | 310 | LCD_SPI_BEGIN(); 311 | LCD_SPI_TX(reg | 0x80); 312 | LCD_SPI_WAIT_RXRDY(); 313 | 314 | LCD_SPI_TX(0); 315 | LCD_SPI_WAIT_RXRDY(); 316 | uint8 value_H = LCD_SPI_WAIT_RX(); 317 | LCD_SPI_TX(0); 318 | LCD_SPI_WAIT_RXRDY(); 319 | uint8 value_L = LCD_SPI_WAIT_RX(); 320 | LCD_SPI_END(); 321 | 322 | value16 = (value_H << 8) | value_L; 323 | 324 | return value16; 325 | } 326 | 327 | uint16 bme280_read16_LE(uint8 reg) { 328 | uint16 temp = bme280_read16(reg); 329 | return (temp >> 8) | (temp << 8); 330 | } 331 | 332 | int16 bme280_readS16(uint8 reg) { 333 | return (int16)bme280_read16(reg); 334 | } 335 | 336 | int16 bme280_readS16_LE(uint8 reg) { 337 | return (int16)bme280_read16_LE(reg); 338 | } 339 | 340 | uint32 bme280_read24(uint8 reg) { 341 | uint32 value32; 342 | 343 | LCD_SPI_BEGIN(); 344 | LCD_SPI_TX(reg | 0x80); 345 | LCD_SPI_WAIT_RXRDY(); 346 | 347 | LCD_SPI_TX(0); 348 | LCD_SPI_WAIT_RXRDY(); 349 | uint32 value32_1 = (uint32)LCD_SPI_WAIT_RX(); 350 | value32_1 <<= 12; 351 | 352 | LCD_SPI_TX(0); 353 | LCD_SPI_WAIT_RXRDY(); 354 | uint32 value32_2 = (uint32)LCD_SPI_WAIT_RX(); 355 | value32_2 <<= 4; 356 | 357 | LCD_SPI_TX(0); 358 | LCD_SPI_WAIT_RXRDY(); 359 | uint32 value32_3 = (uint32)LCD_SPI_WAIT_RX(); 360 | value32_3 >>= 4; 361 | LCD_SPI_END(); 362 | value32 = value32_1 | value32_2 | value32_3; 363 | return value32; 364 | } 365 | 366 | /*! 367 | * @brief setup sensor with given parameters / settings 368 | * 369 | * This is simply a overload to the normal begin()-function, so SPI users 370 | * don't get confused about the library requiring an address. 371 | * @param mode the power mode to use for the sensor 372 | * @param tempSampling the temp samping rate to use 373 | * @param pressSampling the pressure sampling rate to use 374 | * @param humSampling the humidity sampling rate to use 375 | * @param filter the filter mode to use 376 | * @param duration the standby duration to use 377 | */ 378 | void bme280_setSampling(sensor_mode mode, 379 | sensor_sampling tempSampling, 380 | sensor_sampling pressSampling, 381 | sensor_sampling humSampling, 382 | sensor_filter filter, 383 | standby_duration duration) { 384 | 385 | unsigned int configRegspi3w_en = 0; ///< unused - don't set 386 | 387 | // making sure sensor is in sleep mode before setting configuration 388 | // as it otherwise may be ignored 389 | bme280_write8(BME280_REGISTER_CONTROL, MODE_SLEEP); 390 | 391 | // you must make sure to also set REGISTER_CONTROL after setting the 392 | // CONTROLHUMID register, otherwise the values won't be applied (see 393 | // DS 5.4.3) 394 | 395 | // LREP("BME280_REGISTER_CONTROLHUMID=%d\r\n", humSampling); 396 | bme280_write8(BME280_REGISTER_CONTROLHUMID, humSampling); 397 | 398 | // LREP("BME280_REGISTER_CONFIG=%d\r\n", (duration << 5) | (filter << 2) | configRegspi3w_en); 399 | bme280_write8(BME280_REGISTER_CONFIG, (duration << 5) | (filter << 2) | configRegspi3w_en); 400 | 401 | // LREP("BME280_REGISTER_CONTROL=%d\r\n", (tempSampling << 5) | (pressSampling << 2) | mode); 402 | bme280_write8(BME280_REGISTER_CONTROL, (tempSampling << 5) | (pressSampling << 2) | mode); 403 | 404 | } 405 | 406 | void bme280_takeForcedMeasurement(void) { 407 | // If we are in forced mode, the BME sensor goes back to sleep after each 408 | // measurement and we need to set it to forced mode once at this point, so 409 | // it will take the next measurement and then return to sleep again. 410 | // In normal mode simply does new measurements periodically. 411 | 412 | bme280_write8(BME280_REGISTER_CONTROL, (SAMPLING_X16 << 5) | (SAMPLING_X16 << 2) | MODE_FORCED); 413 | // wait until measurement has been completed, otherwise we would read 414 | // the values from the last measurement 415 | while (bme280_read8(BME280_REGISTER_STATUS) & 0x08) 416 | bme_HW_WaitUs(1000); 417 | 418 | } 419 | 420 | float bme280_readTemperature(void) 421 | { 422 | int32 adc_T = bme280_read24(BME280_REGISTER_TEMPDATA); 423 | 424 | double var1; 425 | double var2; 426 | double temperature; 427 | double temperature_min = -40; 428 | double temperature_max = 85; 429 | 430 | var1 = ((double)adc_T) / 16384.0 - ((double)bme280_dig_T1) / 1024.0; 431 | var1 = var1 * ((double)bme280_dig_T2); 432 | var2 = (((double)adc_T) / 131072.0 - ((double)bme280_dig_T1) / 8192.0); 433 | var2 = (var2 * var2) * ((double)bme280_dig_T3); 434 | t_fine = (int32_t)(var1 + var2); 435 | temperature = (var1 + var2) / 5120.0; 436 | if (temperature < temperature_min) 437 | { 438 | temperature = temperature_min; 439 | } 440 | else if (temperature > temperature_max) 441 | { 442 | temperature = temperature_max; 443 | } 444 | 445 | return temperature; 446 | } 447 | 448 | float bme280_readHumidity(void) 449 | { 450 | bme280_readTemperature(); // must be done first to get t_fine 451 | 452 | int32 adc_H = bme280_read16(BME280_REGISTER_HUMIDDATA); 453 | 454 | double humidity; 455 | double humidity_min = 0.0; 456 | double humidity_max = 100.0; 457 | double var1; 458 | double var2; 459 | double var3; 460 | double var4; 461 | double var5; 462 | double var6; 463 | 464 | var1 = ((double)t_fine) - 76800.0; 465 | var2 = (((double)bme280_dig_H4) * 64.0 + (((double)bme280_dig_H5) / 16384.0) * var1); 466 | var3 = adc_H - var2; 467 | var4 = ((double)bme280_dig_H2) / 65536.0; 468 | var5 = (1.0 + (((double)bme280_dig_H3) / 67108864.0) * var1); 469 | var6 = 1.0 + (((double)bme280_dig_H6) / 67108864.0) * var1 * var5; 470 | var6 = var3 * var4 * (var5 * var6); 471 | humidity = var6 * (1.0 - ((double)bme280_dig_H1) * var6 / 524288.0); 472 | 473 | if (humidity > humidity_max) 474 | { 475 | humidity = humidity_max; 476 | } 477 | else if (humidity < humidity_min) 478 | { 479 | humidity = humidity_min; 480 | } 481 | 482 | return humidity ; 483 | } 484 | 485 | float bme280_readPressure(void) 486 | { 487 | 488 | // bme280_readTemperature(); // must be done first to get t_fine 489 | int32 adc_P = bme280_read24(BME280_REGISTER_PRESSUREDATA); 490 | double var1; 491 | double var2; 492 | double var3; 493 | double pressure; 494 | double pressure_min = 30000.0; 495 | double pressure_max = 110000.0; 496 | 497 | var1 = ((double)t_fine / 2.0) - 64000.0; 498 | var2 = var1 * var1 * ((double)bme280_dig_P6) / 32768.0; 499 | var2 = var2 + var1 * ((double)bme280_dig_P5) * 2.0; 500 | var2 = (var2 / 4.0) + (((double)bme280_dig_P4) * 65536.0); 501 | var3 = ((double)bme280_dig_P3) * var1 * var1 / 524288.0; 502 | var1 = (var3 + ((double)bme280_dig_P2) * var1) / 524288.0; 503 | var1 = (1.0 + var1 / 32768.0) * ((double)bme280_dig_P1); 504 | 505 | /* avoid exception caused by division by zero */ 506 | if (var1 > (0.0)) 507 | { 508 | pressure = 1048576.0 - (double) adc_P; 509 | pressure = (pressure - (var2 / 4096.0)) * 6250.0 / var1; 510 | var1 = ((double)bme280_dig_P9) * pressure * pressure / 2147483648.0; 511 | var2 = pressure * ((double)bme280_dig_P8) / 32768.0; 512 | pressure = pressure + (var1 + var2 + ((double)bme280_dig_P7)) / 16.0; 513 | if (pressure < pressure_min) 514 | { 515 | pressure = pressure_min; 516 | } 517 | else if (pressure > pressure_max) 518 | { 519 | pressure = pressure_max; 520 | } 521 | } 522 | else /* Invalid case */ 523 | { 524 | pressure = pressure_min; 525 | } 526 | 527 | return pressure / 100; 528 | } 529 | 530 | -------------------------------------------------------------------------------- /Source/bme280spi.h: -------------------------------------------------------------------------------- 1 | #ifndef BME280SPI_H 2 | #define BME280SPI_H 3 | 4 | void bme_ConfigIO(void); 5 | void bme_ConfigIOInput(void); 6 | void bme_ConfigSPI(void); 7 | void bme_ConfigGP(void); 8 | void bme_HW_WaitUs(uint16 i); 9 | extern void bme280_write8(uint8 reg, uint8 data); 10 | extern uint8 bme280_read8(uint8 reg); 11 | uint8 LCD_SPI_WAIT_RX(void); 12 | uint16 bme280_read16(uint8 reg); 13 | uint16 bme280_read16_LE(uint8 reg); 14 | int16 bme280_readS16(uint8 reg); 15 | int16 bme280_readS16_LE(uint8 reg); 16 | uint32 bme280_read24(uint8 reg); 17 | 18 | extern bool BME280Init(void); 19 | extern float bme280_readTemperature(void); 20 | extern float bme280_readHumidity(void); 21 | extern float bme280_readPressure(void); 22 | extern void bme280_takeForcedMeasurement(void); 23 | 24 | /**************************************************************************/ 25 | /*! 26 | @brief sampling rates 27 | */ 28 | /**************************************************************************/ 29 | enum sensor_sampling { 30 | SAMPLING_NONE = 0x00, //0b000, 31 | SAMPLING_X1 = 0x01, //0b001, 32 | SAMPLING_X2 = 0x02, //0b010, 33 | SAMPLING_X4 = 0x03, //0b011, 34 | SAMPLING_X8 = 0x04, //0b100, 35 | SAMPLING_X16 = 0x05 //0b101 36 | }; 37 | 38 | /**************************************************************************/ 39 | /*! 40 | @brief power modes 41 | */ 42 | /**************************************************************************/ 43 | enum sensor_mode { 44 | MODE_SLEEP = 0x00, //0b00, 45 | MODE_FORCED = 0x01, //0b01, 46 | MODE_NORMAL = 0x03 //0b11 47 | }; 48 | 49 | /**************************************************************************/ 50 | /*! 51 | @brief filter values 52 | */ 53 | /**************************************************************************/ 54 | enum sensor_filter { 55 | FILTER_OFF = 0x00, //0b000, 56 | FILTER_X2 = 0x01, //0b001, 57 | FILTER_X4 = 0x02, //0b010, 58 | FILTER_X8 = 0x03, //0b011, 59 | FILTER_X16 = 0x04 //0b100 60 | }; 61 | 62 | /**************************************************************************/ 63 | /*! 64 | @brief standby duration in ms 65 | */ 66 | /**************************************************************************/ 67 | enum standby_duration { 68 | STANDBY_MS_0_5 = 0x00, //0b000, 69 | STANDBY_MS_10 = 0x06, //0b110, 70 | STANDBY_MS_20 = 0x07, //0b111, 71 | STANDBY_MS_62_5 = 0x01, //0b001, 72 | STANDBY_MS_125 = 0x02, //0b010, 73 | STANDBY_MS_250 = 0x03, //0b011, 74 | STANDBY_MS_500 = 0x04, //0b100, 75 | STANDBY_MS_1000 = 0x05 //0b101 76 | }; 77 | 78 | /*! 79 | * @brief Register addresses 80 | */ 81 | enum { 82 | BME280_REGISTER_DIG_T1 = 0x88, 83 | BME280_REGISTER_DIG_T2 = 0x8A, 84 | BME280_REGISTER_DIG_T3 = 0x8C, 85 | 86 | BME280_REGISTER_DIG_P1 = 0x8E, 87 | BME280_REGISTER_DIG_P2 = 0x90, 88 | BME280_REGISTER_DIG_P3 = 0x92, 89 | BME280_REGISTER_DIG_P4 = 0x94, 90 | BME280_REGISTER_DIG_P5 = 0x96, 91 | BME280_REGISTER_DIG_P6 = 0x98, 92 | BME280_REGISTER_DIG_P7 = 0x9A, 93 | BME280_REGISTER_DIG_P8 = 0x9C, 94 | BME280_REGISTER_DIG_P9 = 0x9E, 95 | 96 | BME280_REGISTER_DIG_H1 = 0xA1, 97 | BME280_REGISTER_DIG_H2 = 0xE1, 98 | BME280_REGISTER_DIG_H3 = 0xE3, 99 | BME280_REGISTER_DIG_H4 = 0xE4, 100 | BME280_REGISTER_DIG_H5 = 0xE5, 101 | BME280_REGISTER_DIG_H6 = 0xE7, 102 | 103 | BME280_REGISTER_CHIPID = 0xD0, 104 | BME280_REGISTER_VERSION = 0xD1, 105 | BME280_REGISTER_SOFTRESET = 0xE0, 106 | 107 | BME280_REGISTER_CAL26 = 0xE1, // R calibration stored in 0xE1-0xF0 108 | 109 | BME280_REGISTER_CONTROLHUMID = 0xF2, 110 | BME280_REGISTER_STATUS = 0XF3, 111 | BME280_REGISTER_CONTROL = 0xF4, 112 | BME280_REGISTER_CONFIG = 0xF5, 113 | BME280_REGISTER_PRESSUREDATA = 0xF7, 114 | BME280_REGISTER_TEMPDATA = 0xFA, 115 | BME280_REGISTER_HUMIDDATA = 0xFD 116 | }; 117 | 118 | typedef uint8 sensor_mode; 119 | typedef uint8 sensor_sampling; 120 | typedef uint8 sensor_filter; 121 | typedef uint8 standby_duration; 122 | 123 | void bme280_setSampling(sensor_mode mode, 124 | sensor_sampling tempSampling, 125 | sensor_sampling pressSampling, 126 | sensor_sampling humSampling, 127 | sensor_filter filter, 128 | standby_duration duration); 129 | 130 | #endif -------------------------------------------------------------------------------- /Source/hal_board_cfg.h: -------------------------------------------------------------------------------- 1 | #ifndef HAL_BOARD_CFG_H 2 | #define HAL_BOARD_CFG_H 3 | 4 | 5 | /* ------------------------------------------------------------------------------------------------ 6 | * Includes 7 | * ------------------------------------------------------------------------------------------------ 8 | */ 9 | 10 | #include "hal_mcu.h" 11 | #include "hal_defs.h" 12 | #include "hal_types.h" 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | /* ------------------------------------------------------------------------------------------------ 21 | * Clock Speed 22 | * ------------------------------------------------------------------------------------------------ 23 | */ 24 | 25 | #define HAL_CPU_CLOCK_MHZ 32 26 | 27 | /* 32 kHz clock source select in CLKCONCMD */ 28 | #if !defined (OSC32K_CRYSTAL_INSTALLED) || (defined (OSC32K_CRYSTAL_INSTALLED) && (OSC32K_CRYSTAL_INSTALLED == TRUE)) 29 | #define OSC_32KHZ 0x00 /* external 32 KHz xosc */ 30 | #else 31 | #define OSC_32KHZ 0x80 /* internal 32 KHz rcosc */ 32 | #endif 33 | 34 | #define HAL_CLOCK_STABLE() 35 | 36 | /* ------------------------------------------------------------------------------------------------ 37 | * Key Release detect support 38 | * ------------------------------------------------------------------------------------------------ 39 | */ 40 | #define HAL_KEY_CODE_NOKEY 0xff 41 | 42 | 43 | /* ------------------------------------------------------------------------------------------------ 44 | * LED Configuration 45 | * ------------------------------------------------------------------------------------------------ 46 | */ 47 | 48 | // TODO: review all HAL_BOARD_CC2530EB_REV17 and replace with HAL_BOARD_CC2530RC 49 | // if applicable. 50 | #define HAL_NUM_LEDS 0 51 | 52 | #define HAL_LED_BLINK_DELAY() st( { volatile uint32 i; for (i=0; i<0x5800; i++) { }; } ) 53 | #define ACTIVE_LOW ! 54 | #define ACTIVE_HIGH !! /* double negation forces result to be '1' */ 55 | 56 | /* ------------------------------------------------------------------------------------------------ 57 | * OSAL NV implemented by internal flash pages. 58 | * ------------------------------------------------------------------------------------------------ 59 | */ 60 | 61 | // Flash is partitioned into 8 banks of 32 KB or 16 pages. 62 | #define HAL_FLASH_PAGE_PER_BANK 16 63 | // Flash is constructed of 128 pages of 2 KB. 64 | #define HAL_FLASH_PAGE_SIZE 2048 65 | #define HAL_FLASH_WORD_SIZE 4 66 | 67 | // CODE banks get mapped into the XDATA range 8000-FFFF. 68 | #define HAL_FLASH_PAGE_MAP 0x8000 69 | 70 | // The last 16 bytes of the last available page are reserved for flash lock bits. 71 | // NV page definitions must coincide with segment declaration in project *.xcl file. 72 | #if defined NON_BANKED 73 | #define HAL_FLASH_LOCK_BITS 16 74 | #define HAL_NV_PAGE_END 30 75 | #define HAL_NV_PAGE_CNT 2 76 | #else 77 | #define HAL_FLASH_LOCK_BITS 16 78 | #define HAL_NV_PAGE_END 126 79 | #define HAL_NV_PAGE_CNT 6 80 | #endif 81 | 82 | // Re-defining Z_EXTADDR_LEN here so as not to include a Z-Stack .h file. 83 | #define HAL_FLASH_IEEE_SIZE 8 84 | #define HAL_FLASH_IEEE_PAGE (HAL_NV_PAGE_END+1) 85 | #define HAL_FLASH_IEEE_OSET (HAL_FLASH_PAGE_SIZE - HAL_FLASH_LOCK_BITS - HAL_FLASH_IEEE_SIZE) 86 | #define HAL_INFOP_IEEE_OSET 0xC 87 | 88 | #define HAL_FLASH_DEV_PRIVATE_KEY_OSET 0x7D2 89 | #define HAL_FLASH_CA_PUBLIC_KEY_OSET 0x7BC 90 | #define HAL_FLASH_IMPLICIT_CERT_OSET 0x78C 91 | 92 | #define HAL_NV_PAGE_BEG (HAL_NV_PAGE_END-HAL_NV_PAGE_CNT+1) 93 | // Used by DMA macros to shift 1 to create a mask for DMA registers. 94 | #define HAL_NV_DMA_CH 0 95 | #define HAL_DMA_CH_RX 3 96 | #define HAL_DMA_CH_TX 4 97 | 98 | #define HAL_NV_DMA_GET_DESC() HAL_DMA_GET_DESC0() 99 | #define HAL_NV_DMA_SET_ADDR(a) HAL_DMA_SET_ADDR_DESC0((a)) 100 | 101 | /* ------------------------------------------------------------------------------------------------ 102 | * Serial Boot Loader: reserving the first 4 pages of flash and other memory in cc2530-sb.xcl. 103 | * ------------------------------------------------------------------------------------------------ 104 | */ 105 | 106 | #define HAL_SB_IMG_ADDR 0x2000 107 | #define HAL_SB_CRC_ADDR 0x2090 108 | // Size of internal flash less 4 pages for boot loader, 6 pages for NV, & 1 page for lock bits. 109 | #define HAL_SB_IMG_SIZE (0x40000 - 0x2000 - 0x3000 - 0x0800) 110 | 111 | /* ------------------------------------------------------------------------------------------------ 112 | * Macros 113 | * ------------------------------------------------------------------------------------------------ 114 | */ 115 | 116 | /* ----------- RF-frontend Connection Initialization ---------- */ 117 | #if defined HAL_PA_LNA || defined HAL_PA_LNA_CC2590 118 | extern void MAC_RfFrontendSetup(void); 119 | #define HAL_BOARD_RF_FRONTEND_SETUP() MAC_RfFrontendSetup() 120 | #else 121 | #define HAL_BOARD_RF_FRONTEND_SETUP() 122 | #endif 123 | 124 | 125 | /* ------------------------------------------------------------------------------------------------ 126 | * Macros 127 | * ------------------------------------------------------------------------------------------------ 128 | */ 129 | 130 | #define CLKCONCMD_VALUE (CLKCONCMD_32MHZ | OSC_32KHZ) 131 | 132 | /* ----------- Cache Prefetch control ---------- */ 133 | #define PREFETCH_ENABLE() st( FCTL = 0x08; ) 134 | #define PREFETCH_DISABLE() st( FCTL = 0x04; ) 135 | 136 | /* ----------- Board Initialization ---------- */ 137 | #define HAL_BOARD_INIT() \ 138 | { \ 139 | uint16 i; \ 140 | \ 141 | SLEEPCMD &= ~OSC_PD; /* turn on 16MHz RC and 32MHz XOSC */ \ 142 | while (!(SLEEPSTA & XOSC_STB)); /* wait for 32MHz XOSC stable */ \ 143 | asm("NOP"); /* chip bug workaround */ \ 144 | for (i=0; i<504; i++) asm("NOP"); /* Require 63us delay for all revs */ \ 145 | CLKCONCMD = CLKCONCMD_VALUE; /* Select 32MHz XOSC and the source for 32K clock */ \ 146 | while (CLKCONSTA != CLKCONCMD_VALUE); /* Wait for the change to be effective */ \ 147 | SLEEPCMD |= OSC_PD; /* turn off 16MHz RC */ \ 148 | \ 149 | /* Turn on cache prefetch mode */ \ 150 | PREFETCH_ENABLE(); \ 151 | HAL_TURN_OFF_LED1(); \ 152 | LED1_DDR |= LED1_BV; \ 153 | LED4_DDR |= LED4_BV; \ 154 | } 155 | 156 | /* ----------- Debounce ---------- */ 157 | #define HAL_DEBOUNCE(expr) { int i; for (i=0; i<500; i++) { if (!(expr)) i = 0; } } 158 | 159 | /* ----------- Push Buttons ---------- */ 160 | #define HAL_PUSH_BUTTON1() (0) 161 | #define HAL_PUSH_BUTTON2() (0) 162 | #define HAL_PUSH_BUTTON3() (0) 163 | #define HAL_PUSH_BUTTON4() (0) 164 | #define HAL_PUSH_BUTTON5() (0) 165 | #define HAL_PUSH_BUTTON6() (0) 166 | 167 | /* ----------- LED's ---------- */ 168 | 169 | #if defined(HAL_BOARD_MOTION) 170 | #define LED1_BV BV(1) 171 | #define LED1_SBIT P0_1 172 | #define LED1_DDR P0DIR 173 | #define LED1_POLARITY ACTIVE_HIGH 174 | 175 | #elif defined(HAL_BOARD_CHDTECH_DEV) 176 | #define LED1_BV BV(0) 177 | #define LED1_SBIT P1_0 178 | #define LED1_DDR P1DIR 179 | #define LED1_POLARITY ACTIVE_LOW 180 | #endif 181 | 182 | //power pin 183 | #define LED4_BV BV(1) 184 | #define LED4_SBIT P1_1 185 | #define LED4_DDR P1DIR 186 | #define LED4_POLARITY ACTIVE_HIGH 187 | 188 | #define HAL_TURN_OFF_LED1() st( LED1_SBIT = LED1_POLARITY (0); ) 189 | #define HAL_TURN_OFF_LED2() asm("NOP") 190 | #define HAL_TURN_OFF_LED3() asm("NOP") 191 | #define HAL_TURN_OFF_LED4() st( LED4_SBIT = LED4_POLARITY (0); ) 192 | 193 | #define HAL_TURN_ON_LED1() st( LED1_SBIT = LED1_POLARITY (1); ) 194 | #define HAL_TURN_ON_LED2() asm("NOP") 195 | #define HAL_TURN_ON_LED3() asm("NOP") 196 | #define HAL_TURN_ON_LED4() st( LED4_SBIT = LED4_POLARITY (1); ) 197 | 198 | #define HAL_TOGGLE_LED1() st( if (LED1_SBIT) { LED1_SBIT = 0; } else { LED1_SBIT = 1;} ) 199 | #define HAL_TOGGLE_LED2() asm("NOP") 200 | #define HAL_TOGGLE_LED3() asm("NOP") 201 | #define HAL_TOGGLE_LED4() st( if (LED4_SBIT) { LED4_SBIT = 0; } else { LED4_SBIT = 1;} ) 202 | 203 | #define HAL_STATE_LED1() (LED1_POLARITY (LED1_SBIT)) 204 | #define HAL_STATE_LED2() 0 205 | #define HAL_STATE_LED3() 0 206 | #define HAL_STATE_LED4() (LED4_POLARITY (LED4_SBIT)) 207 | 208 | /* ----------- Minimum safe bus voltage ---------- */ 209 | 210 | // Vdd/3 / Internal Reference X ENOB --> (Vdd / 3) / 1.15 X 127 211 | #define VDD_2_0 74 // 2.0 V required to safely read/write internal flash. 212 | #define VDD_2_7 100 // 2.7 V required for the Numonyx device. 213 | 214 | #define VDD_MIN_RUN VDD_2_0 215 | #define VDD_MIN_NV (VDD_2_0+4) // 5% margin over minimum to survive a page erase and compaction. 216 | #define VDD_MIN_GOOD (VDD_2_0+8) // 10% margin over minimum to survive a page erase and compaction. 217 | #define VDD_MIN_XNV (VDD_2_7+5) // 5% margin over minimum to survive a page erase and compaction. 218 | 219 | /* ------------------------------------------------------------------------------------------------ 220 | * Driver Configuration 221 | * ------------------------------------------------------------------------------------------------ 222 | */ 223 | 224 | /* Set to TRUE enable H/W TIMER usage, FALSE disable it */ 225 | #ifndef HAL_TIMER 226 | #define HAL_TIMER FALSE 227 | #endif 228 | 229 | /* Set to TRUE enable ADC usage, FALSE disable it */ 230 | #ifndef HAL_ADC 231 | #define HAL_ADC TRUE 232 | #endif 233 | 234 | /* Set to TRUE enable DMA usage, FALSE disable it */ 235 | #ifndef HAL_DMA 236 | #define HAL_DMA TRUE 237 | #endif 238 | 239 | /* Set to TRUE enable Flash access, FALSE disable it */ 240 | #ifndef HAL_FLASH 241 | #define HAL_FLASH TRUE 242 | #endif 243 | 244 | /* Set to TRUE enable AES usage, FALSE disable it */ 245 | #ifndef HAL_AES 246 | #define HAL_AES TRUE 247 | #endif 248 | 249 | #ifndef HAL_AES_DMA 250 | #define HAL_AES_DMA FALSE 251 | #endif 252 | 253 | /* Set to TRUE enable LCD usage, FALSE disable it */ 254 | #ifndef HAL_LCD 255 | #define HAL_LCD FALSE 256 | #endif 257 | 258 | /* Set to TRUE enable LED usage, FALSE disable it */ 259 | #ifndef HAL_LED 260 | #define HAL_LED FALSE 261 | #endif 262 | #if (!defined BLINK_LEDS) && (HAL_LED == TRUE) 263 | #define BLINK_LEDS 264 | #endif 265 | 266 | #ifndef HAL_MOTION 267 | #define HAL_MOTION FASLE 268 | #endif 269 | 270 | /* Set to TRUE enable KEY usage, FALSE disable it */ 271 | #ifndef HAL_KEY 272 | #define HAL_KEY TRUE 273 | #endif 274 | 275 | /* Set to TRUE enable UART usage, FALSE disable it */ 276 | #ifndef HAL_UART 277 | #define HAL_UART FALSE 278 | #endif 279 | 280 | #if HAL_UART 281 | #ifndef HAL_UART_DMA 282 | #if HAL_DMA 283 | #if (defined ZAPP_P2) || (defined ZTOOL_P2) 284 | #define HAL_UART_DMA 2 285 | #else 286 | #define HAL_UART_DMA 1 287 | #endif 288 | #else 289 | #define HAL_UART_DMA 0 290 | #endif 291 | #endif 292 | 293 | #ifndef HAL_UART_ISR 294 | #if HAL_UART_DMA // Default preference for DMA over ISR. 295 | #define HAL_UART_ISR 0 296 | #elif (defined ZAPP_P2) || (defined ZTOOL_P2) 297 | #define HAL_UART_ISR 2 298 | #else 299 | #define HAL_UART_ISR 1 300 | #endif 301 | #endif 302 | 303 | #if (HAL_UART_DMA && (HAL_UART_DMA == HAL_UART_ISR)) 304 | #error HAL_UART_DMA & HAL_UART_ISR must be different. 305 | #endif 306 | 307 | // Used to set P2 priority - USART0 over USART1 if both are defined. 308 | #if ((HAL_UART_DMA == 1) || (HAL_UART_ISR == 1)) 309 | #define HAL_UART_PRIPO 0x00 310 | #else 311 | #define HAL_UART_PRIPO 0x40 312 | #endif 313 | 314 | #else 315 | #define HAL_UART_DMA 0 316 | #define HAL_UART_ISR 0 317 | #endif 318 | 319 | /* USB is not used for CC2530 configuration */ 320 | #define HAL_UART_USB 0 321 | 322 | #ifndef HAL_BUZZER 323 | #define HAL_BUZZER TRUE 324 | #endif 325 | 326 | /******************************************************************************************************* 327 | */ 328 | #endif 329 | -------------------------------------------------------------------------------- /Source/preinclude.h: -------------------------------------------------------------------------------- 1 | #define TC_LINKKEY_JOIN 2 | #define NV_INIT 3 | #define NV_RESTORE 4 | 5 | 6 | #define TP2_LEGACY_ZC 7 | //patch sdk 8 | // #define ZDSECMGR_TC_ATTEMPT_DEFAULT_KEY TRUE 9 | 10 | #define NWK_AUTO_POLL 11 | #define MULTICAST_ENABLED FALSE 12 | 13 | #define ZCL_READ 14 | #define ZCL_WRITE 15 | #define ZCL_BASIC 16 | #define ZCL_IDENTIFY 17 | #define ZCL_ON_OFF 18 | #define ZCL_LEVEL_CTRL 19 | #define ZCL_REPORTING_DEVICE 20 | 21 | //#define ZSTACK_DEVICE_BUILD (DEVICE_BUILD_ENDDEVICE) 22 | //#define ZSTACK_DEVICE_BUILD (DEVICE_BUILD_ROUTER) 23 | 24 | #define DISABLE_GREENPOWER_BASIC_PROXY 25 | #define BDB_FINDING_BINDING_CAPABILITY_ENABLED 1 26 | #define BDB_REPORTING TRUE 27 | 28 | 29 | #define ISR_KEYINTERRUPT 30 | #define HAL_BUZZER FALSE 31 | 32 | #define HAL_LED TRUE 33 | #define HAL_I2C TRUE 34 | #define BLINK_LEDS TRUE 35 | 36 | #define LQI_REQ 37 | #if defined(LQI_REQ) 38 | #define MT_TASK 39 | #define MT_SYS_FUNC 40 | #define MT_ZDO_FUNC 41 | #define MT_ZDO_MGMT 42 | #define INT_HEAP_LEN (2688) 43 | #endif 44 | 45 | //one of this boards 46 | // #define HAL_BOARD_MOTION 47 | // #define HAL_BOARD_CHDTECH_DEV 48 | 49 | #if !defined(HAL_BOARD_MOTION) && !defined(HAL_BOARD_CHDTECH_DEV) 50 | #error "Board type must be defined" 51 | #endif 52 | 53 | #define BDB_MAX_CLUSTERENDPOINTS_REPORTING 10 54 | 55 | #define LUMOISITY_PORT 0 56 | #define LUMOISITY_PIN 7 57 | 58 | //#define SMART 59 | 60 | #if defined(HAL_BOARD_MOTION) 61 | #define POWER_SAVING 62 | //#define DO_DEBUG_UART 63 | 64 | #elif defined(HAL_BOARD_CHDTECH_DEV) 65 | // #define DO_DEBUG_UART 66 | #define DO_DEBUG_MT 67 | 68 | #endif 69 | 70 | 71 | //i2c bh1750 72 | #define OCM_CLK_PORT 0 73 | #define OCM_DATA_PORT 0 74 | #define OCM_CLK_PIN 5 75 | #define OCM_DATA_PIN 6 76 | 77 | #define HAL_I2C_RETRY_CNT 1 78 | 79 | 80 | #ifdef DO_DEBUG_UART 81 | #define HAL_UART TRUE 82 | #define HAL_UART_DMA 1 83 | #define INT_HEAP_LEN (2685 - 0x4B - 0xBB) 84 | #endif 85 | 86 | #ifdef DO_DEBUG_MT 87 | #define HAL_UART TRUE 88 | #define HAL_UART_DMA 1 89 | #define HAL_UART_ISR 2 90 | #define INT_HEAP_LEN (2688-0xC4-0x15-0x44-0x20-0x1E) 91 | 92 | #define MT_TASK 93 | 94 | #define MT_UTIL_FUNC 95 | #define MT_UART_DEFAULT_BAUDRATE HAL_UART_BR_115200 96 | #define MT_UART_DEFAULT_OVERFLOW FALSE 97 | 98 | #define ZTOOL_P1 99 | 100 | #define MT_APP_FUNC 101 | #define MT_APP_CNF_FUNC 102 | #define MT_SYS_FUNC 103 | #define MT_ZDO_FUNC 104 | #define MT_ZDO_MGMT 105 | #define MT_DEBUG_FUNC 106 | 107 | #endif 108 | 109 | 110 | 111 | #if defined(HAL_BOARD_MOTION) 112 | #define FACTORY_RESET_BY_LONG_PRESS_PORT 0x04 //port2 113 | 114 | //#define HAL_KEY_P0_INPUT_PINS BV(4) 115 | #define HAL_KEY_P0_INPUT_PINS BV(0) 116 | #define HAL_KEY_P0_INPUT_PINS_EDGE HAL_KEY_RISING_EDGE 117 | 118 | 119 | #define HAL_KEY_P1_INPUT_PINS BV(3) 120 | #define HAL_KEY_P1_INPUT_PINS_EDGE HAL_KEY_RISING_EDGE 121 | 122 | #define HAL_KEY_P2_INPUT_PINS BV(0) 123 | 124 | #elif defined(HAL_BOARD_CHDTECH_DEV) 125 | #define HAL_KEY_P0_INPUT_PINS BV(1) 126 | #define HAL_KEY_P2_INPUT_PINS BV(0) 127 | #endif 128 | 129 | #include "hal_board_cfg.h" 130 | 131 | #include "stdint.h" 132 | #include "stddef.h" 133 | -------------------------------------------------------------------------------- /Source/stdint.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _STDINT 3 | #define _STDINT 4 | 5 | #ifndef int8_t 6 | #define int8_t int8 7 | #endif 8 | #ifndef int16_t 9 | #define int16_t int16 10 | #endif 11 | #ifndef int32_t 12 | #define int32_t int32 13 | #endif 14 | #ifndef int64_t 15 | #define int64_t int64 16 | #endif 17 | #ifndef uint8_t 18 | #define uint8_t uint8 19 | #endif 20 | #ifndef uint16_t 21 | #define uint16_t uint16 22 | #endif 23 | #ifndef uint32_t 24 | #define uint32_t uint32 25 | #endif 26 | 27 | 28 | #define S8_C(x) x 29 | #define U8_C(x) x 30 | #define S16_C(x) x 31 | #define U16_C(x) x 32 | #define S32_C(x) x 33 | #define U32_C(x) x 34 | #define S64_C(x) x 35 | #define U64_C(x) x 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /Source/version.c: -------------------------------------------------------------------------------- 1 | 2 | #ifndef ZCL_APP_VERSION_H 3 | #define ZCL_APP_VERSION_H 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #include "version.h" 10 | const uint8 zclApp_DateCode[] = { 16, '2', '2', '/', '1', '0', '/', '2', '0', '2', '4', ' ', '2', '2', ':', '0', '5' }; 11 | const char zclApp_DateCodeNT[] = "22/10/2024 22:05"; 12 | 13 | #ifdef __cplusplus 14 | } 15 | #endif 16 | 17 | #endif /* ZCL_APP_VERSION_H */ 18 | -------------------------------------------------------------------------------- /Source/version.h: -------------------------------------------------------------------------------- 1 | extern const uint8 zclApp_DateCode[]; 2 | extern const char zclApp_DateCodeNT[]; -------------------------------------------------------------------------------- /Source/zcl_app.h: -------------------------------------------------------------------------------- 1 | #ifndef ZCL_APP_H 2 | #define ZCL_APP_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | /********************************************************************* 9 | * INCLUDES 10 | */ 11 | #include "version.h" 12 | #include "zcl.h" 13 | 14 | 15 | /********************************************************************* 16 | * CONSTANTS 17 | */ 18 | 19 | // Application Events 20 | #define APP_REPORT_EVT 0x0001 21 | #define APP_READ_SENSORS_EVT 0x0002 22 | #define APP_REPORT_LDR_EVT 0x0004 23 | #define APP_MOTION_ON_EVT 0x0008 24 | #define APP_MOTION_OFF_EVT 0x0020 25 | #define APP_MOTION_DELAY_EVT 0x0040 26 | #define APP_SAVE_ATTRS_EVT 0x0080 27 | #define APP_CONTACT_DELAY_EVT 0x0100 28 | #define APP_BH1750_DELAY_EVT 0x0200 29 | #define APP_REPORT_TEMPERATURE_EVT 0x0400 30 | #define APP_REPORT_PRESSURE_EVT 0x0800 31 | #define APP_REPORT_HUMIDITY_EVT 0x1000 32 | #define APP_REPORT_ILLUMINANCE_EVT 0x2000 33 | #define APP_REPORT_BATTERY_EVT 0x4000 34 | 35 | 36 | //#define AIR_COMPENSATION_FORMULA(ADC) ((0.179 * (double)ADC + 3926.0)) 37 | //#define WATER_COMPENSATION_FORMULA(ADC) ((0.146 * (double)ADC + 2020.0)) 38 | 39 | 40 | 41 | #define APP_REPORT_DELAY ((uint32) 1800000) //30 minutes 42 | //#define APP_REPORT_DELAY ((uint32) 60000) // 60 sec 43 | 44 | /********************************************************************* 45 | * MACROS 46 | */ 47 | #define NW_APP_CONFIG 0x0401 48 | 49 | #define R ACCESS_CONTROL_READ 50 | #define RR (R | ACCESS_REPORTABLE) 51 | #define RW (ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE | ACCESS_CONTROL_AUTH_WRITE) 52 | #define RRW (ACCESS_CONTROL_READ| ACCESS_REPORTABLE | ACCESS_CONTROL_WRITE | ACCESS_CONTROL_AUTH_WRITE) 53 | 54 | #define BASIC ZCL_CLUSTER_ID_GEN_BASIC 55 | #define ONOFF ZCL_CLUSTER_ID_GEN_ON_OFF 56 | #define POWER_CFG ZCL_CLUSTER_ID_GEN_POWER_CFG 57 | #define BINARY_INPUT ZCL_CLUSTER_ID_GEN_BINARY_INPUT_BASIC 58 | #define TEMP ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT 59 | #define HUMIDITY ZCL_CLUSTER_ID_MS_RELATIVE_HUMIDITY 60 | //#define SOIL_HUMIDITY 0x0408 61 | #define PRESSURE ZCL_CLUSTER_ID_MS_PRESSURE_MEASUREMENT 62 | #define ILLUMINANCE ZCL_CLUSTER_ID_MS_ILLUMINANCE_MEASUREMENT 63 | //#define ILLUMINANCE_CONFIG ZCL_CLUSTER_ID_MS_ILLUMINANCE_LEVEL_SENSING_CONFIG 64 | #define OCCUPANCY ZCL_CLUSTER_ID_MS_OCCUPANCY_SENSING 65 | 66 | #define ZCL_BOOLEAN ZCL_DATATYPE_BOOLEAN 67 | #define ZCL_UINT8 ZCL_DATATYPE_UINT8 68 | #define ZCL_UINT16 ZCL_DATATYPE_UINT16 69 | #define ZCL_UINT32 ZCL_DATATYPE_UINT32 70 | #define ZCL_INT16 ZCL_DATATYPE_INT16 71 | #define ZCL_INT8 ZCL_DATATYPE_INT8 72 | #define ZCL_BITMAP8 ZCL_DATATYPE_BITMAP8 73 | #define ZCL_ENUM8 ZCL_DATATYPE_ENUM8 74 | #define ZCL_UNKNOWN ZCL_DATATYPE_UNKNOWN 75 | 76 | #define ATTRID_TEMPERATURE_MIN_ABSOLUTE_CHANGE 0xF001 77 | #define ATTRID_TEMPERATURE_PERIOD 0xF002 78 | #define ATTRID_PRESSURE_MIN_ABSOLUTE_CHANGE 0xF001 79 | #define ATTRID_PRESSURE_PERIOD 0xF002 80 | #define ATTRID_HUMIDITY_MIN_ABSOLUTE_CHANGE 0xF001 81 | #define ATTRID_HUMIDITY_PERIOD 0xF002 82 | #define ATTRID_ILLUMINANCE_LEVEL_SENSING_SENSITIVITY 0xF000 83 | #define ATTRID_ILLUMINANCE_MIN_ABSOLUTE_CHANGE 0xF001 84 | #define ATTRID_ILLUMINANCE_PERIOD 0xF002 85 | #define ATTRID_POWER_CFG_BATTERY_PERIOD 0xF003 86 | 87 | #define ATTRID_GEN_BINARY_INPUT_PRESENTVALUE 0x55 88 | 89 | //#define ATTRID_MS_RELATIVE_HUMIDITY_MEASURED_VALUE_RAW_ADC 0x0200 90 | //#define ATTRID_MS_RELATIVE_HUMIDITY_MEASURED_VALUE_BATTERY_RAW_ADC 0x0201 91 | 92 | 93 | 94 | /********************************************************************* 95 | * TYPEDEFS 96 | */ 97 | 98 | /********************************************************************* 99 | * VARIABLES 100 | */ 101 | 102 | extern SimpleDescriptionFormat_t zclApp_FirstEP; 103 | extern SimpleDescriptionFormat_t zclApp_SecondEP; 104 | extern SimpleDescriptionFormat_t zclApp_ThirdEP; 105 | extern SimpleDescriptionFormat_t zclApp_FourthEP; 106 | 107 | extern uint8 zclApp_BatteryVoltage; 108 | extern uint8 zclApp_BatteryPercentageRemainig; 109 | //extern uint16 zclApp_BatteryVoltageRawAdc; 110 | extern int16 zclApp_Temperature_Sensor_MeasuredValue; 111 | extern int16 zclApp_PressureSensor_MeasuredValue; 112 | extern int16 zclApp_PressureSensor_ScaledValue; 113 | extern int8 zclApp_PressureSensor_Scale; 114 | extern uint16 zclApp_HumiditySensor_MeasuredValue; 115 | //extern int16 zclApp_DS18B20_MeasuredValue; 116 | //extern uint16 zclApp_SoilHumiditySensor_MeasuredValue; 117 | //extern uint16 zclApp_SoilHumiditySensor_MeasuredValueRawAdc; 118 | extern uint16 zclApp_IlluminanceSensor_MeasuredValue; 119 | //extern uint16 zclApp_IlluminanceSensor_MeasuredValueRawAdc; 120 | extern uint16 zclApp_bh1750IlluminanceSensor_MeasuredValue; 121 | 122 | extern uint8 zclApp_Magnet_OnOff; 123 | extern uint8 zclApp_Magnet; 124 | extern uint8 zclApp_Occupied_OnOff; 125 | // Occupancy Cluster 126 | extern uint8 zclApp_Occupied; 127 | //extern uint8 zclApp_OccType; 128 | 129 | typedef struct 130 | { 131 | uint16 PirOccupiedToUnoccupiedDelay; 132 | uint16 PirUnoccupiedToOccupiedDelay; 133 | uint16 MsIlluminanceLevelSensingSensitivity; 134 | uint16 MsTemperatureMinAbsoluteChange; 135 | uint16 MsPressureMinAbsoluteChange; 136 | uint16 MsHumidityMinAbsoluteChange; 137 | uint16 MsIlluminanceMinAbsoluteChange; 138 | uint16 MsTemperaturePeriod; 139 | uint16 MsPressurePeriod; 140 | uint16 MsHumidityPeriod; 141 | uint16 MsIlluminancePeriod; 142 | uint16 CfgBatteryPeriod; 143 | } application_config_t; 144 | 145 | extern application_config_t zclApp_Config; 146 | 147 | // attribute list 148 | extern CONST zclAttrRec_t zclApp_AttrsFirstEP[]; 149 | extern CONST zclAttrRec_t zclApp_AttrsSecondEP[]; 150 | extern CONST zclAttrRec_t zclApp_AttrsThirdEP[]; 151 | extern CONST zclAttrRec_t zclApp_AttrsFourthEP[]; 152 | 153 | extern CONST uint8 zclApp_AttrsSecondEPCount; 154 | extern CONST uint8 zclApp_AttrsFirstEPCount; 155 | extern CONST uint8 zclApp_AttrsThirdEPCount; 156 | extern CONST uint8 zclApp_AttrsFourthEPCount; 157 | 158 | extern const uint8 zclApp_ManufacturerName[]; 159 | extern const uint8 zclApp_ModelId[]; 160 | extern const uint8 zclApp_PowerSource; 161 | 162 | // APP_TODO: Declare application specific attributes here 163 | 164 | /********************************************************************* 165 | * FUNCTIONS 166 | */ 167 | 168 | /* 169 | * Initialization for the task 170 | */ 171 | extern void zclApp_Init(byte task_id); 172 | 173 | /* 174 | * Event Process for the task 175 | */ 176 | extern UINT16 zclApp_event_loop(byte task_id, UINT16 events); 177 | 178 | //void user_delay_ms(uint32_t period); 179 | 180 | extern void zclApp_ResetAttributesToDefaultValues(void); 181 | 182 | #ifdef __cplusplus 183 | } 184 | #endif 185 | 186 | #endif /* ZCL_APP_H */ 187 | -------------------------------------------------------------------------------- /Source/zcl_app_data.c: -------------------------------------------------------------------------------- 1 | #include "AF.h" 2 | #include "OSAL.h" 3 | #include "ZComDef.h" 4 | #include "ZDConfig.h" 5 | 6 | #include "zcl.h" 7 | #include "zcl_general.h" 8 | #include "zcl_ms.h" 9 | #include "zcl_ha.h" 10 | 11 | #include "zcl_app.h" 12 | 13 | #include "battery.h" 14 | #include "version.h" 15 | /********************************************************************* 16 | * CONSTANTS 17 | */ 18 | 19 | #define APP_DEVICE_VERSION 2 20 | #define APP_FLAGS 0 21 | 22 | #define APP_HWVERSION 1 23 | #define APP_ZCLVERSION 1 24 | 25 | /********************************************************************* 26 | * TYPEDEFS 27 | */ 28 | 29 | /********************************************************************* 30 | * MACROS 31 | */ 32 | 33 | /********************************************************************* 34 | * GLOBAL VARIABLES 35 | */ 36 | 37 | // Global attributes 38 | const uint16 zclApp_clusterRevision_all = 0x0001; 39 | 40 | int16 zclApp_Temperature_Sensor_MeasuredValue = 0; 41 | int16 zclApp_PressureSensor_MeasuredValue = 0; 42 | int16 zclApp_PressureSensor_ScaledValue = 0; 43 | int8 zclApp_PressureSensor_Scale = -1; 44 | 45 | uint16 zclApp_HumiditySensor_MeasuredValue = 0; 46 | 47 | //uint16 zclApp_SoilHumiditySensor_MeasuredValue = 0; 48 | //uint16 zclApp_SoilHumiditySensor_MeasuredValueRawAdc = 0; 49 | 50 | int16 zclApp_DS18B20_MeasuredValue = 0; 51 | 52 | uint16 zclApp_IlluminanceSensor_MeasuredValue = 0; 53 | //uint16 zclApp_IlluminanceSensor_MeasuredValueRawAdc = 0; 54 | uint16 zclApp_bh1750IlluminanceSensor_MeasuredValue = 0; 55 | 56 | uint8 zclApp_Magnet_OnOff = 0; 57 | uint8 zclApp_Magnet = 0; 58 | uint8 zclApp_Occupied_OnOff = 0; 59 | 60 | // Occupancy Cluster 61 | uint8 zclApp_Occupied = 0; 62 | /* Set default to Not be occupied */ 63 | //uint8 zclApp_OccType = MS_OCCUPANCY_SENSOR_TYPE_PIR; 64 | 65 | #define DEFAULT_PirOccupiedToUnoccupiedDelay 60 66 | #define DEFAULT_PirUnoccupiedToOccupiedDelay 60 67 | #define DEFAULT_MsIlluminanceLevelSensingSensitivity 69 68 | #define DEFAULT_MsTemperatureMinAbsoluteChange 50 69 | #define DEFAULT_MsPressureMinAbsoluteChange 1 70 | #define DEFAULT_MsHumidityMinAbsoluteChange 1000 71 | #define DEFAULT_MsIlluminanceMinAbsoluteChange 10 72 | #define DEFAULT_MsTemperaturePeriod 10 73 | #define DEFAULT_MsPressurePeriod 10 74 | #define DEFAULT_MsHumidityPeriod 10 75 | #define DEFAULT_MsIlluminancePeriod 10 76 | #define DEFAULT_CfgBatteryPeriod 30 // min 77 | application_config_t zclApp_Config = {.PirOccupiedToUnoccupiedDelay = DEFAULT_PirOccupiedToUnoccupiedDelay, 78 | .PirUnoccupiedToOccupiedDelay = DEFAULT_PirUnoccupiedToOccupiedDelay, 79 | .MsIlluminanceLevelSensingSensitivity = DEFAULT_MsIlluminanceLevelSensingSensitivity, 80 | .MsTemperatureMinAbsoluteChange = DEFAULT_MsTemperatureMinAbsoluteChange, 81 | .MsPressureMinAbsoluteChange = DEFAULT_MsPressureMinAbsoluteChange, 82 | .MsHumidityMinAbsoluteChange = DEFAULT_MsHumidityMinAbsoluteChange, 83 | .MsIlluminanceMinAbsoluteChange = DEFAULT_MsIlluminanceMinAbsoluteChange, 84 | .MsTemperaturePeriod = DEFAULT_MsTemperaturePeriod, 85 | .MsPressurePeriod = DEFAULT_MsPressurePeriod, 86 | .MsHumidityPeriod = DEFAULT_MsHumidityPeriod, 87 | .MsIlluminancePeriod = DEFAULT_MsIlluminancePeriod, 88 | .CfgBatteryPeriod = DEFAULT_CfgBatteryPeriod 89 | }; 90 | 91 | // Basic Cluster 92 | const uint8 zclApp_HWRevision = APP_HWVERSION; 93 | const uint8 zclApp_ZCLVersion = APP_ZCLVERSION; 94 | const uint8 zclApp_ApplicationVersion = 3; 95 | const uint8 zclApp_StackVersion = 4; 96 | 97 | //{lenght, 'd', 'a', 't', 'a'} 98 | const uint8 zclApp_ManufacturerName[] = {9, 'm', 'o', 'd', 'k', 'a', 'm', '.', 'r', 'u'}; 99 | const uint8 zclApp_ModelId[] = {13, 'D', 'I', 'Y', 'R', 'u', 'Z', '_', 'M', 'o', 't', 'i', 'o', 'n'}; 100 | const uint8 zclApp_PowerSource = POWER_SOURCE_BATTERY; 101 | 102 | /********************************************************************* 103 | * ATTRIBUTE DEFINITIONS - Uses REAL cluster IDs 104 | */ 105 | 106 | 107 | // msTemperatureMeasurement int16 108 | // msRelativeHumidity: uint16 109 | // msPressureMeasurement int16 110 | // msIlluminanceMeasurement uint16 111 | 112 | // #define ZCL_CLUSTER_ID_GEN_BASIC 0x0000 113 | // #define ZCL_CLUSTER_ID_GEN_POWER_CFG 0x0001 114 | // #define ZCL_CLUSTER_ID_MS_ILLUMINANCE_MEASUREMENT 0x0400 115 | // #define ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT 0x0402 116 | // #define ZCL_CLUSTER_ID_MS_PRESSURE_MEASUREMENT 0x0403 117 | // #define ZCL_CLUSTER_ID_MS_RELATIVE_HUMIDITY 0x0405 118 | // #define ZCL_CLUSTER_ID_MS_OCCUPANCY_SENSING 0x0406 119 | 120 | CONST zclAttrRec_t zclApp_AttrsFirstEP[] = { 121 | {BASIC, {ATTRID_BASIC_ZCL_VERSION, ZCL_UINT8, R, (void *)&zclApp_ZCLVersion}}, 122 | {BASIC, {ATTRID_BASIC_APPL_VERSION, ZCL_UINT8, R, (void *)&zclApp_ApplicationVersion}}, 123 | {BASIC, {ATTRID_BASIC_STACK_VERSION, ZCL_UINT8, R, (void *)&zclApp_StackVersion}}, 124 | {BASIC, {ATTRID_BASIC_HW_VERSION, ZCL_UINT8, R, (void *)&zclApp_HWRevision}}, 125 | {BASIC, {ATTRID_BASIC_MANUFACTURER_NAME, ZCL_DATATYPE_CHAR_STR, R, (void *)zclApp_ManufacturerName}}, 126 | {BASIC, {ATTRID_BASIC_MODEL_ID, ZCL_DATATYPE_CHAR_STR, R, (void *)zclApp_ModelId}}, 127 | {BASIC, {ATTRID_BASIC_DATE_CODE, ZCL_DATATYPE_CHAR_STR, R, (void *)zclApp_DateCode}}, 128 | {BASIC, {ATTRID_BASIC_POWER_SOURCE, ZCL_DATATYPE_ENUM8, R, (void *)&zclApp_PowerSource}}, 129 | {BASIC, {ATTRID_BASIC_SW_BUILD_ID, ZCL_DATATYPE_CHAR_STR, R, (void *)zclApp_DateCode}}, 130 | {BASIC, {ATTRID_CLUSTER_REVISION, ZCL_DATATYPE_UINT16, R, (void *)&zclApp_clusterRevision_all}}, 131 | 132 | {POWER_CFG, {ATTRID_POWER_CFG_BATTERY_VOLTAGE, ZCL_UINT8, RR, (void *)&zclBattery_Voltage}}, 133 | /** 134 | * FYI: calculating battery percentage can be tricky, since this device can be powered from 2xAA or 1xCR2032 batteries 135 | * */ 136 | {POWER_CFG, {ATTRID_POWER_CFG_BATTERY_PERCENTAGE_REMAINING, ZCL_UINT8, RR, (void *)&zclBattery_PercentageRemainig}}, 137 | {POWER_CFG, {ATTRID_POWER_CFG_BATTERY_PERIOD, ZCL_UINT16, RRW, (void *)&zclApp_Config.CfgBatteryPeriod}}, 138 | 139 | {ILLUMINANCE, {ATTRID_MS_ILLUMINANCE_MEASURED_VALUE, ZCL_UINT16, RR, (void *)&zclApp_IlluminanceSensor_MeasuredValue}}, 140 | 141 | {TEMP, {ATTRID_MS_TEMPERATURE_MEASURED_VALUE, ZCL_INT16, RR, (void *)&zclApp_Temperature_Sensor_MeasuredValue}}, 142 | {TEMP, {ATTRID_TEMPERATURE_MIN_ABSOLUTE_CHANGE, ZCL_UINT16, RRW, (void *)&zclApp_Config.MsTemperatureMinAbsoluteChange}}, 143 | {TEMP, {ATTRID_TEMPERATURE_PERIOD, ZCL_UINT16, RRW, (void *)&zclApp_Config.MsTemperaturePeriod}}, 144 | 145 | {PRESSURE, {ATTRID_MS_PRESSURE_MEASUREMENT_MEASURED_VALUE, ZCL_INT16, RR, (void *)&zclApp_PressureSensor_MeasuredValue}}, 146 | {PRESSURE, {ATTRID_MS_PRESSURE_MEASUREMENT_SCALED_VALUE, ZCL_INT16, RR, (void *)&zclApp_PressureSensor_ScaledValue}}, 147 | {PRESSURE, {ATTRID_MS_PRESSURE_MEASUREMENT_SCALE, ZCL_INT8, RR, (void *)&zclApp_PressureSensor_Scale}}, 148 | {PRESSURE, {ATTRID_PRESSURE_MIN_ABSOLUTE_CHANGE, ZCL_UINT16, RRW, (void *)&zclApp_Config.MsPressureMinAbsoluteChange}}, 149 | {PRESSURE, {ATTRID_PRESSURE_PERIOD, ZCL_UINT16, RRW, (void *)&zclApp_Config.MsPressurePeriod}}, 150 | 151 | {HUMIDITY, {ATTRID_MS_RELATIVE_HUMIDITY_MEASURED_VALUE, ZCL_UINT16, RR, (void *)&zclApp_HumiditySensor_MeasuredValue}}, 152 | {HUMIDITY, {ATTRID_HUMIDITY_MIN_ABSOLUTE_CHANGE, ZCL_UINT16, RRW, (void *)&zclApp_Config.MsHumidityMinAbsoluteChange}}, 153 | {HUMIDITY, {ATTRID_HUMIDITY_PERIOD, ZCL_UINT16, RRW, (void *)&zclApp_Config.MsHumidityPeriod}} 154 | }; 155 | 156 | 157 | CONST zclAttrRec_t zclApp_AttrsSecondEP[] = { 158 | // {ONOFF, {ATTRID_ON_OFF, ZCL_BOOLEAN, R, (void *)&zclApp_Magnet_OnOff}}, 159 | {BINARY_INPUT, {ATTRID_GEN_BINARY_INPUT_PRESENTVALUE, ZCL_BOOLEAN, RR, (void *)&zclApp_Magnet}} 160 | }; 161 | 162 | CONST zclAttrRec_t zclApp_AttrsThirdEP[] = { 163 | // {ONOFF, {ATTRID_ON_OFF, ZCL_BOOLEAN, R, (void *)&zclApp_Occupied_OnOff}}, 164 | {OCCUPANCY, {ATTRID_MS_OCCUPANCY_SENSING_CONFIG_OCCUPANCY, ZCL_BITMAP8, RR, (void *)&zclApp_Occupied}}, 165 | {OCCUPANCY, {ATTRID_MS_OCCUPANCY_SENSING_CONFIG_PIR_O_TO_U_DELAY, ZCL_UINT16, RRW, (void *)&zclApp_Config.PirOccupiedToUnoccupiedDelay}}, 166 | {OCCUPANCY, {ATTRID_MS_OCCUPANCY_SENSING_CONFIG_PIR_U_TO_O_DELAY, ZCL_UINT16, RRW, (void *)&zclApp_Config.PirUnoccupiedToOccupiedDelay}} 167 | }; 168 | 169 | CONST zclAttrRec_t zclApp_AttrsFourthEP[] = { 170 | {ILLUMINANCE, {ATTRID_MS_ILLUMINANCE_MEASURED_VALUE, ZCL_UINT16, RR, (void *)&zclApp_bh1750IlluminanceSensor_MeasuredValue}}, 171 | {ILLUMINANCE, {ATTRID_ILLUMINANCE_MIN_ABSOLUTE_CHANGE, ZCL_UINT16, RRW, (void *)&zclApp_Config.MsIlluminanceMinAbsoluteChange}}, 172 | {ILLUMINANCE, {ATTRID_ILLUMINANCE_LEVEL_SENSING_SENSITIVITY, ZCL_UINT16, RRW, (void *)&zclApp_Config.MsIlluminanceLevelSensingSensitivity}}, 173 | {ILLUMINANCE, {ATTRID_ILLUMINANCE_PERIOD, ZCL_UINT16, RRW, (void *)&zclApp_Config.MsIlluminancePeriod}} 174 | }; 175 | 176 | uint8 CONST zclApp_AttrsSecondEPCount = (sizeof(zclApp_AttrsSecondEP) / sizeof(zclApp_AttrsSecondEP[0])); 177 | uint8 CONST zclApp_AttrsFirstEPCount = (sizeof(zclApp_AttrsFirstEP) / sizeof(zclApp_AttrsFirstEP[0])); 178 | uint8 CONST zclApp_AttrsThirdEPCount = (sizeof(zclApp_AttrsThirdEP) / sizeof(zclApp_AttrsThirdEP[0])); 179 | uint8 CONST zclApp_AttrsFourthEPCount = (sizeof(zclApp_AttrsFourthEP) / sizeof(zclApp_AttrsFourthEP[0])); 180 | 181 | const cId_t zclApp_InClusterList[] = {ZCL_CLUSTER_ID_GEN_BASIC}; 182 | 183 | #define APP_MAX_INCLUSTERS (sizeof(zclApp_InClusterList) / sizeof(zclApp_InClusterList[0])) 184 | 185 | const cId_t zclApp_OutClusterListFirstEP[] = {POWER_CFG, ILLUMINANCE, TEMP, PRESSURE, HUMIDITY}; 186 | const cId_t zclApp_OutClusterListSecondEP[] = {ONOFF, BINARY_INPUT}; 187 | const cId_t zclApp_OutClusterListThirdEP[] = {ONOFF, ZCL_CLUSTER_ID_MS_OCCUPANCY_SENSING}; 188 | const cId_t zclApp_OutClusterListFourthEP[] = {ILLUMINANCE}; 189 | 190 | #define APP_MAX_OUTCLUSTERS_FIRST_EP (sizeof(zclApp_OutClusterListFirstEP) / sizeof(zclApp_OutClusterListFirstEP[0])) 191 | #define APP_MAX_OUTCLUSTERS_SECOND_EP (sizeof(zclApp_OutClusterListSecondEP) / sizeof(zclApp_OutClusterListSecondEP[0])) 192 | #define APP_MAX_OUTCLUSTERS_THIRD_EP (sizeof(zclApp_OutClusterListThirdEP) / sizeof(zclApp_OutClusterListThirdEP[0])) 193 | #define APP_MAX_OUTCLUSTERS_FOURTH_EP (sizeof(zclApp_OutClusterListFourthEP) / sizeof(zclApp_OutClusterListFourthEP[0])) 194 | 195 | 196 | 197 | SimpleDescriptionFormat_t zclApp_FirstEP = { 198 | 1, // int Endpoint; 199 | ZCL_HA_PROFILE_ID, // uint16 AppProfId[2]; 200 | ZCL_HA_DEVICEID_SIMPLE_SENSOR, // uint16 AppDeviceId[2]; 201 | APP_DEVICE_VERSION, // int AppDevVer:4; 202 | APP_FLAGS, // int AppFlags:4; 203 | APP_MAX_INCLUSTERS, // byte AppNumInClusters; 204 | (cId_t *)zclApp_InClusterList, // byte *pAppInClusterList; 205 | APP_MAX_OUTCLUSTERS_FIRST_EP, // byte AppNumInClusters; 206 | (cId_t *)zclApp_OutClusterListFirstEP // byte *pAppInClusterList; 207 | }; 208 | 209 | 210 | SimpleDescriptionFormat_t zclApp_SecondEP = { 211 | 2, // int Endpoint; 212 | ZCL_HA_PROFILE_ID, // uint16 AppProfId[2]; 213 | ZCL_HA_DEVICEID_SIMPLE_SENSOR, // uint16 AppDeviceId[2]; 214 | APP_DEVICE_VERSION, // int AppDevVer:4; 215 | APP_FLAGS, // int AppFlags:4; 216 | 0, // byte AppNumInClusters; 217 | (cId_t *)NULL, // byte *pAppInClusterList; 218 | APP_MAX_OUTCLUSTERS_SECOND_EP, // byte AppNumInClusters; 219 | (cId_t *)zclApp_OutClusterListSecondEP // byte *pAppInClusterList; 220 | }; 221 | 222 | SimpleDescriptionFormat_t zclApp_ThirdEP = { 223 | 3, // int Endpoint; 224 | ZCL_HA_PROFILE_ID, // uint16 AppProfId[2]; 225 | ZCL_HA_DEVICEID_OCCUPANCY_SENSOR, // uint16 AppDeviceId[2]; 226 | APP_DEVICE_VERSION, // int AppDevVer:4; 227 | APP_FLAGS, // int AppFlags:4; 228 | 0, // byte AppNumInClusters; 229 | (cId_t *)NULL, // byte *pAppInClusterList; 230 | APP_MAX_OUTCLUSTERS_THIRD_EP, // byte AppNumInClusters; 231 | (cId_t *)zclApp_OutClusterListThirdEP // byte *pAppInClusterList; 232 | }; 233 | 234 | SimpleDescriptionFormat_t zclApp_FourthEP = { 235 | 4, // int Endpoint; 236 | ZCL_HA_PROFILE_ID, // uint16 AppProfId[2]; 237 | ZCL_HA_DEVICEID_SIMPLE_SENSOR, // uint16 AppDeviceId[2]; 238 | APP_DEVICE_VERSION, // int AppDevVer:4; 239 | APP_FLAGS, // int AppFlags:4; 240 | 0, // byte AppNumInClusters; 241 | (cId_t *)NULL, // byte *pAppInClusterList; 242 | APP_MAX_OUTCLUSTERS_FOURTH_EP, // byte AppNumInClusters; 243 | (cId_t *)zclApp_OutClusterListFourthEP // byte *pAppInClusterList; 244 | }; 245 | 246 | void zclApp_ResetAttributesToDefaultValues(void) { 247 | zclApp_Config.PirOccupiedToUnoccupiedDelay = DEFAULT_PirOccupiedToUnoccupiedDelay; 248 | zclApp_Config.PirUnoccupiedToOccupiedDelay = DEFAULT_PirUnoccupiedToOccupiedDelay; 249 | zclApp_Config.MsIlluminanceLevelSensingSensitivity = DEFAULT_MsIlluminanceLevelSensingSensitivity; 250 | zclApp_Config.MsTemperatureMinAbsoluteChange = DEFAULT_MsTemperatureMinAbsoluteChange; 251 | zclApp_Config.MsPressureMinAbsoluteChange = DEFAULT_MsPressureMinAbsoluteChange; 252 | zclApp_Config.MsHumidityMinAbsoluteChange = DEFAULT_MsHumidityMinAbsoluteChange; 253 | zclApp_Config.MsIlluminanceMinAbsoluteChange = DEFAULT_MsIlluminanceMinAbsoluteChange; 254 | zclApp_Config.MsTemperaturePeriod = DEFAULT_MsTemperaturePeriod; 255 | zclApp_Config.MsPressurePeriod = DEFAULT_MsPressurePeriod; 256 | zclApp_Config.MsHumidityPeriod = DEFAULT_MsHumidityPeriod; 257 | zclApp_Config.MsIlluminancePeriod = DEFAULT_MsIlluminancePeriod; 258 | zclApp_Config.CfgBatteryPeriod = DEFAULT_CfgBatteryPeriod; 259 | } -------------------------------------------------------------------------------- /converters/DIYRuZ_Motion.js: -------------------------------------------------------------------------------- 1 | const { 2 | fromZigbeeConverters, 3 | toZigbeeConverters, 4 | exposes 5 | } = require('zigbee-herdsman-converters'); 6 | 7 | const bind = async (endpoint, target, clusters) => { 8 | for (const cluster of clusters) { 9 | await endpoint.bind(cluster, target); 10 | } 11 | }; 12 | 13 | const ACCESS_STATE = 0b001, ACCESS_WRITE = 0b010, ACCESS_READ = 0b100; 14 | 15 | const withEpPreffix = (converter) => ({ 16 | ...converter, 17 | convert: (model, msg, publish, options, meta) => { 18 | const epID = msg.endpoint.ID; 19 | const converterResults = converter.convert(model, msg, publish, options, meta) || {}; 20 | return Object.keys(converterResults) 21 | .reduce((result, key) => { 22 | result[`${key}_${epID}`] = converterResults[key]; 23 | return result; 24 | }, {}); 25 | }, 26 | }); 27 | 28 | const postfixWithEndpointName = (name, msg, definition) => { 29 | if (definition.meta && definition.meta.multiEndpoint) { 30 | const endpointName = definition.hasOwnProperty('endpoint') ? 31 | getKey(definition.endpoint(msg.device), msg.endpoint.ID) : msg.endpoint.ID; 32 | return `${name}_${endpointName}`; 33 | } else { 34 | return name; 35 | } 36 | }; 37 | 38 | const fz = { 39 | illuminance: { 40 | cluster: 'msIlluminanceMeasurement', 41 | type: ['attributeReport', 'readResponse'], 42 | convert: (model, msg, publish, options, meta) => { 43 | if (msg.data.hasOwnProperty('measuredValue')) { 44 | const illuminance = msg.data['measuredValue']; 45 | const property = postfixWithEndpointName('illuminance', msg, model); 46 | return {[property]: msg.data.measuredValue}; 47 | } 48 | }, 49 | }, 50 | battery_config: { 51 | cluster: 'genPowerCfg', 52 | type: ['attributeReport', 'readResponse'], 53 | convert: (model, msg, publish, options, meta) => { 54 | const result = {}; 55 | if (msg.data.hasOwnProperty(0xF003)) { 56 | result.battery_period = msg.data[0xF003]; 57 | } 58 | return result; 59 | }, 60 | }, 61 | illuminance_config: { 62 | cluster: 'msIlluminanceMeasurement', 63 | type: ['attributeReport', 'readResponse'], 64 | convert: (model, msg, publish, options, meta) => { 65 | const result = {}; 66 | if (msg.data.hasOwnProperty(0xF000)) { 67 | result.illuminance_sensitivity = msg.data[0xF000]; 68 | } 69 | if (msg.data.hasOwnProperty(0xF001)) { 70 | result.illuminance_change = msg.data[0xF001]; 71 | } 72 | if (msg.data.hasOwnProperty(0xF002)) { 73 | result.illuminance_period = msg.data[0xF002]; 74 | } 75 | return result; 76 | }, 77 | }, 78 | temperature_config: { 79 | cluster: 'msTemperatureMeasurement', 80 | type: ['attributeReport', 'readResponse'], 81 | convert: (model, msg, publish, options, meta) => { 82 | const result = {}; 83 | if (msg.data.hasOwnProperty('measuredValue')) { 84 | result.temperature = msg.data.measuredValue/100; 85 | } 86 | if (msg.data.hasOwnProperty(0xF001)) { 87 | result.temperature_change = msg.data[0xF001]/100; 88 | } 89 | if (msg.data.hasOwnProperty(0xF002)) { 90 | result.temperature_period = msg.data[0xF002]; 91 | } 92 | return result; 93 | }, 94 | }, 95 | pressure_config: { 96 | cluster: 'msPressureMeasurement', 97 | type: ['attributeReport', 'readResponse'], 98 | convert: (model, msg, publish, options, meta) => { 99 | const result = {}; 100 | if (msg.data.hasOwnProperty('scaledValue')) { 101 | result.pressure = msg.data.scaledValue/10; 102 | } 103 | if (msg.data.hasOwnProperty(0xF001)) { 104 | result.pressure_change = msg.data[0xF001]/10; 105 | } 106 | if (msg.data.hasOwnProperty(0xF002)) { 107 | result.pressure_period = msg.data[0xF002]; 108 | } 109 | return result; 110 | }, 111 | }, 112 | humidity_config: { 113 | cluster: 'msRelativeHumidity', 114 | type: ['attributeReport', 'readResponse'], 115 | convert: (model, msg, publish, options, meta) => { 116 | const result = {}; 117 | if (msg.data.hasOwnProperty('measuredValue')) { 118 | result.humidity = msg.data.measuredValue/100; 119 | } 120 | if (msg.data.hasOwnProperty(0xF001)) { 121 | result.humidity_change = msg.data[0xF001]/100; 122 | } 123 | if (msg.data.hasOwnProperty(0xF002)) { 124 | result.humidity_period = msg.data[0xF002]; 125 | } 126 | return result; 127 | }, 128 | }, 129 | occupancy: { 130 | cluster: 'msOccupancySensing', 131 | type: ['attributeReport', 'readResponse'], 132 | convert: (model, msg, publish, options, meta) => { 133 | if (msg.data.hasOwnProperty('occupancy')) { 134 | return {occupancy: msg.data.occupancy === 1}; 135 | } 136 | }, 137 | }, 138 | occupancy_config: { 139 | cluster: 'msOccupancySensing', 140 | type: ['attributeReport', 'readResponse'], 141 | convert: (model, msg, publish, options, meta) => { 142 | const result = {}; 143 | if (msg.data.hasOwnProperty('pirOToUDelay')) { 144 | result.occupancy_timeout = msg.data.pirOToUDelay; 145 | } 146 | if (msg.data.hasOwnProperty('pirUToODelay')) { 147 | result.unoccupancy_timeout = msg.data.pirUToODelay; 148 | } 149 | return result; 150 | }, 151 | }, 152 | contact: { 153 | cluster: 'genBinaryInput', 154 | type: ['attributeReport', 'readResponse'], 155 | convert: (model, msg, publish, options, meta) => { 156 | return {contact: msg.data['presentValue'] !== 0}; 157 | }, 158 | }, 159 | }; 160 | 161 | const tz = { 162 | occupancy_timeout: { 163 | // set delay after motion detector changes from occupied to unoccupied 164 | key: ['occupancy_timeout'], 165 | convertSet: async (entity, key, value, meta) => { 166 | value *= 1; 167 | const thirdEndpoint = meta.device.getEndpoint(3); 168 | await thirdEndpoint.write('msOccupancySensing', {pirOToUDelay: value}); 169 | return {state: {occupancy_timeout: value}}; 170 | }, 171 | convertGet: async (entity, key, meta) => { 172 | const thirdEndpoint = meta.device.getEndpoint(3); 173 | await thirdEndpoint.read('msOccupancySensing', ['pirOToUDelay']); 174 | }, 175 | }, 176 | unoccupancy_timeout: { 177 | // set delay after motion detector changes from unoccupied to occupied 178 | key: ['unoccupancy_timeout'], 179 | convertSet: async (entity, key, value, meta) => { 180 | value *= 1; 181 | const thirdEndpoint = meta.device.getEndpoint(3); 182 | await thirdEndpoint.write('msOccupancySensing', {pirUToODelay: value}); 183 | return {state: {unoccupancy_timeout: value}}; 184 | }, 185 | convertGet: async (entity, key, meta) => { 186 | const thirdEndpoint = meta.device.getEndpoint(3); 187 | await thirdEndpoint.read('msOccupancySensing', ['pirUToODelay']); 188 | }, 189 | }, 190 | illuminance_config: { 191 | // set illuminance sensitivity 192 | key: ['illuminance_sensitivity', 'illuminance_change', 'illuminance_period'], 193 | convertSet: async (entity, key, value, meta) => { 194 | value *= 1; 195 | const fourthEndpoint = meta.device.getEndpoint(4); 196 | const payloads = { 197 | illuminance_sensitivity: ['msIlluminanceMeasurement', {0xF000: {value, type: 0x21}}], 198 | illuminance_change: ['msIlluminanceMeasurement', {0xF001: {value, type: 0x21}}], 199 | illuminance_period: ['msIlluminanceMeasurement', {0xF002: {value, type: 0x21}}], 200 | }; 201 | await fourthEndpoint.write(payloads[key][0], payloads[key][1]); 202 | return { 203 | state: {[key]: value}, 204 | }; 205 | }, 206 | convertGet: async (entity, key, meta) => { 207 | const fourthEndpoint = meta.device.getEndpoint(4); 208 | const payloads = { 209 | illuminance_sensitivity: ['msIlluminanceMeasurement', 0xF000], 210 | illuminance_change: ['msIlluminanceMeasurement', 0xF001], 211 | illuminance_period: ['msIlluminanceMeasurement', 0xF002], 212 | }; 213 | await fourthEndpoint.read(payloads[key][0], [payloads[key][1]]); 214 | }, 215 | }, 216 | change_period: { 217 | // set minAbsoluteChange 218 | key: ['temperature_change', 'pressure_change', 'humidity_change', 'temperature_period', 'pressure_period', 'humidity_period', 'battery_period'], 219 | convertSet: async (entity, key, value, meta) => { 220 | value *= 1; 221 | const temp_value = value; 222 | if ([key] == 'pressure_change'){ 223 | value *= 10; 224 | } 225 | if ([key] == 'temperature_change'){ 226 | value *= 100; 227 | } 228 | if ([key] == 'humidity_change'){ 229 | value *= 100; 230 | } 231 | const payloads = { 232 | temperature_change: ['msTemperatureMeasurement', {0xF001: {value, type: 0x21}}], 233 | pressure_change: ['msPressureMeasurement', {0xF001: {value, type: 0x21}}], 234 | humidity_change: ['msRelativeHumidity', {0xF001: {value, type: 0x21}}], 235 | temperature_period: ['msTemperatureMeasurement', {0xF002: {value, type: 0x21}}], 236 | pressure_period: ['msPressureMeasurement', {0xF002: {value, type: 0x21}}], 237 | humidity_period: ['msRelativeHumidity', {0xF002: {value, type: 0x21}}], 238 | battery_period: ['genPowerCfg', {0xF003: {value, type: 0x21}}], 239 | }; 240 | await entity.write(payloads[key][0], payloads[key][1]); 241 | return { 242 | state: {[key]: temp_value}, 243 | }; 244 | }, 245 | convertGet: async (entity, key, meta) => { 246 | const payloads = { 247 | temperature_change: ['msTemperatureMeasurement', 0xF001], 248 | pressure_change: ['msPressureMeasurement', 0xF001], 249 | humidity_change: ['msRelativeHumidity', 0xF001], 250 | temperature_period: ['msTemperatureMeasurement', 0xF002], 251 | pressure_period: ['msPressureMeasurement', 0xF002], 252 | humidity_period: ['msRelativeHumidity', 0xF002], 253 | battery_period: ['genPowerCfg', 0xF003], 254 | }; 255 | await entity.read(payloads[key][0], [payloads[key][1]]); 256 | }, 257 | }, 258 | }; 259 | 260 | const device = { 261 | zigbeeModel: ['DIYRuZ_Motion'], 262 | model: 'DIYRuZ_Motion', 263 | vendor: 'DIYRuZ', 264 | description: '[Motion sensor](https://github.com/koptserg/motion)', 265 | supports: 'temperature, humidity, illuminance, contact, pressure, battery, occupancy', 266 | fromZigbee: [ 267 | fz.battery_config, 268 | fz.temperature_config, 269 | fz.humidity_config, 270 | fz.illuminance, 271 | fz.illuminance_config, 272 | fz.pressure_config, 273 | fromZigbeeConverters.battery, 274 | fz.contact, 275 | fz.occupancy, 276 | fz.occupancy_config, 277 | ], 278 | toZigbee: [ 279 | tz.occupancy_timeout, 280 | tz.unoccupancy_timeout, 281 | tz.illuminance_config, 282 | tz.change_period, 283 | toZigbeeConverters.factory_reset, 284 | ], 285 | meta: { 286 | configureKey: 1, 287 | multiEndpoint: true, 288 | }, 289 | configure: async (device, coordinatorEndpoint) => { 290 | const firstEndpoint = device.getEndpoint(1); 291 | const secondEndpoint = device.getEndpoint(2); 292 | const thirdEndpoint = device.getEndpoint(3); 293 | const fourthEndpoint = device.getEndpoint(4); 294 | await bind(firstEndpoint, coordinatorEndpoint, [ 295 | 'genPowerCfg', 296 | 'msTemperatureMeasurement', 297 | 'msRelativeHumidity', 298 | 'msPressureMeasurement', 299 | 'msIlluminanceMeasurement', 300 | ]); 301 | await bind(secondEndpoint, coordinatorEndpoint, [ 302 | // 'genOnOff', 303 | 'genBinaryInput', 304 | ]); 305 | await bind(thirdEndpoint, coordinatorEndpoint, [ 306 | // 'genOnOff', 307 | 'msOccupancySensing', 308 | ]); 309 | await bind(fourthEndpoint, coordinatorEndpoint, [ 310 | 'msIlluminanceMeasurement', 311 | ]); 312 | 313 | const genPowerCfgPayload = [{ 314 | attribute: 'batteryVoltage', 315 | minimumReportInterval: 0, 316 | maximumReportInterval: 3600, 317 | reportableChange: 0, 318 | }, 319 | { 320 | attribute: 'batteryPercentageRemaining', 321 | minimumReportInterval: 0, 322 | maximumReportInterval: 3600, 323 | reportableChange: 0, 324 | } 325 | ]; 326 | 327 | const msBindPayload = [{ 328 | attribute: 'measuredValue', 329 | minimumReportInterval: 0, 330 | maximumReportInterval: 3600, 331 | reportableChange: 0, 332 | }]; 333 | const msTemperatureBindPayload = [{ 334 | attribute: 'measuredValue', 335 | minimumReportInterval: 0, 336 | maximumReportInterval: 3600, 337 | reportableChange: 0, 338 | }]; 339 | const genBinaryInputBindPayload = [{ 340 | attribute: 'presentValue', 341 | minimumReportInterval: 0, 342 | maximumReportInterval: 3600, 343 | reportableChange: 0, 344 | }]; 345 | const msOccupancySensingBindPayload = [{ 346 | attribute: 'occupancy', 347 | minimumReportInterval: 0, 348 | maximumReportInterval: 3600, 349 | reportableChange: 0, 350 | }]; 351 | await firstEndpoint.configureReporting('genPowerCfg', genPowerCfgPayload); 352 | await firstEndpoint.configureReporting('msTemperatureMeasurement', msTemperatureBindPayload); 353 | await firstEndpoint.configureReporting('msRelativeHumidity', msBindPayload); 354 | await firstEndpoint.configureReporting('msPressureMeasurement', msBindPayload); 355 | await firstEndpoint.configureReporting('msIlluminanceMeasurement', msBindPayload); 356 | await secondEndpoint.configureReporting('genBinaryInput', genBinaryInputBindPayload); 357 | await thirdEndpoint.configureReporting('msOccupancySensing', msOccupancySensingBindPayload); 358 | await fourthEndpoint.configureReporting('msIlluminanceMeasurement', msBindPayload); 359 | }, 360 | exposes: [ 361 | exposes.numeric('battery', ACCESS_STATE).withUnit('%').withDescription('Remaining battery in %').withValueMin(0).withValueMax(100), 362 | exposes.numeric('temperature', ACCESS_STATE).withUnit('°C').withDescription('Measured temperature value'), 363 | exposes.numeric('humidity', ACCESS_STATE).withUnit('%').withDescription('Measured relative humidity'), 364 | exposes.numeric('pressure', ACCESS_STATE).withUnit('hPa').withDescription('The measured atmospheric pressure'), 365 | exposes.numeric('illuminance_1', ACCESS_STATE).withDescription('Raw measured illuminance LDR'), 366 | exposes.numeric('illuminance_4', ACCESS_STATE).withUnit('lx').withDescription('Measured illuminance in lux BH1750'), 367 | exposes.binary('contact', ACCESS_STATE).withDescription('Indicates if the contact is closed (= true) or open (= false)'), 368 | exposes.binary('occupancy', ACCESS_STATE).withDescription('Indicates whether the device detected occupancy'), 369 | exposes.numeric('occupancy_timeout', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('sec').withDescription('Delay occupied to unoccupied + 10 sec adaptation'), 370 | exposes.numeric('unoccupancy_timeout', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('sec').withDescription('Delay unoccupied to occupied'), 371 | exposes.numeric('illuminance_sensitivity', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withDescription('Illuminance level sensitivity 31 - 254 (default = 69)'), 372 | exposes.numeric('temperature_change', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('°C').withDescription('Temperature min absolute change (default = 0,5 °C)'), 373 | exposes.numeric('temperature_period', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('sec').withDescription('Temperature measurement period (default = 10 sec)'), 374 | exposes.numeric('pressure_change', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('hPa').withDescription('Pressure min absolute change (default = 0,1 hPa)'), 375 | exposes.numeric('pressure_period', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('sec').withDescription('Pressure measurement period (default = 10 sec)'), 376 | exposes.numeric('humidity_change', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('%').withDescription('Humidity min absolute change (default = 10%)'), 377 | exposes.numeric('humidity_period', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('sec').withDescription('Humidity measurement period (default = 10 sec)'), 378 | exposes.numeric('illuminance_change', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('lx').withDescription('Illuminance BH1750 min absolute change (default = 10 lux)'), 379 | exposes.numeric('illuminance_period', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('sec').withDescription('Illuminance BH1750 measurement period (default = 10 sec)'), 380 | exposes.numeric('battery_period', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('min').withDescription('Battery report period (default = 30 min)'), 381 | ], 382 | }; 383 | 384 | module.exports = device; -------------------------------------------------------------------------------- /converters/DIYRuZ_Motion_150724.js: -------------------------------------------------------------------------------- 1 | //const { 2 | // fromZigbeeConverters, 3 | // toZigbeeConverters, 4 | // exposes 5 | //} = require('zigbee-herdsman-converters'); 6 | 7 | const fz = require('zigbee-herdsman-converters/converters/fromZigbee'); 8 | const tz = require('zigbee-herdsman-converters/converters/toZigbee'); 9 | const exposes = require('zigbee-herdsman-converters/lib/exposes'); 10 | const constants = require('zigbee-herdsman-converters/lib/constants'); 11 | const reporting = require('zigbee-herdsman-converters/lib/reporting'); 12 | const ota = require('zigbee-herdsman-converters/lib/ota'); 13 | //const extend = require('zigbee-herdsman-converters/lib/extend'); 14 | const e = exposes.presets; 15 | const ea = exposes.access; 16 | //const {calibrateAndPrecisionRoundOptions} = require('zigbee-herdsman-converters/lib/utils'); 17 | //const {postfixWithEndpointName} = require('zigbee-herdsman-converters/lib/utils'); 18 | 19 | const bind = async (endpoint, target, clusters) => { 20 | for (const cluster of clusters) { 21 | await endpoint.bind(cluster, target); 22 | } 23 | }; 24 | 25 | const ACCESS_STATE = 0b001, ACCESS_WRITE = 0b010, ACCESS_READ = 0b100; 26 | 27 | const postfixWithEndpointName = (name, msg, definition) => { 28 | if (definition.meta && definition.meta.multiEndpoint) { 29 | const endpointName = definition.hasOwnProperty('endpoint') ? 30 | getKey(definition.endpoint(msg.device), msg.endpoint.ID) : msg.endpoint.ID; 31 | return `${name}_${endpointName}`; 32 | } else { 33 | return name; 34 | } 35 | }; 36 | 37 | const fz_local = { 38 | illuminance: { 39 | cluster: 'msIlluminanceMeasurement', 40 | type: ['attributeReport', 'readResponse'], 41 | convert: (model, msg, publish, options, meta) => { 42 | if (msg.data.hasOwnProperty('measuredValue')) { 43 | const illuminance = msg.data['measuredValue']; 44 | const property = postfixWithEndpointName('illuminance', msg, model); 45 | return {[property]: msg.data.measuredValue}; 46 | } 47 | }, 48 | }, 49 | battery_config: { 50 | cluster: 'genPowerCfg', 51 | type: ['attributeReport', 'readResponse'], 52 | convert: (model, msg, publish, options, meta) => { 53 | const result = {}; 54 | if (msg.data.hasOwnProperty(0xF003)) { 55 | result.battery_period = msg.data[0xF003]; 56 | } 57 | return result; 58 | }, 59 | }, 60 | illuminance_config: { 61 | cluster: 'msIlluminanceMeasurement', 62 | type: ['attributeReport', 'readResponse'], 63 | convert: (model, msg, publish, options, meta) => { 64 | const result = {}; 65 | if (msg.data.hasOwnProperty(0xF000)) { 66 | result.illuminance_sensitivity = msg.data[0xF000]; 67 | } 68 | if (msg.data.hasOwnProperty(0xF001)) { 69 | result.illuminance_change = msg.data[0xF001]; 70 | } 71 | if (msg.data.hasOwnProperty(0xF002)) { 72 | result.illuminance_period = msg.data[0xF002]; 73 | } 74 | return result; 75 | }, 76 | }, 77 | temperature_config: { 78 | cluster: 'msTemperatureMeasurement', 79 | type: ['attributeReport', 'readResponse'], 80 | convert: (model, msg, publish, options, meta) => { 81 | const result = {}; 82 | if (msg.data.hasOwnProperty('measuredValue')) { 83 | result.temperature = msg.data.measuredValue/100; 84 | } 85 | if (msg.data.hasOwnProperty(0xF001)) { 86 | result.temperature_change = msg.data[0xF001]/100; 87 | } 88 | if (msg.data.hasOwnProperty(0xF002)) { 89 | result.temperature_period = msg.data[0xF002]; 90 | } 91 | return result; 92 | }, 93 | }, 94 | pressure_config: { 95 | cluster: 'msPressureMeasurement', 96 | type: ['attributeReport', 'readResponse'], 97 | convert: (model, msg, publish, options, meta) => { 98 | const result = {}; 99 | if (msg.data.hasOwnProperty('scaledValue')) { 100 | result.pressure = msg.data.scaledValue/10; 101 | } 102 | if (msg.data.hasOwnProperty(0xF001)) { 103 | result.pressure_change = msg.data[0xF001]/10; 104 | } 105 | if (msg.data.hasOwnProperty(0xF002)) { 106 | result.pressure_period = msg.data[0xF002]; 107 | } 108 | return result; 109 | }, 110 | }, 111 | humidity_config: { 112 | cluster: 'msRelativeHumidity', 113 | type: ['attributeReport', 'readResponse'], 114 | convert: (model, msg, publish, options, meta) => { 115 | const result = {}; 116 | if (msg.data.hasOwnProperty('measuredValue')) { 117 | result.humidity = msg.data.measuredValue/100; 118 | } 119 | if (msg.data.hasOwnProperty(0xF001)) { 120 | result.humidity_change = msg.data[0xF001]/100; 121 | } 122 | if (msg.data.hasOwnProperty(0xF002)) { 123 | result.humidity_period = msg.data[0xF002]; 124 | } 125 | return result; 126 | }, 127 | }, 128 | occupancy: { 129 | cluster: 'msOccupancySensing', 130 | type: ['attributeReport', 'readResponse'], 131 | convert: (model, msg, publish, options, meta) => { 132 | if (msg.data.hasOwnProperty('occupancy')) { 133 | // if (msg.data.occupancy !== 0){ 134 | // publish({occupancy: 2}); 135 | // } 136 | return {occupancy: msg.data.occupancy === 1}; 137 | } 138 | }, 139 | }, 140 | occupancy_config: { 141 | cluster: 'msOccupancySensing', 142 | type: ['attributeReport', 'readResponse'], 143 | convert: (model, msg, publish, options, meta) => { 144 | const result = {}; 145 | if (msg.data.hasOwnProperty('pirOToUDelay')) { 146 | result.occupancy_timeout = msg.data.pirOToUDelay; 147 | } 148 | if (msg.data.hasOwnProperty('pirUToODelay')) { 149 | result.unoccupancy_timeout = msg.data.pirUToODelay; 150 | } 151 | return result; 152 | }, 153 | }, 154 | contact: { 155 | cluster: 'genBinaryInput', 156 | type: ['attributeReport', 'readResponse'], 157 | convert: (model, msg, publish, options, meta) => { 158 | return {contact: msg.data['presentValue'] !== 0}; 159 | }, 160 | }, 161 | }; 162 | 163 | const tz_local = { 164 | occupancy_timeout: { 165 | // set delay after motion detector changes from occupied to unoccupied 166 | key: ['occupancy_timeout'], 167 | convertSet: async (entity, key, value, meta) => { 168 | value *= 1; 169 | const thirdEndpoint = meta.device.getEndpoint(3); 170 | await thirdEndpoint.write('msOccupancySensing', {pirOToUDelay: value}); 171 | return {state: {occupancy_timeout: value}}; 172 | }, 173 | convertGet: async (entity, key, meta) => { 174 | const thirdEndpoint = meta.device.getEndpoint(3); 175 | await thirdEndpoint.read('msOccupancySensing', ['pirOToUDelay']); 176 | }, 177 | }, 178 | unoccupancy_timeout: { 179 | // set delay after motion detector changes from unoccupied to occupied 180 | key: ['unoccupancy_timeout'], 181 | convertSet: async (entity, key, value, meta) => { 182 | value *= 1; 183 | const thirdEndpoint = meta.device.getEndpoint(3); 184 | await thirdEndpoint.write('msOccupancySensing', {pirUToODelay: value}); 185 | return {state: {unoccupancy_timeout: value}}; 186 | }, 187 | convertGet: async (entity, key, meta) => { 188 | const thirdEndpoint = meta.device.getEndpoint(3); 189 | await thirdEndpoint.read('msOccupancySensing', ['pirUToODelay']); 190 | }, 191 | }, 192 | illuminance_config: { 193 | // set illuminance sensitivity 194 | key: ['illuminance_sensitivity', 'illuminance_change', 'illuminance_period'], 195 | convertSet: async (entity, key, value, meta) => { 196 | value *= 1; 197 | const fourthEndpoint = meta.device.getEndpoint(4); 198 | const payloads = { 199 | illuminance_sensitivity: ['msIlluminanceMeasurement', {0xF000: {value, type: 0x21}}], 200 | illuminance_change: ['msIlluminanceMeasurement', {0xF001: {value, type: 0x21}}], 201 | illuminance_period: ['msIlluminanceMeasurement', {0xF002: {value, type: 0x21}}], 202 | }; 203 | await fourthEndpoint.write(payloads[key][0], payloads[key][1]); 204 | return { 205 | state: {[key]: value}, 206 | }; 207 | }, 208 | convertGet: async (entity, key, meta) => { 209 | const fourthEndpoint = meta.device.getEndpoint(4); 210 | const payloads = { 211 | illuminance_sensitivity: ['msIlluminanceMeasurement', 0xF000], 212 | illuminance_change: ['msIlluminanceMeasurement', 0xF001], 213 | illuminance_period: ['msIlluminanceMeasurement', 0xF002], 214 | }; 215 | await fourthEndpoint.read(payloads[key][0], [payloads[key][1]]); 216 | }, 217 | }, 218 | change_period: { 219 | // set minAbsoluteChange 220 | key: ['temperature_change', 'pressure_change', 'humidity_change', 'temperature_period', 'pressure_period', 'humidity_period', 'battery_period'], 221 | convertSet: async (entity, key, value, meta) => { 222 | value *= 1; 223 | const temp_value = value; 224 | if ([key] == 'pressure_change'){ 225 | value *= 10; 226 | } 227 | if ([key] == 'temperature_change'){ 228 | value *= 100; 229 | } 230 | if ([key] == 'humidity_change'){ 231 | value *= 100; 232 | } 233 | const payloads = { 234 | temperature_change: ['msTemperatureMeasurement', {0xF001: {value, type: 0x21}}], 235 | pressure_change: ['msPressureMeasurement', {0xF001: {value, type: 0x21}}], 236 | humidity_change: ['msRelativeHumidity', {0xF001: {value, type: 0x21}}], 237 | temperature_period: ['msTemperatureMeasurement', {0xF002: {value, type: 0x21}}], 238 | pressure_period: ['msPressureMeasurement', {0xF002: {value, type: 0x21}}], 239 | humidity_period: ['msRelativeHumidity', {0xF002: {value, type: 0x21}}], 240 | battery_period: ['genPowerCfg', {0xF003: {value, type: 0x21}}], 241 | }; 242 | await entity.write(payloads[key][0], payloads[key][1]); 243 | return { 244 | state: {[key]: temp_value}, 245 | }; 246 | }, 247 | convertGet: async (entity, key, meta) => { 248 | const payloads = { 249 | temperature_change: ['msTemperatureMeasurement', 0xF001], 250 | pressure_change: ['msPressureMeasurement', 0xF001], 251 | humidity_change: ['msRelativeHumidity', 0xF001], 252 | temperature_period: ['msTemperatureMeasurement', 0xF002], 253 | pressure_period: ['msPressureMeasurement', 0xF002], 254 | humidity_period: ['msRelativeHumidity', 0xF002], 255 | battery_period: ['genPowerCfg', 0xF003], 256 | }; 257 | await entity.read(payloads[key][0], [payloads[key][1]]); 258 | }, 259 | }, 260 | }; 261 | 262 | const device = { 263 | zigbeeModel: ['DIYRuZ_Motion'], 264 | model: 'DIYRuZ_Motion', 265 | vendor: 'DIYRuZ', 266 | description: '[Motion sensor](https://github.com/koptserg/motion)', 267 | supports: 'temperature, humidity, illuminance, contact, pressure, battery, occupancy', 268 | fromZigbee: [ 269 | fz_local.battery_config, 270 | fz_local.temperature_config, 271 | fz_local.humidity_config, 272 | fz_local.illuminance, 273 | fz_local.illuminance_config, 274 | fz_local.pressure_config, 275 | fz.battery, 276 | fz_local.contact, 277 | fz_local.occupancy, 278 | fz_local.occupancy_config, 279 | ], 280 | toZigbee: [ 281 | tz_local.occupancy_timeout, 282 | tz_local.unoccupancy_timeout, 283 | tz_local.illuminance_config, 284 | tz_local.change_period, 285 | tz.factory_reset, 286 | ], 287 | meta: { 288 | configureKey: 1, 289 | multiEndpoint: true, 290 | }, 291 | configure: async (device, coordinatorEndpoint) => { 292 | const firstEndpoint = device.getEndpoint(1); 293 | const secondEndpoint = device.getEndpoint(2); 294 | const thirdEndpoint = device.getEndpoint(3); 295 | const fourthEndpoint = device.getEndpoint(4); 296 | await bind(firstEndpoint, coordinatorEndpoint, [ 297 | 'genPowerCfg', 298 | 'msTemperatureMeasurement', 299 | 'msRelativeHumidity', 300 | 'msPressureMeasurement', 301 | 'msIlluminanceMeasurement', 302 | ]); 303 | await bind(secondEndpoint, coordinatorEndpoint, [ 304 | // 'genOnOff', 305 | 'genBinaryInput', 306 | ]); 307 | await bind(thirdEndpoint, coordinatorEndpoint, [ 308 | // 'genOnOff', 309 | 'msOccupancySensing', 310 | ]); 311 | await bind(fourthEndpoint, coordinatorEndpoint, [ 312 | 'msIlluminanceMeasurement', 313 | ]); 314 | 315 | const genPowerCfgPayload = [{ 316 | attribute: 'batteryVoltage', 317 | minimumReportInterval: 0, 318 | maximumReportInterval: 3600, 319 | reportableChange: 0, 320 | }, 321 | { 322 | attribute: 'batteryPercentageRemaining', 323 | minimumReportInterval: 0, 324 | maximumReportInterval: 3600, 325 | reportableChange: 0, 326 | } 327 | ]; 328 | 329 | const msBindPayload = [{ 330 | attribute: 'measuredValue', 331 | minimumReportInterval: 0, 332 | maximumReportInterval: 3600, 333 | reportableChange: 0, 334 | }]; 335 | const msTemperatureBindPayload = [{ 336 | attribute: 'measuredValue', 337 | minimumReportInterval: 0, 338 | maximumReportInterval: 3600, 339 | reportableChange: 0, 340 | }]; 341 | const genBinaryInputBindPayload = [{ 342 | attribute: 'presentValue', 343 | minimumReportInterval: 0, 344 | maximumReportInterval: 3600, 345 | reportableChange: 0, 346 | }]; 347 | const msOccupancySensingBindPayload = [{ 348 | attribute: 'occupancy', 349 | minimumReportInterval: 0, 350 | maximumReportInterval: 3600, 351 | reportableChange: 0, 352 | }]; 353 | await firstEndpoint.configureReporting('genPowerCfg', genPowerCfgPayload); 354 | await firstEndpoint.configureReporting('msTemperatureMeasurement', msTemperatureBindPayload); 355 | await firstEndpoint.configureReporting('msRelativeHumidity', msBindPayload); 356 | await firstEndpoint.configureReporting('msPressureMeasurement', msBindPayload); 357 | await firstEndpoint.configureReporting('msIlluminanceMeasurement', msBindPayload); 358 | await secondEndpoint.configureReporting('genBinaryInput', genBinaryInputBindPayload); 359 | await thirdEndpoint.configureReporting('msOccupancySensing', msOccupancySensingBindPayload); 360 | await fourthEndpoint.configureReporting('msIlluminanceMeasurement', msBindPayload); 361 | }, 362 | exposes: [ 363 | exposes.numeric('battery', ACCESS_STATE).withUnit('%').withDescription('Remaining battery in %').withValueMin(0).withValueMax(100), 364 | exposes.numeric('temperature', ACCESS_STATE).withUnit('°C').withDescription('Measured temperature value'), 365 | exposes.numeric('humidity', ACCESS_STATE).withUnit('%').withDescription('Measured relative humidity'), 366 | exposes.numeric('pressure', ACCESS_STATE).withUnit('hPa').withDescription('The measured atmospheric pressure'), 367 | exposes.numeric('illuminance_1', ACCESS_STATE).withDescription('Raw measured illuminance LDR'), 368 | exposes.numeric('illuminance_4', ACCESS_STATE).withUnit('lx').withDescription('Measured illuminance in lux BH1750'), 369 | exposes.binary('contact', ACCESS_STATE).withDescription('Indicates if the contact is closed (= true) or open (= false)'), 370 | exposes.binary('occupancy', ACCESS_STATE).withDescription('Indicates whether the device detected occupancy'), 371 | exposes.numeric('occupancy_timeout', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('sec').withDescription('Delay occupied to unoccupied + 10 sec adaptation'), 372 | exposes.numeric('unoccupancy_timeout', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('sec').withDescription('Delay unoccupied to occupied'), 373 | exposes.numeric('illuminance_sensitivity', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withDescription('Illuminance level sensitivity 31 - 254 (default = 69)'), 374 | exposes.numeric('temperature_change', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('°C').withDescription('Temperature min absolute change (default = 0,5 °C)'), 375 | exposes.numeric('temperature_period', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('sec').withDescription('Temperature measurement period (default = 10 sec)'), 376 | exposes.numeric('pressure_change', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('hPa').withDescription('Pressure min absolute change (default = 0,1 hPa)'), 377 | exposes.numeric('pressure_period', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('sec').withDescription('Pressure measurement period (default = 10 sec)'), 378 | exposes.numeric('humidity_change', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('%').withDescription('Humidity min absolute change (default = 10%)'), 379 | exposes.numeric('humidity_period', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('sec').withDescription('Humidity measurement period (default = 10 sec)'), 380 | exposes.numeric('illuminance_change', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('lx').withDescription('Illuminance BH1750 min absolute change (default = 10 lux)'), 381 | exposes.numeric('illuminance_period', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('sec').withDescription('Illuminance BH1750 measurement period (default = 10 sec)'), 382 | exposes.numeric('battery_period', ACCESS_STATE | ACCESS_WRITE | ACCESS_READ).withUnit('min').withDescription('Battery report period (default = 30 min)'), 383 | ], 384 | }; 385 | 386 | module.exports = device; -------------------------------------------------------------------------------- /firmwares/README.md: -------------------------------------------------------------------------------- 1 | Downalod from github [releases](https://github.com/koptserg/motion/releases) 2 | -------------------------------------------------------------------------------- /hardware/AAA/BOM_PCB_zigbee_pir_share_036_AAA_2021-07-14.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/hardware/AAA/BOM_PCB_zigbee_pir_share_036_AAA_2021-07-14.csv -------------------------------------------------------------------------------- /hardware/AAA/Gerber_PCB_zigbee_pir_share_036_AAA_2021-07-14.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/hardware/AAA/Gerber_PCB_zigbee_pir_share_036_AAA_2021-07-14.zip -------------------------------------------------------------------------------- /hardware/AAA/zigbee_pir_share_AAA.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/hardware/AAA/zigbee_pir_share_AAA.pdf -------------------------------------------------------------------------------- /hardware/CR2/BOM_zigbee_multipurpose_sensor_cr2450_v4.2_CR2_2021-07-14.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/hardware/CR2/BOM_zigbee_multipurpose_sensor_cr2450_v4.2_CR2_2021-07-14.csv -------------------------------------------------------------------------------- /hardware/CR2/Gerber_zigbee_multipurpose_sensor_cr2450_v4.2_CR2_2021-07-14.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/hardware/CR2/Gerber_zigbee_multipurpose_sensor_cr2450_v4.2_CR2_2021-07-14.zip -------------------------------------------------------------------------------- /hardware/CR2/zigbee_pir_share_CR2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/hardware/CR2/zigbee_pir_share_CR2.pdf -------------------------------------------------------------------------------- /hardware/datasheet/1: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /images/diyruz_motion.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/images/diyruz_motion.jpg -------------------------------------------------------------------------------- /images/diyruz_motion_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/images/diyruz_motion_1.jpg -------------------------------------------------------------------------------- /images/diyruz_motion_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/images/diyruz_motion_2.jpg -------------------------------------------------------------------------------- /images/diyruz_motion_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/images/diyruz_motion_3.jpg -------------------------------------------------------------------------------- /images/diyruz_motion_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/images/diyruz_motion_4.jpg -------------------------------------------------------------------------------- /images/diyruz_motion_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/images/diyruz_motion_5.png -------------------------------------------------------------------------------- /images/diyruz_motion_6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/images/diyruz_motion_6.jpg -------------------------------------------------------------------------------- /images/diyruz_motion_sheme.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/images/diyruz_motion_sheme.jpg -------------------------------------------------------------------------------- /images/motion_AAA.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/images/motion_AAA.jpg -------------------------------------------------------------------------------- /images/motion_CR2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/images/motion_CR2.jpg -------------------------------------------------------------------------------- /images/photo_2021-07-11_18-00-41.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/images/photo_2021-07-11_18-00-41.jpg -------------------------------------------------------------------------------- /images/photo_2021-07-11_18-02-03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koptserg/motion/a7c12671808af82eac6e9974feb16e52112155a5/images/photo_2021-07-11_18-02-03.jpg -------------------------------------------------------------------------------- /jsons2csv.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import json 4 | import csv 5 | 6 | intput_file = sys.argv[1] 7 | output_file = sys.argv[2] 8 | 9 | with open(intput_file) as fp: 10 | with open(output_file, 'w', newline='') as csvfile: 11 | fieldnames = ['raw_battery_adc_2', 'raw_humidity_adc_2'] 12 | writer = csv.DictWriter(csvfile, fieldnames=fieldnames) 13 | writer.writeheader() 14 | 15 | for line in fp: 16 | record = json.loads(line) 17 | writer.writerow({'raw_battery_adc_2': record['raw_battery_adc_2'], 'raw_humidity_adc_2': record['raw_humidity_adc_2']}) 18 | -------------------------------------------------------------------------------- /ver.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from os.path import dirname, join 3 | cwd = dirname(__file__) 4 | now = datetime.now() 5 | dt_string = now.strftime("%d/%m/%Y %H:%M") 6 | print("date and time =", dt_string) 7 | with open(join(cwd, './Source/version.c'), 'w') as f: 8 | chars = ["'{0}'".format(char) for char in dt_string] 9 | f.write(""" 10 | #ifndef ZCL_APP_VERSION_H 11 | #define ZCL_APP_VERSION_H 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | """ 18 | ) 19 | f.write('#include "version.h"\n') 20 | code = """const uint8 zclApp_DateCode[] = {{ {0}, {1} }};\n""".format(len(chars), ', '.join(chars)) 21 | f.write(code) 22 | code = """const char zclApp_DateCodeNT[] = \"{0}\";\n""".format(dt_string) 23 | f.write(code) 24 | f.write(""" 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | #endif /* ZCL_APP_VERSION_H */ 30 | """) -------------------------------------------------------------------------------- /zstack-lib/Debug.c: -------------------------------------------------------------------------------- 1 | #include "Debug.h" 2 | #include "DebugTrace.h" 3 | #include "MT.h" 4 | #include "OSAL.h" 5 | #include "OSAL_Memory.h" 6 | 7 | 8 | void vprint(const char *fmt, va_list argp) { 9 | uint8 string[100]; 10 | if (0 < vsprintf((char *)string, fmt, argp)) // build string 11 | { 12 | LREPMaster(string); 13 | } 14 | } 15 | 16 | #ifdef DO_DEBUG_UART 17 | #define UART_PORT HAL_UART_PORT_0 18 | bool DebugInit() { 19 | halUARTCfg_t halUARTConfig; 20 | halUARTConfig.configured = TRUE; 21 | halUARTConfig.baudRate = HAL_UART_BR_115200; 22 | halUARTConfig.flowControl = FALSE; 23 | halUARTConfig.flowControlThreshold = 48; // this parameter indicates number of bytes left before Rx Buffer 24 | // reaches maxRxBufSize 25 | halUARTConfig.idleTimeout = 10; // this parameter indicates rx timeout period in millisecond 26 | halUARTConfig.rx.maxBufSize = 0; 27 | halUARTConfig.tx.maxBufSize = BUFFLEN; 28 | halUARTConfig.intEnable = TRUE; 29 | halUARTConfig.callBackFunc = NULL; 30 | HalUARTInit(); 31 | if (HalUARTOpen(UART_PORT, &halUARTConfig) == HAL_UART_SUCCESS) { 32 | LREPMaster("Initialized debug module \r\n"); 33 | return true; 34 | } 35 | return false; 36 | } 37 | 38 | void LREPMaster(uint8 *data) { 39 | if (data == NULL) { 40 | return; 41 | } 42 | HalUARTWrite(UART_PORT, data, osal_strlen((char *)data)); 43 | } 44 | 45 | void LREP(char *format, ...) { 46 | va_list argp; 47 | va_start(argp, format); 48 | vprint(format, argp); 49 | va_end(argp); 50 | } 51 | #elif defined(DO_DEBUG_MT) 52 | 53 | bool DebugInit() { 54 | debugThreshold = 0x04; // increase threshold as soon as we initialize debug module 55 | LREPMaster("Initialized debug module \r\n"); 56 | return TRUE; 57 | } 58 | void LREP(char *format, ...) { 59 | 60 | va_list argp; 61 | va_start(argp, format); 62 | vprint(format, argp); 63 | va_end(argp); 64 | } 65 | void LREPMaster(uint8 *data) { debug_str(data); } 66 | #else 67 | bool DebugInit() {return true;}; 68 | void LREP(char *format, ...) { 69 | va_list argp; 70 | va_start(argp, format); 71 | printf(format, argp); 72 | va_end(argp); 73 | }; 74 | void LREPMaster(uint8 *data) { 75 | printf((const char*)data); 76 | }; 77 | #endif 78 | -------------------------------------------------------------------------------- /zstack-lib/Debug.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEBUG_H 2 | #define _DEBUG_H 3 | 4 | #include "hal_types.h" 5 | #include "hal_uart.h" 6 | #include 7 | #include 8 | #include 9 | 10 | #define BUFFLEN 128 11 | #define BUFFER 100 12 | 13 | #define PRINT_NUMBER_TYPE long 14 | 15 | #define PAD_RIGHT 1 16 | #define PAD_ZERO 2 17 | 18 | #define PRINT_BUF_LEN 12 19 | 20 | #define PRINT_IMMEDIATE_PRINT 0 21 | 22 | 23 | #define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" 24 | #define BYTE_TO_BINARY(byte) \ 25 | (byte & 0x80 ? '1' : '0'), \ 26 | (byte & 0x40 ? '1' : '0'), \ 27 | (byte & 0x20 ? '1' : '0'), \ 28 | (byte & 0x10 ? '1' : '0'), \ 29 | (byte & 0x08 ? '1' : '0'), \ 30 | (byte & 0x04 ? '1' : '0'), \ 31 | (byte & 0x02 ? '1' : '0'), \ 32 | (byte & 0x01 ? '1' : '0') 33 | 34 | extern halUARTCfg_t halUARTConfig; 35 | 36 | void vprint(const char *fmt, va_list argp); 37 | extern bool DebugInit(void); 38 | extern void LREP(char *format, ...); 39 | extern void LREPMaster(uint8 *data); 40 | #endif -------------------------------------------------------------------------------- /zstack-lib/README.md: -------------------------------------------------------------------------------- 1 | # Collection of reusable componets for Z-stack 3.0.2 -------------------------------------------------------------------------------- /zstack-lib/battery.h: -------------------------------------------------------------------------------- 1 | #ifndef _BATTERY_H 2 | #define _BATTERY_H 3 | //This is custom attribute 4 | #define ATTRID_POWER_CFG_BATTERY_VOLTAGE_RAW_ADC 0x0200 5 | 6 | 7 | extern uint8 zclBattery_Voltage; 8 | extern uint8 zclBattery_PercentageRemainig; 9 | extern uint16 zclBattery_RawAdc; 10 | 11 | 12 | extern uint16 getBatteryVoltage(void); 13 | extern uint8 getBatteryVoltageZCL(uint16 millivolts); 14 | extern uint8 getBatteryRemainingPercentageZCL(uint16 millivolts); 15 | extern uint8 getBatteryRemainingPercentageZCLCR2032(uint16 volt16); 16 | 17 | extern void zclBattery_Init(uint8 task_id); 18 | extern uint16 zclBattery_event_loop(uint8 task_id, uint16 events); 19 | extern void zclBattery_HandleKeys(uint8 portAndAction, uint8 keyCode); 20 | extern void zclBattery_Report(void); 21 | #endif -------------------------------------------------------------------------------- /zstack-lib/bettery.c: -------------------------------------------------------------------------------- 1 | #include "Debug.h" 2 | #include "battery.h" 3 | #include "hal_adc.h" 4 | #include "utils.h" 5 | #include "OSAL.h" 6 | #include "zcl.h" 7 | #include "zcl_general.h" 8 | #include "bdb_interface.h" 9 | // (( 3 * 1.15 ) / (( 2^14 / 2 ) - 1 )) * 1000 (not correct) 10 | // #define MULTI (float) 0.4211939934 11 | // this coefficient calculated using 12 | // https://docs.google.com/spreadsheets/d/1qrFdMTo0ZrqtlGUoafeB3hplhU3GzDnVWuUK4M9OgNo/edit?usp=sharing 13 | #define MULTI (float)0.443 14 | 15 | #define VOLTAGE_MIN 2.0 16 | #define VOLTAGE_MAX 3.3 17 | 18 | #ifndef ZCL_BATTERY_REPORT_INTERVAL 19 | #define ZCL_BATTERY_REPORT_INTERVAL ((uint32) 1800000) //30 minutes 20 | #endif 21 | 22 | #ifndef ZCL_BATTERY_REPORT_DELAY 23 | #define ZCL_BATTERY_REPORT_DELAY 5 * 1000 24 | #endif 25 | 26 | #ifndef ZCL_BATTERY_REPORT_REPORT_CONVERTER 27 | #define ZCL_BATTERY_REPORT_REPORT_CONVERTER(millivolts) getBatteryRemainingPercentageZCLCR2032(millivolts) 28 | #endif 29 | 30 | #define POWER_CFG ZCL_CLUSTER_ID_GEN_POWER_CFG 31 | 32 | #define ZCL_BATTERY_REPORT_EVT 0x0001 33 | 34 | 35 | uint8 zclBattery_Voltage = 0xff; 36 | uint8 zclBattery_PercentageRemainig = 0xff; 37 | uint16 zclBattery_RawAdc = 0xff; 38 | 39 | uint8 getBatteryVoltageZCL(uint16 millivolts) { 40 | uint8 volt8 = (uint8)(millivolts / 100); 41 | if ((millivolts - (volt8 * 100)) > 50) { 42 | return volt8 + 1; 43 | } else { 44 | return volt8; 45 | } 46 | } 47 | // return millivolts 48 | uint16 getBatteryVoltage(void) { 49 | HalAdcSetReference(HAL_ADC_REF_125V); 50 | zclBattery_RawAdc = adcReadSampled(HAL_ADC_CHANNEL_VDD, HAL_ADC_RESOLUTION_14, HAL_ADC_REF_125V, 10); 51 | return (uint16)(zclBattery_RawAdc * MULTI); 52 | } 53 | 54 | uint8 getBatteryRemainingPercentageZCL(uint16 millivolts) { return (uint8)mapRange(VOLTAGE_MIN, VOLTAGE_MAX, 0.0, 200.0, millivolts); } 55 | 56 | uint8 getBatteryRemainingPercentageZCLCR2032(uint16 volt16) { 57 | float battery_level; 58 | if (volt16 >= 3000) { 59 | battery_level = 100; 60 | } else if (volt16 > 2900) { 61 | battery_level = 100 - ((3000 - volt16) * 58) / 100; 62 | } else if (volt16 > 2740) { 63 | battery_level = 42 - ((2900 - volt16) * 24) / 160; 64 | } else if (volt16 > 2440) { 65 | battery_level = 18 - ((2740 - volt16) * 12) / 300; 66 | } else if (volt16 > 2100) { 67 | battery_level = 6 - ((2440 - volt16) * 6) / 340; 68 | } else { 69 | battery_level = 0; 70 | } 71 | return (uint8)(battery_level * 2); 72 | } 73 | 74 | void zclBattery_Report(void) { 75 | uint16 millivolts = getBatteryVoltage(); 76 | zclBattery_Voltage = getBatteryVoltageZCL(millivolts); 77 | zclBattery_PercentageRemainig = ZCL_BATTERY_REPORT_REPORT_CONVERTER(millivolts); 78 | 79 | LREP("Battery voltageZCL=%d prc=%d voltage=%d\r\n", zclBattery_Voltage, zclBattery_PercentageRemainig, millivolts); 80 | 81 | #if BDB_REPORTING 82 | bdb_RepChangedAttrValue(1, POWER_CFG, ATTRID_POWER_CFG_BATTERY_PERCENTAGE_REMAINING); 83 | #else 84 | const uint8 NUM_ATTRIBUTES = 3; 85 | zclReportCmd_t *pReportCmd; 86 | pReportCmd = osal_mem_alloc(sizeof(zclReportCmd_t) + (NUM_ATTRIBUTES * sizeof(zclReport_t))); 87 | if (pReportCmd != NULL) { 88 | pReportCmd->numAttr = NUM_ATTRIBUTES; 89 | 90 | pReportCmd->attrList[0].attrID = ATTRID_POWER_CFG_BATTERY_VOLTAGE; 91 | pReportCmd->attrList[0].dataType = ZCL_DATATYPE_UINT8; 92 | pReportCmd->attrList[0].attrData = (void *)(&zclBattery_Voltage); 93 | 94 | pReportCmd->attrList[1].attrID = ATTRID_POWER_CFG_BATTERY_PERCENTAGE_REMAINING; 95 | pReportCmd->attrList[1].dataType = ZCL_DATATYPE_UINT8; 96 | pReportCmd->attrList[1].attrData = (void *)(&zclBattery_PercentageRemainig); 97 | 98 | pReportCmd->attrList[2].attrID = ATTRID_POWER_CFG_BATTERY_VOLTAGE_RAW_ADC; 99 | pReportCmd->attrList[2].dataType = ZCL_DATATYPE_UINT16; 100 | pReportCmd->attrList[2].attrData = (void *)(&zclBattery_RawAdc); 101 | 102 | afAddrType_t inderect_DstAddr = {.addrMode = (afAddrMode_t)AddrNotPresent, .endPoint = 0, .addr.shortAddr = 0}; 103 | zcl_SendReportCmd(1, &inderect_DstAddr, POWER_CFG, pReportCmd, ZCL_FRAME_CLIENT_SERVER_DIR, TRUE, bdb_getZCLFrameCounter()); 104 | } 105 | osal_mem_free(pReportCmd); 106 | #endif 107 | } 108 | 109 | uint8 zclBattery_TaskId = 0; 110 | 111 | void zclBattery_Init(uint8 task_id) { 112 | zclBattery_TaskId = task_id; 113 | #if BDB_REPORTING 114 | osal_start_reload_timer(zclBattery_TaskId, ZCL_BATTERY_REPORT_EVT, ZCL_BATTERY_REPORT_INTERVAL); 115 | #endif 116 | } 117 | 118 | uint16 zclBattery_event_loop(uint8 task_id, uint16 events) { 119 | LREP("zclBattery_event_loop 0x%X\r\n", events); 120 | if (events & ZCL_BATTERY_REPORT_EVT) { 121 | LREPMaster("ZCL_BATTERY_REPORT_EVT\r\n"); 122 | zclBattery_Report(); 123 | return (events ^ ZCL_BATTERY_REPORT_EVT); 124 | } 125 | return 0; 126 | } 127 | 128 | void zclBattery_HandleKeys(uint8 portAndAction, uint8 keyCode) { 129 | osal_start_timerEx(zclBattery_TaskId, ZCL_BATTERY_REPORT_EVT, ZCL_BATTERY_REPORT_DELAY); 130 | } -------------------------------------------------------------------------------- /zstack-lib/commissioning.c: -------------------------------------------------------------------------------- 1 | #include "commissioning.h" 2 | #include "Debug.h" 3 | #include "OSAL_PwrMgr.h" 4 | #include "ZDApp.h" 5 | #include "bdb_interface.h" 6 | #include "hal_key.h" 7 | #include "hal_led.h" 8 | 9 | static void zclCommissioning_ProcessCommissioningStatus(bdbCommissioningModeMsg_t *bdbCommissioningModeMsg); 10 | static void zclCommissioning_ResetBackoffRetry(void); 11 | static void zclCommissioning_BindNotification(bdbBindNotificationData_t *data); 12 | extern bool requestNewTrustCenterLinkKey; 13 | 14 | byte rejoinsLeft = APP_COMMISSIONING_END_DEVICE_REJOIN_TRIES; 15 | uint32 rejoinDelay = APP_COMMISSIONING_END_DEVICE_REJOIN_START_DELAY; 16 | 17 | uint8 zclCommissioning_TaskId = 0; 18 | 19 | #ifndef APP_TX_POWER 20 | #define APP_TX_POWER TX_PWR_PLUS_4 21 | #endif 22 | 23 | void zclCommissioning_Init(uint8 task_id) { 24 | zclCommissioning_TaskId = task_id; 25 | 26 | bdb_RegisterCommissioningStatusCB(zclCommissioning_ProcessCommissioningStatus); 27 | bdb_RegisterBindNotificationCB(zclCommissioning_BindNotification); 28 | 29 | ZMacSetTransmitPower(APP_TX_POWER); 30 | 31 | // this is important to allow connects throught routers 32 | // to make this work, coordinator should be compiled with this flag #define TP2_LEGACY_ZC 33 | requestNewTrustCenterLinkKey = FALSE; 34 | bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING | BDB_COMMISSIONING_MODE_FINDING_BINDING); 35 | } 36 | 37 | static void zclCommissioning_ResetBackoffRetry(void) { 38 | rejoinsLeft = APP_COMMISSIONING_END_DEVICE_REJOIN_TRIES; 39 | rejoinDelay = APP_COMMISSIONING_END_DEVICE_REJOIN_START_DELAY; 40 | } 41 | 42 | static void zclCommissioning_OnConnect(void) { 43 | LREPMaster("zclCommissioning_OnConnect \r\n"); 44 | zclCommissioning_ResetBackoffRetry(); 45 | osal_start_timerEx(zclCommissioning_TaskId, APP_COMMISSIONING_CLOCK_DOWN_POLING_RATE_EVT, 10 * 1000); 46 | } 47 | 48 | static void zclCommissioning_ProcessCommissioningStatus(bdbCommissioningModeMsg_t *bdbCommissioningModeMsg) { 49 | LREP("bdbCommissioningMode=%d bdbCommissioningStatus=%d bdbRemainingCommissioningModes=0x%X\r\n", 50 | bdbCommissioningModeMsg->bdbCommissioningMode, bdbCommissioningModeMsg->bdbCommissioningStatus, 51 | bdbCommissioningModeMsg->bdbRemainingCommissioningModes); 52 | switch (bdbCommissioningModeMsg->bdbCommissioningMode) { 53 | case BDB_COMMISSIONING_INITIALIZATION: 54 | switch (bdbCommissioningModeMsg->bdbCommissioningStatus) { 55 | case BDB_COMMISSIONING_NO_NETWORK: 56 | LREP("No network\r\n"); 57 | HalLedBlink(HAL_LED_1, 3, 50, 500); 58 | break; 59 | case BDB_COMMISSIONING_NETWORK_RESTORED: 60 | zclCommissioning_OnConnect(); 61 | break; 62 | default: 63 | break; 64 | } 65 | break; 66 | case BDB_COMMISSIONING_NWK_STEERING: 67 | switch (bdbCommissioningModeMsg->bdbCommissioningStatus) { 68 | case BDB_COMMISSIONING_SUCCESS: 69 | HalLedBlink(HAL_LED_1, 5, 50, 500); 70 | LREPMaster("BDB_COMMISSIONING_SUCCESS\r\n"); 71 | zclCommissioning_OnConnect(); 72 | break; 73 | 74 | default: 75 | HalLedSet(HAL_LED_1, HAL_LED_MODE_BLINK); 76 | break; 77 | } 78 | 79 | break; 80 | 81 | case BDB_COMMISSIONING_PARENT_LOST: 82 | LREPMaster("BDB_COMMISSIONING_PARENT_LOST\r\n"); 83 | switch (bdbCommissioningModeMsg->bdbCommissioningStatus) { 84 | case BDB_COMMISSIONING_NETWORK_RESTORED: 85 | zclCommissioning_ResetBackoffRetry(); 86 | break; 87 | 88 | default: 89 | HalLedSet(HAL_LED_1, HAL_LED_MODE_BLINK); 90 | // // Parent not found, attempt to rejoin again after a exponential backoff delay 91 | LREP("rejoinsLeft %d rejoinDelay=%ld\r\n", rejoinsLeft, rejoinDelay); 92 | if (rejoinsLeft > 0) { 93 | rejoinDelay *= APP_COMMISSIONING_END_DEVICE_REJOIN_BACKOFF; 94 | rejoinsLeft -= 1; 95 | } else { 96 | rejoinDelay = APP_COMMISSIONING_END_DEVICE_REJOIN_MAX_DELAY; 97 | } 98 | osal_start_timerEx(zclCommissioning_TaskId, APP_COMMISSIONING_END_DEVICE_REJOIN_EVT, rejoinDelay); 99 | break; 100 | } 101 | break; 102 | default: 103 | break; 104 | } 105 | } 106 | 107 | static void zclCommissioning_ProcessIncomingMsg(zclIncomingMsg_t *pInMsg) { 108 | if (pInMsg->attrCmd) { 109 | osal_mem_free(pInMsg->attrCmd); 110 | } 111 | } 112 | 113 | void zclCommissioning_Sleep(uint8 allow) { 114 | LREP("zclCommissioning_Sleep %d\r\n", allow); 115 | #if defined(POWER_SAVING) 116 | if (allow) { 117 | NLME_SetPollRate(0); 118 | } else { 119 | NLME_SetPollRate(POLL_RATE); 120 | } 121 | #endif 122 | } 123 | 124 | uint16 zclCommissioning_event_loop(uint8 task_id, uint16 events) { 125 | if (events & SYS_EVENT_MSG) { 126 | devStates_t zclApp_NwkState; 127 | afIncomingMSGPacket_t *MSGpkt; 128 | while ((MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive(zclCommissioning_TaskId))) { 129 | 130 | switch (MSGpkt->hdr.event) { 131 | case ZDO_STATE_CHANGE: 132 | HalLedSet(HAL_LED_1, HAL_LED_MODE_BLINK); 133 | zclApp_NwkState = (devStates_t)(MSGpkt->hdr.status); 134 | LREP("NwkState=%d\r\n", zclApp_NwkState); 135 | if (zclApp_NwkState == DEV_END_DEVICE) { 136 | HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF); 137 | } 138 | break; 139 | 140 | case ZCL_INCOMING_MSG: 141 | zclCommissioning_ProcessIncomingMsg((zclIncomingMsg_t *)MSGpkt); 142 | break; 143 | 144 | default: 145 | break; 146 | } 147 | 148 | // Release the memory 149 | osal_msg_deallocate((uint8 *)MSGpkt); 150 | } 151 | 152 | // return unprocessed events 153 | return (events ^ SYS_EVENT_MSG); 154 | } 155 | if (events & APP_COMMISSIONING_END_DEVICE_REJOIN_EVT) { 156 | LREPMaster("APP_END_DEVICE_REJOIN_EVT\r\n"); 157 | #if ZG_BUILD_ENDDEVICE_TYPE 158 | bdb_ZedAttemptRecoverNwk(); 159 | // for sleeping after changing parent 160 | osal_start_timerEx(zclCommissioning_TaskId, APP_COMMISSIONING_CLOCK_DOWN_POLING_RATE_EVT, 10 * 1000); 161 | #endif 162 | return (events ^ APP_COMMISSIONING_END_DEVICE_REJOIN_EVT); 163 | } 164 | 165 | if (events & APP_COMMISSIONING_CLOCK_DOWN_POLING_RATE_EVT) { 166 | LREPMaster("APP_CLOCK_DOWN_POLING_RATE_EVT\r\n"); 167 | zclCommissioning_Sleep(true); 168 | return (events ^ APP_COMMISSIONING_CLOCK_DOWN_POLING_RATE_EVT); 169 | } 170 | 171 | // Discard unknown events 172 | return 0; 173 | } 174 | 175 | static void zclCommissioning_BindNotification(bdbBindNotificationData_t *data) { 176 | HalLedSet(HAL_LED_1, HAL_LED_MODE_BLINK); 177 | LREP("Recieved bind request clusterId=0x%X dstAddr=0x%X ep=%d\r\n", data->clusterId, data->dstAddr, data->ep); 178 | uint16 maxEntries = 0, usedEntries = 0; 179 | bindCapacity(&maxEntries, &usedEntries); 180 | LREP("bindCapacity %d %usedEntries %d \r\n", maxEntries, usedEntries); 181 | } 182 | 183 | void zclCommissioning_HandleKeys(uint8 portAndAction, uint8 keyCode) { 184 | if (portAndAction & HAL_KEY_PRESS) { 185 | #if ZG_BUILD_ENDDEVICE_TYPE 186 | if (devState == DEV_NWK_ORPHAN) { 187 | LREP("devState=%d try to restore network\r\n", devState); 188 | bdb_ZedAttemptRecoverNwk(); 189 | } 190 | #endif 191 | } 192 | #if defined(POWER_SAVING) 193 | NLME_SetPollRate(1); 194 | #endif 195 | } -------------------------------------------------------------------------------- /zstack-lib/commissioning.h: -------------------------------------------------------------------------------- 1 | #ifndef commissioning_h 2 | #define commissioning_h 3 | 4 | #define APP_COMMISSIONING_CLOCK_DOWN_POLING_RATE_EVT 0x0001 5 | #define APP_COMMISSIONING_END_DEVICE_REJOIN_EVT 0x0002 6 | 7 | #define APP_COMMISSIONING_END_DEVICE_REJOIN_MAX_DELAY ((uint32)1800000) // 30 minutes 30 * 60 * 1000 8 | #define APP_COMMISSIONING_END_DEVICE_REJOIN_START_DELAY 10 * 1000 // 10 seconds 9 | #define APP_COMMISSIONING_END_DEVICE_REJOIN_BACKOFF ((float) 1.2) 10 | #define APP_COMMISSIONING_END_DEVICE_REJOIN_TRIES 20 11 | 12 | 13 | 14 | 15 | extern void zclCommissioning_Init(uint8 task_id); 16 | extern uint16 zclCommissioning_event_loop(uint8 task_id, uint16 events); 17 | extern void zclCommissioning_Sleep( uint8 allow ); 18 | extern void zclCommissioning_HandleKeys(uint8 portAndAction, uint8 keyCode); 19 | 20 | #endif -------------------------------------------------------------------------------- /zstack-lib/ds18b20.c: -------------------------------------------------------------------------------- 1 | #include "ds18b20.h" 2 | #include "OnBoard.h" 3 | 4 | #define DS18B20_SKIP_ROM 0xCC 5 | #define DS18B20_CONVERT_T 0x44 6 | #define DS18B20_READ_SCRATCHPAD 0xBE 7 | #define DS18B20_WRITE_SCRATCHPAD 0x4E 8 | 9 | // Device resolution 10 | #define DS18B20_TEMP_9_BIT 0x1F // 9 bit 11 | #define DS18B20_TEMP_10_BIT 0x3F // 10 bit 12 | #define DS18B20_TEMP_11_BIT 0x5F // 11 bit 13 | #define DS18B20_TEMP_12_BIT 0x7F // 12 bit 14 | 15 | #ifndef DS18B20_RESOLUTION 16 | #define DS18B20_RESOLUTION DS18B20_TEMP_10_BIT 17 | #endif 18 | 19 | #ifndef DS18B20_RETRY_COUNT 20 | #define DS18B20_RETRY_COUNT 10 21 | #endif 22 | 23 | #define MAX_CONVERSION_TIME (750 * 1.2) // ms 750ms + some overhead 24 | 25 | #define DS18B20_RETRY_DELAY ((uint16) (MAX_CONVERSION_TIME / DS18B20_RETRY_COUNT)) 26 | 27 | static void _delay_us(uint16); 28 | static void _delay_ms(uint16); 29 | static void ds18b20_send(uint8); 30 | static uint8 ds18b20_read(void); 31 | static void ds18b20_send_byte(int8); 32 | static uint8 ds18b20_read_byte(void); 33 | static uint8 ds18b20_Reset(void); 34 | static void ds18b20_GroudPins(void); 35 | static void ds18b20_setResolution(uint8 resolution); 36 | static int16 ds18b20_convertTemperature(uint8 temp1, uint8 temp2, uint8 resolution); 37 | 38 | static void _delay_us(uint16 microSecs) { 39 | MicroWait(microSecs); 40 | } 41 | 42 | static void _delay_ms(uint16 milliSecs) { 43 | while (milliSecs--) { 44 | _delay_us(1000); 45 | } 46 | } 47 | 48 | // Sends one bit to bus 49 | static void ds18b20_send(uint8 bit) { 50 | TSENS_SBIT = 1; 51 | TSENS_DIR |= TSENS_BV; // output 52 | TSENS_SBIT = 0; 53 | if (bit != 0) 54 | _delay_us(8); 55 | else 56 | _delay_us(80); 57 | TSENS_SBIT = 1; 58 | if (bit != 0) 59 | _delay_us(80); 60 | else 61 | _delay_us(2); 62 | // TSENS_SBIT = 1; 63 | } 64 | 65 | // Reads one bit from bus 66 | static uint8 ds18b20_read(void) { 67 | TSENS_SBIT = 1; 68 | TSENS_DIR |= TSENS_BV; // output 69 | TSENS_SBIT = 0; 70 | _delay_us(2); 71 | // TSENS_SBIT = 1; 72 | //_delay_us(15); 73 | TSENS_DIR &= ~TSENS_BV; // input 74 | _delay_us(5); 75 | uint8 i = TSENS_SBIT; 76 | _delay_us(60); 77 | return i; 78 | } 79 | 80 | // Sends one byte to bus 81 | static void ds18b20_send_byte(int8 data) { 82 | uint8 i, x; 83 | for (i = 0; i < 8; i++) { 84 | x = data >> i; 85 | x &= 0x01; 86 | ds18b20_send(x); 87 | } 88 | //_delay_us(100); 89 | } 90 | 91 | // Reads one byte from bus 92 | static uint8 ds18b20_read_byte(void) { 93 | uint8 i; 94 | uint8 data = 0; 95 | for (i = 0; i < 8; i++) { 96 | if (ds18b20_read()) 97 | data |= 0x01 << i; 98 | //_delay_us(25); 99 | } 100 | return (data); 101 | } 102 | 103 | // Sends reset pulse 104 | static uint8 ds18b20_Reset(void) { 105 | TSENS_SBIT = 0; 106 | TSENS_DIR |= TSENS_BV; // output 107 | _delay_us(600); 108 | TSENS_DIR &= ~TSENS_BV; // input 109 | _delay_us(70); 110 | uint8 i = TSENS_SBIT; 111 | _delay_us(200); 112 | TSENS_SBIT = 1; 113 | TSENS_DIR |= TSENS_BV; // output 114 | _delay_us(600); 115 | return i; 116 | } 117 | 118 | static void ds18b20_GroudPins(void) { 119 | // TSENS_SBIT = 0; 120 | TSENS_DIR &= ~TSENS_BV; // input 121 | } 122 | 123 | static void ds18b20_setResolution(uint8 resolution) { 124 | ds18b20_Reset(); 125 | ds18b20_send_byte(DS18B20_SKIP_ROM); 126 | ds18b20_send_byte(DS18B20_WRITE_SCRATCHPAD); 127 | // two dummy values for LOW & HIGH ALARM 128 | ds18b20_send_byte(0); 129 | ds18b20_send_byte(100); 130 | ds18b20_send_byte(resolution); 131 | ds18b20_Reset(); 132 | } 133 | static int16 ds18b20_convertTemperature(uint8 temp1, uint8 temp2, uint8 resolution) { 134 | float temperature = 0; 135 | uint8 ignoreMask = 0; 136 | switch (resolution) { 137 | case DS18B20_TEMP_9_BIT: 138 | ignoreMask = (BV(0) | BV(1) | BV(2)); 139 | break; 140 | 141 | case DS18B20_TEMP_10_BIT: 142 | ignoreMask = (BV(0) | BV(1)); 143 | break; 144 | 145 | case DS18B20_TEMP_11_BIT: 146 | ignoreMask = (BV(0)); 147 | break; 148 | 149 | case DS18B20_TEMP_12_BIT: 150 | ignoreMask = 0; 151 | break; 152 | 153 | default: 154 | break; 155 | } 156 | temperature = (uint16)temp1 | (uint16)(ignoreMask ? temp2 & ignoreMask : temp2) << 8; 157 | // neg. temp 158 | if (temp2 & (BV(3))) { 159 | temperature = temperature / 16.0 - 128.0; 160 | } 161 | // pos. temp 162 | else { 163 | temperature = temperature / 16.0; 164 | } 165 | return (int16)(temperature * 100); 166 | } 167 | 168 | int16 readTemperature(void) { 169 | 170 | uint8 temp1, temp2, retry_count = DS18B20_RETRY_COUNT; 171 | ds18b20_setResolution(DS18B20_RESOLUTION); 172 | ds18b20_Reset(); 173 | 174 | ds18b20_send_byte(DS18B20_SKIP_ROM); 175 | ds18b20_send_byte(DS18B20_CONVERT_T); 176 | 177 | while (retry_count) { 178 | _delay_ms(DS18B20_RETRY_DELAY); 179 | ds18b20_Reset(); 180 | ds18b20_send_byte(DS18B20_SKIP_ROM); 181 | ds18b20_send_byte(DS18B20_READ_SCRATCHPAD); 182 | temp1 = ds18b20_read_byte(); 183 | temp2 = ds18b20_read_byte(); 184 | ds18b20_Reset(); 185 | 186 | if (temp1 == 0xff && temp2 == 0xff) { 187 | // No sensor found. 188 | ds18b20_GroudPins(); 189 | return 1; 190 | } 191 | if (temp1 == 0x50 && temp2 == 0x05) { 192 | // Power-up State, not ready yet 193 | retry_count--; 194 | continue; 195 | } 196 | 197 | ds18b20_GroudPins(); 198 | return ds18b20_convertTemperature(temp1, temp2, DS18B20_RESOLUTION); 199 | } 200 | 201 | ds18b20_GroudPins(); 202 | return 1; 203 | } -------------------------------------------------------------------------------- /zstack-lib/ds18b20.h: -------------------------------------------------------------------------------- 1 | #ifndef ds18b20_h 2 | int16 readTemperature(void); 3 | #define ds18b20_h 4 | #endif 5 | -------------------------------------------------------------------------------- /zstack-lib/f8wConfig.cfg: -------------------------------------------------------------------------------- 1 | /* 2 | * f8wConfig.cfg 3 | * 4 | * Compiler command-line options used to define a TI Z-Stack ZigBee device. 5 | * To move an option from here to the project file, comment out or delete the 6 | * option from this file and enter it into the "Define Symbols" box under the 7 | * Preprocessor tab of the C/C++ Compiler Project Options. New user defined 8 | * options may be added to this file, as necessary. 9 | * 10 | * Each macro is prefixed with '-D'. The entries are to be constructed as if 11 | * they are to be on the compiler command line invocation (which they are). 12 | * 13 | * NOTE: The RHS (Right-Hand-Side) must be quoted if there are embedded blanks. 14 | * See the DEFAULT_KEY definition for an example. 15 | */ 16 | 17 | /* Enable ZigBee-Pro */ 18 | -DZIGBEEPRO 19 | 20 | /* Set to 1 to enable security. To disable set to 0 */ 21 | -DSECURE=1 22 | -DZG_SECURE_DYNAMIC=0 23 | 24 | /* Enable the Reflector */ 25 | -DREFLECTOR 26 | 27 | /* Default channel is Channel 11 - 0x0B */ 28 | // Channels are defined in the following: 29 | // 0 : 868 MHz 0x00000001 30 | // 1 - 10 : 915 MHz 0x000007FE 31 | // 11 - 26 : 2.4 GHz 0x07FFF800 32 | // 33 | //-DMAX_CHANNELS_868MHZ 0x00000001 34 | //-DMAX_CHANNELS_915MHZ 0x000007FE 35 | //-DMAX_CHANNELS_24GHZ 0x07FFF800 36 | //-DDEFAULT_CHANLIST=0x04000000 // 26 - 0x1A 37 | //-DDEFAULT_CHANLIST=0x02000000 // 25 - 0x19 38 | //-DDEFAULT_CHANLIST=0x01000000 // 24 - 0x18 39 | //-DDEFAULT_CHANLIST=0x00800000 // 23 - 0x17 40 | //-DDEFAULT_CHANLIST=0x00400000 // 22 - 0x16 41 | //-DDEFAULT_CHANLIST=0x00200000 // 21 - 0x15 42 | //-DDEFAULT_CHANLIST=0x00100000 // 20 - 0x14 43 | //-DDEFAULT_CHANLIST=0x00080000 // 19 - 0x13 44 | //-DDEFAULT_CHANLIST=0x00040000 // 18 - 0x12 45 | //-DDEFAULT_CHANLIST=0x00020000 // 17 - 0x11 46 | //-DDEFAULT_CHANLIST=0x00010000 // 16 - 0x10 47 | //-DDEFAULT_CHANLIST=0x00008000 // 15 - 0x0F 48 | //-DDEFAULT_CHANLIST=0x00004000 // 14 - 0x0E 49 | //-DDEFAULT_CHANLIST=0x00002000 // 13 - 0x0D 50 | //-DDEFAULT_CHANLIST=0x00001000 // 12 - 0x0C 51 | -DDEFAULT_CHANLIST=0x07FFF800 // ALL channels 52 | 53 | /* Define the default PAN ID. 54 | * 55 | * Setting this to a value other than 0xFFFF causes 56 | * ZDO_COORD to use this value as its PAN ID and 57 | * Routers and end devices to join PAN with this ID 58 | */ 59 | -DZDAPP_CONFIG_PAN_ID=0xFFFF 60 | 61 | /* Minimum number of milliseconds to hold off the start of the device 62 | * in the network and the minimum delay between joining cycles. 63 | */ 64 | -DNWK_START_DELAY=100 65 | 66 | /* Mask for the random joining delay. This value is masked with 67 | * the return from osal_rand() to get a random delay time for 68 | * each joining cycle. This random value is added to NWK_START_DELAY. 69 | * For example, a value of 0x007F will be a joining delay of 0 to 127 70 | * milliseconds. 71 | */ 72 | -DEXTENDED_JOINING_RANDOM_MASK=0x007F 73 | 74 | /* Minimum number of milliseconds to delay between each beacon request 75 | * in a joining cycle. 76 | */ 77 | -DBEACON_REQUEST_DELAY=100 78 | 79 | /* Mask for the random beacon request delay. This value is masked with the 80 | * return from osal_rand() to get a random delay time for each joining cycle. 81 | * This random value is added to DBEACON_REQUEST_DELAY. For example, a value 82 | * of 0x00FF will be a beacon request delay of 0 to 255 milliseconds. 83 | */ 84 | -DBEACON_REQ_DELAY_MASK=0x00FF 85 | 86 | /* Jitter mask for the link status report timer. This value is masked with the 87 | * return from osal_rand() to add a random delay to _NIB.nwkLinkStatusPeriod. 88 | * For example, a value of 0x007F allows a jitter between 0-127 milliseconds. 89 | */ 90 | -DLINK_STATUS_JITTER_MASK=0x007F 91 | 92 | /* in seconds; set to 0 to turn off route expiry */ 93 | -DROUTE_EXPIRY_TIME=30 94 | 95 | /* This number is used by polled devices, since the spec'd formula 96 | * doesn't work for sleeping end devices. For non-polled devices, 97 | * a formula is used. Value is in 2 milliseconds periods 98 | */ 99 | -DAPSC_ACK_WAIT_DURATION_POLLED=3000 100 | 101 | /* Default indirect message holding timeout value: 102 | * 1-65535 (0 -> 65536) X CNT_RTG_TIMER X RTG_TIMER_INTERVAL 103 | */ 104 | -DNWK_INDIRECT_MSG_TIMEOUT=7 105 | 106 | /* The number of simultaneous route discoveries in network */ 107 | -DMAX_RREQ_ENTRIES=8 108 | 109 | /* The maximum number of retries allowed after a transmission failure */ 110 | -DAPSC_MAX_FRAME_RETRIES=3 111 | 112 | /* Max number of times retry looking for the next hop address of a message */ 113 | -DNWK_MAX_DATA_RETRIES=2 114 | 115 | /* Number of times retry to poll parent before indicating loss of synchronization 116 | * with parent. Note that larger value will cause longer delay for the child to 117 | * rejoin the network. 118 | */ 119 | -DMAX_POLL_FAILURE_RETRIES=2 120 | 121 | /* The number of items in the broadcast table */ 122 | -DMAX_BCAST=9 123 | 124 | /* The maximum number of groups in the groups table */ 125 | -DAPS_MAX_GROUPS=16 126 | 127 | /* Number of entries in the regular routing table plus additional 128 | * entries for route repair 129 | */ 130 | -DMAX_RTG_ENTRIES=40 131 | 132 | /* Maximum number of entries in the Binding table. */ 133 | -DNWK_MAX_BINDING_ENTRIES=8 134 | 135 | /* Maximum number of cluster IDs for each binding table entry. 136 | * Note that any value other than the default value may cause a 137 | * compilation warning but Device Binding will function correctly. 138 | */ 139 | -DMAX_BINDING_CLUSTER_IDS=15 140 | 141 | /* Default security key. */ 142 | -DDEFAULT_KEY="{0}" 143 | 144 | /* Reset when ASSERT occurs, otherwise flash LEDs */ 145 | //-DASSERT_RESET 146 | 147 | /* Set the MAC MAX Frame Size (802.15.4 default is 102) */ 148 | -DMAC_MAX_FRAME_SIZE=116 149 | 150 | /* Minimum transmissions attempted for Channel Interference detection, 151 | * Frequency Agility can be disabled by setting this parameter to zero. 152 | */ 153 | -DZDNWKMGR_MIN_TRANSMISSIONS=20 154 | 155 | /* Compiler keywords */ 156 | -DCONST="const __code" 157 | -DGENERIC=__generic 158 | 159 | /**************************************** 160 | * The following are for End Devices only 161 | ***************************************/ 162 | 163 | -DRFD_RCVC_ALWAYS_ON=FALSE 164 | 165 | /* The number of milliseconds to wait between data request polls to the coordinator. */ 166 | //-DPOLL_RATE=0 167 | -DPOLL_RATE=1000 168 | 169 | /* This is used after receiving a data indication to poll immediately 170 | * for queued messages...in milliseconds. 171 | */ 172 | //-DQUEUED_POLL_RATE=0 173 | -DQUEUED_POLL_RATE=100 174 | 175 | /* This is used after receiving a data confirmation to poll immediately 176 | * for response messages...in milliseconds 177 | */ 178 | //-DRESPONSE_POLL_RATE=0 179 | -DRESPONSE_POLL_RATE=100 180 | 181 | /* This is used as an alternate response poll rate only for rejoin request. 182 | * This rate is determined by the response time of the parent that the device 183 | * is trying to join. 184 | */ 185 | -DREJOIN_POLL_RATE=440 186 | 187 | /* Rejoin retry backoff silent period timer duration in milliseconds - default 15 minutes according to HA test spec */ 188 | -DREJOIN_BACKOFF=900000 189 | 190 | /* Rejoin retry backoff scan timer duration in milliseconds - default 15 minutes according to HA test spec */ 191 | -DREJOIN_SCAN=900000 192 | 193 | /* Latest sample apps use LED4 and do not use S1 switch */ 194 | -DENABLE_LED4_DISABLE_S1 -------------------------------------------------------------------------------- /zstack-lib/factory_reset.c: -------------------------------------------------------------------------------- 1 | #include "factory_reset.h" 2 | #include "AF.h" 3 | #include "Debug.h" 4 | #include "OnBoard.h" 5 | #include "bdb.h" 6 | #include "bdb_interface.h" 7 | #include "hal_led.h" 8 | #include "ZComDef.h" 9 | #include "hal_key.h" 10 | 11 | static void zclFactoryResetter_ResetToFN(void); 12 | static void zclFactoryResetter_ProcessBootCounter(void); 13 | static void zclFactoryResetter_ResetBootCounter(void); 14 | 15 | static uint8 zclFactoryResetter_TaskID; 16 | 17 | uint16 zclFactoryResetter_loop(uint8 task_id, uint16 events) { 18 | LREP("zclFactoryResetter_loop 0x%X\r\n", events); 19 | if (events & FACTORY_RESET_EVT) { 20 | LREPMaster("FACTORY_RESET_EVT\r\n"); 21 | zclFactoryResetter_ResetToFN(); 22 | return (events ^ FACTORY_RESET_EVT); 23 | } 24 | 25 | if (events & FACTORY_BOOTCOUNTER_RESET_EVT) { 26 | LREPMaster("FACTORY_BOOTCOUNTER_RESET_EVT\r\n"); 27 | zclFactoryResetter_ResetBootCounter(); 28 | return (events ^ FACTORY_BOOTCOUNTER_RESET_EVT); 29 | } 30 | return 0; 31 | } 32 | void zclFactoryResetter_ResetBootCounter(void) { 33 | uint16 bootCnt = 0; 34 | LREPMaster("Clear boot counter\r\n"); 35 | osal_nv_write(ZCD_NV_BOOTCOUNTER, 0, sizeof(bootCnt), &bootCnt); 36 | } 37 | 38 | void zclFactoryResetter_Init(uint8 task_id) { 39 | zclFactoryResetter_TaskID = task_id; 40 | /** 41 | * We can't register more than one task, call in main app taks 42 | * zclFactoryResetter_HandleKeys(portAndAction, keyCode); 43 | * */ 44 | // RegisterForKeys(task_id); 45 | #if FACTORY_RESET_BY_BOOT_COUNTER 46 | zclFactoryResetter_ProcessBootCounter(); 47 | #endif 48 | } 49 | 50 | void zclFactoryResetter_ResetToFN(void) { 51 | HalLedSet(HAL_LED_1, HAL_LED_MODE_FLASH); 52 | LREP("bdbAttributes.bdbNodeIsOnANetwork=%d bdbAttributes.bdbCommissioningMode=0x%X\r\n", bdbAttributes.bdbNodeIsOnANetwork, bdbAttributes.bdbCommissioningMode); 53 | LREPMaster("zclFactoryResetter: Reset to FN\r\n"); 54 | bdb_resetLocalAction(); 55 | } 56 | 57 | void zclFactoryResetter_HandleKeys(uint8 portAndAction, uint8 keyCode) { 58 | #if FACTORY_RESET_BY_LONG_PRESS 59 | if (portAndAction & HAL_KEY_RELEASE) { 60 | LREPMaster("zclFactoryResetter: Key release\r\n"); 61 | osal_stop_timerEx(zclFactoryResetter_TaskID, FACTORY_RESET_EVT); 62 | } else { 63 | LREPMaster("zclFactoryResetter: Key press\r\n"); 64 | bool statTimer = true; 65 | #if FACTORY_RESET_BY_LONG_PRESS_PORT 66 | statTimer = FACTORY_RESET_BY_LONG_PRESS_PORT & portAndAction; 67 | #endif 68 | LREP("zclFactoryResetter statTimer hold timer %d\r\n", statTimer); 69 | if (statTimer) { 70 | uint32 timeout = bdbAttributes.bdbNodeIsOnANetwork ? FACTORY_RESET_HOLD_TIME_LONG : FACTORY_RESET_HOLD_TIME_FAST; 71 | osal_start_timerEx(zclFactoryResetter_TaskID, FACTORY_RESET_EVT, timeout); 72 | } 73 | } 74 | #endif 75 | } 76 | 77 | void zclFactoryResetter_ProcessBootCounter(void) { 78 | LREPMaster("zclFactoryResetter_ProcessBootCounter\r\n"); 79 | osal_start_timerEx(zclFactoryResetter_TaskID, FACTORY_BOOTCOUNTER_RESET_EVT, FACTORY_RESET_BOOTCOUNTER_RESET_TIME); 80 | 81 | uint16 bootCnt = 0; 82 | if (osal_nv_item_init(ZCD_NV_BOOTCOUNTER, sizeof(bootCnt), &bootCnt) == ZSUCCESS) { 83 | osal_nv_read(ZCD_NV_BOOTCOUNTER, 0, sizeof(bootCnt), &bootCnt); 84 | } 85 | LREP("bootCnt %d\r\n", bootCnt); 86 | bootCnt += 1; 87 | if (bootCnt >= FACTORY_RESET_BOOTCOUNTER_MAX_VALUE) { 88 | LREP("bootCnt =%d greater than, ressetting %d\r\n", bootCnt, FACTORY_RESET_BOOTCOUNTER_MAX_VALUE); 89 | bootCnt = 0; 90 | osal_stop_timerEx(zclFactoryResetter_TaskID, FACTORY_BOOTCOUNTER_RESET_EVT); 91 | osal_start_timerEx(zclFactoryResetter_TaskID, FACTORY_RESET_EVT, 5000); 92 | } 93 | osal_nv_write(ZCD_NV_BOOTCOUNTER, 0, sizeof(bootCnt), &bootCnt); 94 | } -------------------------------------------------------------------------------- /zstack-lib/factory_reset.h: -------------------------------------------------------------------------------- 1 | #ifndef FACTORY_RESET_H 2 | #define FACTORY_RESET_H 3 | 4 | #define FACTORY_RESET_EVT 0x1000 5 | #define FACTORY_BOOTCOUNTER_RESET_EVT 0x2000 6 | 7 | #ifndef FACTORY_RESET_HOLD_TIME_LONG 8 | #define FACTORY_RESET_HOLD_TIME_LONG ((uint32)10 * 1000) 9 | #endif 10 | 11 | #ifndef FACTORY_RESET_HOLD_TIME_FAST 12 | #define FACTORY_RESET_HOLD_TIME_FAST 1000 13 | #endif 14 | 15 | #ifndef FACTORY_RESET_BOOTCOUNTER_MAX_VALUE 16 | #define FACTORY_RESET_BOOTCOUNTER_MAX_VALUE 5 17 | #endif 18 | 19 | #ifndef FACTORY_RESET_BOOTCOUNTER_RESET_TIME 20 | #define FACTORY_RESET_BOOTCOUNTER_RESET_TIME 10 * 1000 21 | #endif 22 | 23 | #ifndef FACTORY_RESET_BY_LONG_PRESS 24 | #define FACTORY_RESET_BY_LONG_PRESS TRUE 25 | #endif 26 | 27 | 28 | #ifndef FACTORY_RESET_BY_LONG_PRESS_PORT 29 | #define FACTORY_RESET_BY_LONG_PRESS_PORT 0x00 30 | #endif 31 | 32 | 33 | #ifndef FACTORY_RESET_BY_BOOT_COUNTER 34 | #define FACTORY_RESET_BY_BOOT_COUNTER TRUE 35 | #endif 36 | 37 | extern void zclFactoryResetter_Init(uint8 task_id); 38 | extern uint16 zclFactoryResetter_loop(uint8 task_id, uint16 events); 39 | extern void zclFactoryResetter_HandleKeys(uint8 portAndAction, uint8 keyCode); 40 | #endif -------------------------------------------------------------------------------- /zstack-lib/hal_i2c.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************************** 2 | Filename: hal_i2c.h 3 | Revised: $Date: 2009-01-20 06:41:30 -0800 (Tue, 20 Jan 2009) $ 4 | Revision: $Revision: 18809 $ 5 | 6 | Description: Interface for I2C driver. 7 | 8 | 9 | Copyright 2006 - 2008 Texas Instruments Incorporated. All rights reserved. 10 | 11 | IMPORTANT: Your use of this Software is limited to those specific rights 12 | granted under the terms of a software license agreement between the user 13 | who downloaded the software, his/her employer (which must be your employer) 14 | and Texas Instruments Incorporated (the "License"). You may not use this 15 | Software unless you agree to abide by the terms of the License. The License 16 | limits your use, and you acknowledge, that the Software may not be modified, 17 | copied or distributed unless embedded on a Texas Instruments microcontroller 18 | or used solely and exclusively in conjunction with a Texas Instruments radio 19 | frequency transceiver, which is integrated into your product. Other than for 20 | the foregoing purpose, you may not use, reproduce, copy, prepare derivative 21 | works of, modify, distribute, perform, display or sell this Software and/or 22 | its documentation for any purpose. 23 | 24 | YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE 25 | PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, 26 | INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, 27 | NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL 28 | TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, 29 | NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER 30 | LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES 31 | INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE 32 | OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT 33 | OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES 34 | (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. 35 | 36 | Should you have any questions regarding your right to use this Software, 37 | contact Texas Instruments Incorporated at www.TI.com. 38 | **************************************************************************************************/ 39 | 40 | #ifndef HAL_I2C_H 41 | #define HAL_I2C_H 42 | 43 | 44 | #define I2C_ERROR 1 45 | #define I2C_SUCCESS 0 46 | 47 | #define OCM_READ (0x01) 48 | #define OCM_WRITE (0x00) 49 | 50 | /********************************************************************* 51 | * @fn HalI2CInit 52 | * @brief Initializes two-wire serial I/O bus 53 | * @param void 54 | * @return void 55 | */ 56 | void HalI2CInit( void ); 57 | 58 | /********************************************************************* 59 | * @fn HALI2CReceive 60 | * @brief Receives data into a buffer from an I2C slave device 61 | * @param address: address of the slave device 62 | * @param buf: target array for read characters 63 | * @param len: max number of characters to read 64 | * @return zero when successful. 65 | */ 66 | int8 HalI2CReceive(uint8 address, uint8 *buf, uint16 len); 67 | 68 | /********************************************************************* 69 | * @fn HALI2CSend 70 | * @brief Sends buffer contents to an I2C slave device 71 | * @param address: address of the slave device 72 | * @param buf - ptr to buffered data to send 73 | * @param len - number of bytes in buffer 74 | * @return zero when successful. 75 | */ 76 | int8 HalI2CSend(uint8 address, uint8 *buf, uint16 len); 77 | 78 | 79 | 80 | int8 I2C_ReadMultByte( uint8 address, uint8 reg, uint8 *buffer, uint16 len ); 81 | int8 I2C_WriteMultByte( uint8 address, uint8 reg, uint8 *buffer, uint16 len ); 82 | #endif 83 | -------------------------------------------------------------------------------- /zstack-lib/hal_key.c: -------------------------------------------------------------------------------- 1 | /************************************************************************************************** 2 | * INCLUDES 3 | **************************************************************************************************/ 4 | #include "hal_key.h" 5 | #include "Debug.h" 6 | #include "OnBoard.h" 7 | #include "utils.h" 8 | 9 | #include "hal_adc.h" 10 | #include "hal_defs.h" 11 | #include "hal_drivers.h" 12 | #include "hal_led.h" 13 | #include "hal_mcu.h" 14 | #include "hal_types.h" 15 | #include "osal.h" 16 | 17 | /************************************************************************************************** 18 | * MACROS 19 | **************************************************************************************************/ 20 | 21 | #ifndef HAL_KEY_P0_INPUT_PINS 22 | #define HAL_KEY_P0_INPUT_PINS 0x00 23 | #endif 24 | 25 | #ifndef HAL_KEY_P1_INPUT_PINS 26 | #define HAL_KEY_P1_INPUT_PINS 0x00 27 | #endif 28 | 29 | #ifndef HAL_KEY_P2_INPUT_PINS 30 | #define HAL_KEY_P2_INPUT_PINS 0x00 31 | #endif 32 | 33 | 34 | #ifndef HAL_KEY_P0_INPUT_PINS_EDGE 35 | #define HAL_KEY_P0_INPUT_PINS_EDGE HAL_KEY_FALLING_EDGE 36 | #endif 37 | 38 | #ifndef HAL_KEY_P1_INPUT_PINS_EDGE 39 | #define HAL_KEY_P1_INPUT_PINS_EDGE HAL_KEY_FALLING_EDGE 40 | #endif 41 | 42 | #ifndef HAL_KEY_P2_INPUT_PINS_EDGE 43 | #define HAL_KEY_P2_INPUT_PINS_EDGE HAL_KEY_FALLING_EDGE 44 | #endif 45 | /************************************************************************************************** 46 | * CONSTANTS 47 | **************************************************************************************************/ 48 | 49 | uint8 portNum = 0; 50 | uint8 pinNum = 0; 51 | 52 | #define HAL_KEY_DEBOUNCE_VALUE 25 53 | 54 | #define HAL_KEY_P0_EDGE_BITS HAL_KEY_BIT0 55 | #define HAL_KEY_P1_EDGE_BITS (HAL_KEY_BIT1 | HAL_KEY_BIT2) 56 | #define HAL_KEY_P2_EDGE_BITS HAL_KEY_BIT3 57 | 58 | /************************************************************************************************** 59 | * TYPEDEFS 60 | **************************************************************************************************/ 61 | 62 | /************************************************************************************************** 63 | * GLOBAL VARIABLES 64 | **************************************************************************************************/ 65 | bool Hal_KeyIntEnable; 66 | /************************************************************************************************** 67 | * FUNCTIONS - Local 68 | **************************************************************************************************/ 69 | void halProcessKeyInterrupt(uint8 portNum); 70 | 71 | void HalKeyPoll(void) { 72 | uint8 pinStatus = 0; 73 | bool isPressed = false; 74 | switch (portNum) { 75 | case HAL_KEY_PORT0: 76 | PICTL ^= HAL_KEY_P0_EDGE_BITS; // flip edge bit 77 | pinStatus = P0 & pinNum; 78 | isPressed = HAL_KEY_P0_INPUT_PINS_EDGE != !!(pinStatus); 79 | break; 80 | 81 | case HAL_KEY_PORT1: 82 | PICTL ^= HAL_KEY_P1_EDGE_BITS; // flip edge bit 83 | pinStatus = P1 & pinNum; 84 | isPressed = HAL_KEY_P1_INPUT_PINS_EDGE != !!(pinStatus); 85 | break; 86 | 87 | case HAL_KEY_PORT2: 88 | PICTL ^= HAL_KEY_P2_EDGE_BITS; // flip edge bit 89 | pinStatus = P2 & pinNum; 90 | isPressed = HAL_KEY_P2_INPUT_PINS_EDGE != !!(pinStatus); 91 | break; 92 | 93 | default: 94 | break; 95 | } 96 | LREP("portNum=0x%X pinNum=0x%X isPressed=%d\r\n", portNum, pinNum, isPressed); 97 | 98 | // LREP("pinStatus=" BYTE_TO_BINARY_PATTERN "\r\n", BYTE_TO_BINARY(pinStatus)); 99 | OnBoard_SendKeys(pinNum, (isPressed ? HAL_KEY_PRESS : HAL_KEY_RELEASE) | portNum); 100 | } 101 | 102 | void HalKeyInit(void) { 103 | #if HAL_KEY_P0_INPUT_PINS 104 | P0SEL &= ~HAL_KEY_P0_INPUT_PINS; 105 | P0DIR &= ~(HAL_KEY_P0_INPUT_PINS); 106 | #endif 107 | 108 | #if HAL_KEY_P1_INPUT_PINS 109 | P1SEL &= ~HAL_KEY_P1_INPUT_PINS; 110 | P1DIR &= ~(HAL_KEY_P1_INPUT_PINS); 111 | #endif 112 | 113 | #if HAL_KEY_P2_INPUT_PINS 114 | P2SEL &= ~HAL_KEY_P2_INPUT_PINS; 115 | P2DIR &= ~(HAL_KEY_P2_INPUT_PINS); 116 | #endif 117 | 118 | } 119 | 120 | void HalKeyConfig(bool interruptEnable, halKeyCBack_t cback) { 121 | Hal_KeyIntEnable = true; 122 | 123 | #if HAL_KEY_P0_INPUT_PINS 124 | P0IEN |= HAL_KEY_P0_INPUT_PINS; 125 | IEN1 |= HAL_KEY_BIT5; // enable port0 int 126 | P0INP &= ~HAL_KEY_P0_INPUT_PINS; // Pullup/pulldown 127 | #if (HAL_KEY_P0_INPUT_PINS_EDGE == HAL_KEY_FALLING_EDGE) 128 | // P2INP &= ~HAL_KEY_BIT5; // pull up 129 | // MicroWait(50); 130 | // PICTL |= HAL_KEY_P0_EDGE_BITS; // set falling edge on port 131 | #else 132 | // P2INP |= HAL_KEY_BIT5; // pull down 133 | // MicroWait(50); 134 | // PICTL &= ~(HAL_KEY_P0_EDGE_BITS); 135 | #endif 136 | 137 | #endif 138 | 139 | #if HAL_KEY_P1_INPUT_PINS 140 | P1IEN |= HAL_KEY_P1_INPUT_PINS; 141 | IEN2 |= HAL_KEY_BIT4; // enable port1 int 142 | P1INP &= ~HAL_KEY_P1_INPUT_PINS; //Pullup/pulldown 143 | #if (HAL_KEY_P1_INPUT_PINS_EDGE == HAL_KEY_FALLING_EDGE) 144 | // P2INP &= ~HAL_KEY_BIT6; // pull up 145 | // MicroWait(50); 146 | // PICTL |= HAL_KEY_P1_EDGE_BITS; // set falling edge on port 147 | #else 148 | // P2INP |= HAL_KEY_BIT6; // pull down 149 | // MicroWait(50); 150 | // PICTL &= ~HAL_KEY_P1_EDGE_BITS; 151 | #endif 152 | 153 | #endif 154 | 155 | #if HAL_KEY_P2_INPUT_PINS 156 | P2IEN |= HAL_KEY_P2_INPUT_PINS; 157 | IEN2 |= HAL_KEY_BIT1; // enable port2 int 158 | P2INP &= ~HAL_KEY_P2_INPUT_PINS; //Pullup/pulldown 159 | #if (HAL_KEY_P2_INPUT_PINS_EDGE == HAL_KEY_FALLING_EDGE) 160 | P2INP &= ~HAL_KEY_BIT7; // pull up 161 | MicroWait(50); 162 | PICTL |= HAL_KEY_P2_EDGE_BITS; // set falling edge on port 163 | #else 164 | P2INP |= HAL_KEY_BIT7; // pull down 165 | MicroWait(50); 166 | PICTL &= ~HAL_KEY_P2_EDGE_BITS; 167 | #endif 168 | 169 | #endif 170 | } 171 | 172 | void halProcessKeyInterrupt(uint8 _portNum) { 173 | portNum = _portNum; 174 | switch (_portNum) { 175 | case HAL_KEY_PORT0: 176 | pinNum = P0IFG & HAL_KEY_P0_INPUT_PINS; 177 | break; 178 | 179 | case HAL_KEY_PORT1: 180 | pinNum = P1IFG & HAL_KEY_P1_INPUT_PINS; 181 | break; 182 | 183 | case HAL_KEY_PORT2: 184 | pinNum = P2IFG & HAL_KEY_P2_INPUT_PINS; 185 | break; 186 | default: 187 | break; 188 | } 189 | osal_start_timerEx(Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE); 190 | } 191 | 192 | void HalKeyEnterSleep(void) { 193 | uint8 clkcmd = CLKCONCMD; 194 | uint8 clksta = CLKCONSTA; 195 | // Switch to 16MHz before setting the DC/DC to bypass to reduce risk of flash corruption 196 | CLKCONCMD = (CLKCONCMD_16MHZ | OSC_32KHZ); 197 | // wait till clock speed stablizes 198 | while (CLKCONSTA != (CLKCONCMD_16MHZ | OSC_32KHZ)) 199 | ; 200 | 201 | CLKCONCMD = clkcmd; 202 | while (CLKCONSTA != (clksta)) 203 | ; 204 | } 205 | 206 | uint8 HalKeyExitSleep(void) { 207 | uint8 clkcmd = CLKCONCMD; 208 | // Switch to 16MHz before setting the DC/DC to on to reduce risk of flash corruption 209 | CLKCONCMD = (CLKCONCMD_16MHZ | OSC_32KHZ); 210 | // wait till clock speed stablizes 211 | while (CLKCONSTA != (CLKCONCMD_16MHZ | OSC_32KHZ)) 212 | ; 213 | 214 | CLKCONCMD = clkcmd; 215 | 216 | // /* Wake up and read keys */ 217 | return (HalKeyRead()); 218 | } 219 | 220 | #if HAL_KEY_P0_INPUT_PINS 221 | HAL_ISR_FUNCTION(halKeyPort0Isr, P0INT_VECTOR) { 222 | HAL_ENTER_ISR(); 223 | 224 | if (P0IFG & HAL_KEY_P0_INPUT_PINS) { 225 | halProcessKeyInterrupt(HAL_KEY_PORT0); 226 | } 227 | 228 | P0IFG = 0; //&= ~HAL_KEY_P0_INPUT_PINS; 229 | P0IF = 0; 230 | 231 | CLEAR_SLEEP_MODE(); 232 | HAL_EXIT_ISR(); 233 | } 234 | #endif 235 | 236 | #if HAL_KEY_P1_INPUT_PINS 237 | HAL_ISR_FUNCTION(halKeyPort1Isr, P1INT_VECTOR) { 238 | HAL_ENTER_ISR(); 239 | 240 | if (P1IFG & HAL_KEY_P1_INPUT_PINS) { 241 | halProcessKeyInterrupt(HAL_KEY_PORT1); 242 | } 243 | 244 | P1IFG = 0; //&= ~HAL_KEY_P1_INPUT_PINS; 245 | P1IF = 0; 246 | 247 | CLEAR_SLEEP_MODE(); 248 | HAL_EXIT_ISR(); 249 | } 250 | #endif 251 | 252 | #if HAL_KEY_P2_INPUT_PINS 253 | HAL_ISR_FUNCTION(halKeyPort2Isr, P2INT_VECTOR) { 254 | HAL_ENTER_ISR(); 255 | 256 | if (P2IFG & HAL_KEY_P2_INPUT_PINS) { 257 | halProcessKeyInterrupt(HAL_KEY_PORT2); 258 | } 259 | 260 | P2IFG = 0; //&= ~HAL_KEY_P2_INPUT_PINS; 261 | P2IF = 0; 262 | 263 | CLEAR_SLEEP_MODE(); 264 | HAL_EXIT_ISR(); 265 | } 266 | #endif 267 | 268 | 269 | 270 | uint8 HalKeyRead ( void ){ 271 | return 0; 272 | } -------------------------------------------------------------------------------- /zstack-lib/hal_key.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************************** 2 | Filename: hal_key.h 3 | Revised: $Date: 2007-07-06 10:42:24 -0700 (Fri, 06 Jul 2007) $ 4 | Revision: $Revision: 13579 $ 5 | 6 | Description: This file contains the interface to the KEY Service. 7 | 8 | 9 | Copyright 2005-2012 Texas Instruments Incorporated. All rights reserved. 10 | 11 | IMPORTANT: Your use of this Software is limited to those specific rights 12 | granted under the terms of a software license agreement between the user 13 | who downloaded the software, his/her employer (which must be your employer) 14 | and Texas Instruments Incorporated (the "License"). You may not use this 15 | Software unless you agree to abide by the terms of the License. The License 16 | limits your use, and you acknowledge, that the Software may not be modified, 17 | copied or distributed unless embedded on a Texas Instruments microcontroller 18 | or used solely and exclusively in conjunction with a Texas Instruments radio 19 | frequency transceiver, which is integrated into your product. Other than for 20 | the foregoing purpose, you may not use, reproduce, copy, prepare derivative 21 | works of, modify, distribute, perform, display or sell this Software and/or 22 | its documentation for any purpose. 23 | 24 | YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE 25 | PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, 26 | INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, 27 | NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL 28 | TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, 29 | NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER 30 | LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES 31 | INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE 32 | OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT 33 | OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES 34 | (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. 35 | 36 | Should you have any questions regarding your right to use this Software, 37 | contact Texas Instruments Incorporated at www.TI.com. 38 | **************************************************************************************************/ 39 | 40 | #ifndef HAL_KEY_H 41 | #define HAL_KEY_H 42 | 43 | #ifdef __cplusplus 44 | extern "C" 45 | { 46 | #endif 47 | 48 | /************************************************************************************************** 49 | * INCLUDES 50 | **************************************************************************************************/ 51 | #include "hal_board.h" 52 | 53 | /************************************************************************************************** 54 | * MACROS 55 | **************************************************************************************************/ 56 | 57 | /************************************************************************************************** 58 | * CONSTANTS 59 | **************************************************************************************************/ 60 | #define HAL_KEY_BIT0 0x01 61 | #define HAL_KEY_BIT1 0x02 62 | #define HAL_KEY_BIT2 0x04 63 | #define HAL_KEY_BIT3 0x08 64 | #define HAL_KEY_BIT4 0x10 65 | #define HAL_KEY_BIT5 0x20 66 | #define HAL_KEY_BIT6 0x40 67 | #define HAL_KEY_BIT7 0x80 68 | 69 | 70 | 71 | 72 | 73 | /* Interrupt option - Enable or disable */ 74 | #define HAL_KEY_INTERRUPT_DISABLE 0x00 75 | #define HAL_KEY_INTERRUPT_ENABLE 0x01 76 | 77 | /* Key state - shift or nornal */ 78 | #define HAL_KEY_STATE_NORMAL 0x00 79 | #define HAL_KEY_STATE_SHIFT 0x01 80 | 81 | #define HAL_KEY_RISING_EDGE 0 82 | #define HAL_KEY_FALLING_EDGE 1 83 | 84 | 85 | 86 | #define HAL_KEY_PORT0 0x01 87 | #define HAL_KEY_PORT1 0x02 88 | #define HAL_KEY_PORT2 0x04 89 | 90 | #define HAL_KEY_PRESS 0x20 91 | #define HAL_KEY_RELEASE 0x40 92 | 93 | 94 | 95 | #define HAL_KEY_SW_1 0x01 // Joystick up 96 | #define HAL_KEY_SW_2 0x02 // Joystick right 97 | #define HAL_KEY_SW_5 0x04 // Joystick center 98 | #define HAL_KEY_SW_4 0x08 // Joystick left 99 | #define HAL_KEY_SW_3 0x10 // Joystick down 100 | 101 | #define HAL_KEY_SW_6 0x20 // Button S1 if available 102 | #define HAL_KEY_SW_7 0x40 // Button S2 if available 103 | 104 | /************************************************************************************************** 105 | * TYPEDEFS 106 | **************************************************************************************************/ 107 | typedef void (*halKeyCBack_t) (uint8 keys, uint8 state); 108 | 109 | /************************************************************************************************** 110 | * GLOBAL VARIABLES 111 | **************************************************************************************************/ 112 | extern bool Hal_KeyIntEnable; 113 | 114 | /************************************************************************************************** 115 | * FUNCTIONS - API 116 | **************************************************************************************************/ 117 | 118 | /* 119 | * Initialize the Key Service 120 | */ 121 | extern void HalKeyInit( void ); 122 | 123 | /* 124 | * Configure the Key Service 125 | */ 126 | extern void HalKeyConfig( bool interruptEnable, const halKeyCBack_t cback); 127 | 128 | /* 129 | * Read the Key status 130 | */ 131 | extern uint8 HalKeyRead( void); 132 | 133 | /* 134 | * Enter sleep mode, store important values 135 | */ 136 | extern void HalKeyEnterSleep ( void ); 137 | 138 | /* 139 | * Exit sleep mode, retore values 140 | */ 141 | extern uint8 HalKeyExitSleep ( void ); 142 | 143 | /* 144 | * This is for internal used by hal_driver 145 | */ 146 | extern void HalKeyPoll ( void ); 147 | 148 | /* 149 | * This is for internal used by hal_sleep 150 | */ 151 | extern bool HalKeyPressed( void ); 152 | 153 | extern uint8 hal_key_keys(void); 154 | 155 | extern uint8 hal_key_int_keys(void); 156 | 157 | /************************************************************************************************** 158 | **************************************************************************************************/ 159 | 160 | #ifdef __cplusplus 161 | } 162 | #endif 163 | 164 | #endif 165 | -------------------------------------------------------------------------------- /zstack-lib/mhz19.c: -------------------------------------------------------------------------------- 1 | #include "mhz19.h" 2 | #include "Debug.h" 3 | #include "OSAL.h" 4 | #include "OnBoard.h" 5 | #include "hal_led.h" 6 | #include "hal_uart.h" 7 | 8 | #ifndef CO2_UART_PORT 9 | #define CO2_UART_PORT HAL_UART_PORT_1 10 | #endif 11 | 12 | #define MHZ18_RESPONSE_LENGTH 13 13 | 14 | uint8 MHZ19_RESPONSE_LENGTH = 9; 15 | uint8 MHZ19_COMMAND_GET_PPM[] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; 16 | uint8 MHZ19_COMMAND_ABC_ENABLE[] = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xE6}; 17 | uint8 MHZ19_COMMAND_ABC_DISABLE[] = {0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86}; 18 | 19 | void MHZ19_SetABC(bool isEnabled) { 20 | if (isEnabled) { 21 | HalUARTWrite(CO2_UART_PORT, MHZ19_COMMAND_ABC_ENABLE, sizeof(MHZ19_COMMAND_ABC_ENABLE) / sizeof(MHZ19_COMMAND_ABC_ENABLE[0])); 22 | } else { 23 | HalUARTWrite(CO2_UART_PORT, MHZ19_COMMAND_ABC_DISABLE, sizeof(MHZ19_COMMAND_ABC_DISABLE) / sizeof(MHZ19_COMMAND_ABC_DISABLE[0])); 24 | } 25 | } 26 | 27 | void MHZ19_RequestMeasure(void) { HalUARTWrite(CO2_UART_PORT, MHZ19_COMMAND_GET_PPM, sizeof(MHZ19_COMMAND_GET_PPM) / sizeof(MHZ19_COMMAND_GET_PPM[0])); } 28 | uint16 MHZ19_Read(void) { 29 | 30 | uint8 response[MHZ18_RESPONSE_LENGTH]; 31 | HalUARTRead(CO2_UART_PORT, (uint8 *)&response, sizeof(response) / sizeof(response[0])); 32 | 33 | if (response[0] != 0xFF || response[1] != 0x86) { 34 | LREPMaster("MHZ18 Invalid response\r\n"); 35 | HalLedSet(HAL_LED_ALL, HAL_LED_MODE_FLASH); 36 | return 0; 37 | } 38 | 39 | const uint16 ppm = (((uint16)response[2]) << 8) | response[3]; 40 | const int temp = ((int)response[4]) - 40; 41 | const uint8 status = response[5]; 42 | 43 | LREP("MHZ18 Received CO₂=%d ppm Status=0x%X temp=%d\r\n", ppm, status, temp); 44 | 45 | return ppm; 46 | } -------------------------------------------------------------------------------- /zstack-lib/mhz19.h: -------------------------------------------------------------------------------- 1 | #ifndef mhz19_h 2 | #define mhz19_h 3 | extern void MHZ19_RequestMeasure(void); 4 | extern uint16 MHZ19_Read(void); 5 | extern void MHZ19_SetABC(bool isEnabled); 6 | #endif -------------------------------------------------------------------------------- /zstack-lib/senseair.c: -------------------------------------------------------------------------------- 1 | #include "senseair.h" 2 | #include "Debug.h" 3 | #include "OSAL.h" 4 | #include "OnBoard.h" 5 | #include "hal_led.h" 6 | #include "hal_uart.h" 7 | 8 | 9 | #ifndef CO2_UART_PORT 10 | #define CO2_UART_PORT HAL_UART_PORT_1 11 | #endif 12 | 13 | #define SENSEAIR_RESPONSE_LENGTH 13 14 | 15 | uint8 readCO2[] = {0xFE, 0x04, 0x00, 0x00, 0x00, 0x04, 0xE5, 0xC6}; 16 | uint8 disableABC[] = {0xFE, 0x06, 0x00, 0x1F, 0x00, 0x00, 0xAC, 0x03}; 17 | uint8 enableABC[] = {0xFE, 0x60, 0x00, 0x1F, 0x00, 0xB4, 0xAC, 0x74}; 18 | 19 | void SenseAir_SetABC(bool isEnabled) { 20 | if (isEnabled) { 21 | HalUARTWrite(CO2_UART_PORT, enableABC, sizeof(enableABC) / sizeof(enableABC[0])); 22 | } else { 23 | HalUARTWrite(CO2_UART_PORT, disableABC, sizeof(disableABC) / sizeof(disableABC[0])); 24 | } 25 | } 26 | 27 | void SenseAir_RequestMeasure(void) { HalUARTWrite(CO2_UART_PORT, readCO2, sizeof(readCO2) / sizeof(readCO2[0])); } 28 | uint16 SenseAir_Read(void) { 29 | 30 | uint8 response[SENSEAIR_RESPONSE_LENGTH]; 31 | HalUARTRead(CO2_UART_PORT, (uint8 *)&response, sizeof(response) / sizeof(response[0])); 32 | 33 | if (response[0] != 0xFE || response[1] != 0x04) { 34 | LREPMaster("Invalid response\r\n"); 35 | return 0; 36 | } 37 | 38 | const uint8 length = response[2]; 39 | const uint16 status = (((uint16)response[3]) << 8) | response[4]; 40 | const uint16 ppm = (((uint16)response[length + 1]) << 8) | response[length + 2]; 41 | 42 | LREP("SenseAir Received CO₂=%d ppm Status=0x%X\r\n", ppm, status); 43 | 44 | return ppm; 45 | } -------------------------------------------------------------------------------- /zstack-lib/senseair.h: -------------------------------------------------------------------------------- 1 | #ifndef SENSEAIR_H 2 | #define SENSEAIR_H 3 | extern void SenseAir_RequestMeasure(void); 4 | extern uint16 SenseAir_Read(void); 5 | extern void SenseAir_SetABC(bool isEnabled); 6 | #endif -------------------------------------------------------------------------------- /zstack-lib/stdint.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDINT 2 | #define _STDINT 3 | 4 | #ifndef int8_t 5 | #define int8_t int8 6 | #endif 7 | #ifndef int16_t 8 | #define int16_t int16 9 | #endif 10 | #ifndef int32_t 11 | #define int32_t int32 12 | #endif 13 | #ifndef int64_t 14 | #define int64_t int64 15 | #endif 16 | #ifndef uint8_t 17 | #define uint8_t uint8 18 | #endif 19 | #ifndef uint16_t 20 | #define uint16_t uint16 21 | #endif 22 | #ifndef uint32_t 23 | #define uint32_t uint32 24 | #endif 25 | 26 | 27 | #define S8_C(x) x 28 | #define U8_C(x) x 29 | #define S16_C(x) x 30 | #define U16_C(x) x 31 | #define S32_C(x) x 32 | #define U32_C(x) x 33 | #define S64_C(x) x 34 | #define U64_C(x) x 35 | 36 | #endif -------------------------------------------------------------------------------- /zstack-lib/tl_resetter.c: -------------------------------------------------------------------------------- 1 | #include "tl_resetter.h" 2 | #include "Debug.h" 3 | #include "Osal_Memory.h" 4 | #include "bdb.h" 5 | #include "bdb_interface.h" 6 | #include "bdb_touchlink.h" 7 | #include "bdb_touchlink_initiator.h" 8 | #include "hal_key.h" 9 | #include "hal_led.h" 10 | 11 | #ifndef TL_RESETTER_TRIGGER_KEY 12 | #define TL_RESETTER_TRIGGER_KEY 2 13 | #endif 14 | 15 | 16 | #ifndef TL_RESETTERL_START_DELAY 17 | #define TL_RESETTERL_START_DELAY 5 * 1000 18 | #endif 19 | 20 | #ifndef TL_RESETTERL_REPEAT_DELAY 21 | #define TL_RESETTERL_REPEAT_DELAY 1 * 1000 22 | #endif 23 | 24 | #ifndef TL_RESETTER_ATTEMPTS_COUNT 25 | #define TL_RESETTER_ATTEMPTS_COUNT 10 26 | #endif 27 | 28 | #define TL_RESETTER_START_TL_EVT 0x0001 29 | #define TL_RESETTER_RETRY_TL_EVT 0x0002 30 | 31 | static void zclTouchLinkResetter_StartTL(void); 32 | static ZStatus_t zclTouchLinkResetter_TL_NotifyCb(epInfoRec_t *pData); 33 | 34 | 35 | uint8 zclTouchLinkResetter_TaskId = 0; 36 | uint8 zclTouchLinkResetter_CurrentAttempt = 0; 37 | 38 | static void zclTouchLinkResetter_StartTL(void) { 39 | LREP("zclTouchLinkResetter_StartTL attempt=%d\r\n", zclTouchLinkResetter_CurrentAttempt); 40 | HalLedSet(HAL_LED_1, HAL_LED_MODE_FLASH); 41 | if (zclTouchLinkResetter_CurrentAttempt < TL_RESETTER_ATTEMPTS_COUNT) { 42 | touchLinkInitiator_StartDevDisc(); 43 | zclTouchLinkResetter_CurrentAttempt += 1; 44 | osal_start_timerEx(zclTouchLinkResetter_TaskId, TL_RESETTER_RETRY_TL_EVT, TL_RESETTERL_REPEAT_DELAY); 45 | } 46 | } 47 | 48 | ZStatus_t zclTouchLinkResetter_TL_NotifyCb(epInfoRec_t *pData) { 49 | LREPMaster("zclTouchLinkResetter_TL_NotifyCb\r\n"); 50 | osal_stop_timerEx(zclTouchLinkResetter_TaskId, TL_RESETTER_RETRY_TL_EVT); 51 | touchLinkInitiator_ResetToFNSelectedTarget(); 52 | HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF); 53 | return ZSuccess; 54 | } 55 | 56 | void zclTouchLinkRestter_Init(uint8 task_id) { 57 | zclTouchLinkResetter_TaskId = task_id; 58 | touchLinkInitiator_RegisterNotifyTLCB(zclTouchLinkResetter_TL_NotifyCb); 59 | } 60 | 61 | uint16 zclTouchLinkRestter_event_loop(uint8 task_id, uint16 events) { 62 | LREP("zclTouchLinkRestter_event_loop 0x%X\r\n", events); 63 | if (events & TL_RESETTER_START_TL_EVT) { 64 | zclTouchLinkResetter_CurrentAttempt = 0; 65 | zclTouchLinkResetter_StartTL(); 66 | return (events ^ TL_RESETTER_START_TL_EVT); 67 | } 68 | 69 | if (events & TL_RESETTER_RETRY_TL_EVT) { 70 | LREPMaster("TL_RESETTER_RETRY_TL_EVT\r\n"); 71 | zclTouchLinkResetter_StartTL(); 72 | return (events ^ TL_RESETTER_RETRY_TL_EVT); 73 | } 74 | 75 | return 0; 76 | } 77 | 78 | void zclTouchLinkRestter_HandleKeys(uint8 portAndAction, uint8 keyCode) { 79 | if (portAndAction & HAL_KEY_PRESS) { 80 | if (keyCode == TL_RESETTER_TRIGGER_KEY) { 81 | osal_start_timerEx(zclTouchLinkResetter_TaskId, TL_RESETTER_START_TL_EVT, TL_RESETTERL_START_DELAY); 82 | } 83 | } else { 84 | osal_stop_timerEx(zclTouchLinkResetter_TaskId, TL_RESETTER_START_TL_EVT); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /zstack-lib/tl_resetter.h: -------------------------------------------------------------------------------- 1 | #ifndef TL_RESETTER_H 2 | #define TL_RESETTER_H 3 | 4 | 5 | extern void zclTouchLinkRestter_Init(uint8 task_id); 6 | extern uint16 zclTouchLinkRestter_event_loop(uint8 task_id, uint16 events); 7 | extern void zclTouchLinkRestter_HandleKeys(uint8 portAndAction, uint8 keyCode); 8 | #endif -------------------------------------------------------------------------------- /zstack-lib/utils.c: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | #include "hal_adc.h" 3 | 4 | // #define MAX(x, y) (((x) > (y)) ? (x) : (y)) 5 | // #define MIN(x, y) (((x) < (y)) ? (x) : (y)) 6 | 7 | double mapRange(double a1, double a2, double b1, double b2, double s) { 8 | double result = b1 + (s - a1) * (b2 - b1) / (a2 - a1); 9 | return MIN(b2, MAX(result, b1)); 10 | } 11 | 12 | uint16 adcReadSampled(uint8 channel, uint8 resolution, uint8 reference, uint8 samplesCount) { 13 | HalAdcSetReference(reference); 14 | uint32 samplesSum = 0; 15 | for (uint8 i = 0; i < samplesCount; i++) { 16 | samplesSum += HalAdcRead(channel, resolution); 17 | } 18 | return samplesSum /samplesCount; 19 | } 20 | -------------------------------------------------------------------------------- /zstack-lib/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_H 2 | #define UTILS_H 3 | extern double mapRange(double a1, double a2, double b1, double b2, double s); 4 | 5 | extern uint16 adcReadSampled(uint8 channel, uint8 resolution, uint8 reference, uint8 samplesCount); 6 | 7 | 8 | #undef P 9 | #undef INP 10 | #define INP INP 11 | #undef DIR 12 | #define DIR DIR 13 | #undef SEL 14 | #define SEL SEL 15 | 16 | // General I/O definitions 17 | #define IO_GIO 0 // General purpose I/O 18 | #define IO_PER 1 // Peripheral function 19 | #define IO_IN 0 // Input pin 20 | #define IO_OUT 1 // Output pin 21 | #define IO_PUD 0 // Pullup/pulldn input 22 | #define IO_TRI 1 // Tri-state input 23 | #define IO_PUP 0 // Pull-up input pin 24 | #define IO_PDN 1 // Pull-down input pin 25 | 26 | /* I/O PORT CONFIGURATION */ 27 | #define CAT1(x, y) x##y // Concatenates 2 strings 28 | #define CAT2(x, y) CAT1(x, y) // Forces evaluation of CAT1 29 | 30 | // OCM port I/O defintions 31 | // Builds I/O port name: PNAME(1,INP) ==> P1INP 32 | #define PNAME(y, z) CAT2(P, CAT2(y, z)) 33 | // Builds I/O bit name: BNAME(1,2) ==> P1_2 34 | #define BNAME(port, pin) CAT2(CAT2(P, port), CAT2(_, pin)) 35 | 36 | 37 | #define IO_DIR_PORT_PIN(port, pin, dir) \ 38 | { \ 39 | if (dir == IO_OUT) \ 40 | PNAME(port, DIR) |= (1 << (pin)); \ 41 | else \ 42 | PNAME(port, DIR) &= ~(1 << (pin)); \ 43 | } 44 | 45 | 46 | 47 | #define IO_FUNC_PORT_PIN(port, pin, func) \ 48 | { \ 49 | if (port < 2) { \ 50 | if (func == IO_PER) \ 51 | PNAME(port, SEL) |= (1 << (pin)); \ 52 | else \ 53 | PNAME(port, SEL) &= ~(1 << (pin)); \ 54 | } else { \ 55 | if (func == IO_PER) \ 56 | P2SEL |= (1 << (pin >> 1)); \ 57 | else \ 58 | P2SEL &= ~(1 << (pin >> 1)); \ 59 | } \ 60 | } 61 | 62 | #define IO_IMODE_PORT_PIN(port, pin, mode) \ 63 | { \ 64 | if (mode == IO_TRI) \ 65 | PNAME(port, INP) |= (1 << (pin)); \ 66 | else \ 67 | PNAME(port, INP) &= ~(1 << (pin)); \ 68 | } 69 | 70 | #define IO_PUD_PORT(port, dir) \ 71 | { \ 72 | if (dir == IO_PDN) \ 73 | P2INP |= (1 << (port + 5)); \ 74 | else \ 75 | P2INP &= ~(1 << (port + 5)); \ 76 | } 77 | #endif --------------------------------------------------------------------------------