Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[portinglayer] Matter Fan Example #177

Merged
merged 1 commit into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions component/common/application/matter/example/fan/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
BASEDIR := $(shell pwd)
SDKROOTDIR := $(BASEDIR)/../../../../../..
AMEBAZ2_TOOLDIR = $(SDKROOTDIR)/component/soc/realtek/8710c/misc/iar_utility
CHIPDIR = $(SDKROOTDIR)/third_party/connectedhomeip
BUILDDIR = $(BASEDIR)/build
OUTPUT_DIR = $(BUILDDIR)/chip
MATTER_TOOLDIR = $(SDKROOTDIR)/tools/matter

FAN_FILE = $(OUTPUT_DIR)/codegen/cluster-file.txt
FAN_ZAP = $(BASEDIR)/fan-app.zap

OS := $(shell uname)
LBITS := $(shell getconf LONG_BIT)

.PHONY: toolchain
toolchain:
@echo Toolchain unzipping...
ifeq ($(findstring CYGWIN, $(OS)), CYGWIN)
ifneq ("$(LBITS)", "32")
@echo ONLY 32-BIT CYGWIN IS SUPPORTED!
@exit -1
endif
if [ ! -f $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk-6.4.1-cygwin-newlib-build-2778-i686.tar.bz2 ] ; then cat $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk-6.4.1-cygwin-newlib-build-2778-i686.tar.bz2* > $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk-6.4.1-cygwin-newlib-build-2778-i686.tar.bz2; fi;\
if [ ! -d $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk ] ; then mkdir $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk; fi;\
if [ ! -d $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk/cygwin ] ; then tar -jxf $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk-6.4.1-cygwin-newlib-build-2778-i686.tar.bz2 -C $(SDKROOTDIR)/tools/arm-none-eabi-gcc/ ; mv $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk-6.4.1/cygwin $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk/cygwin ;fi
endif

ifeq ($(findstring MINGW32, $(OS)), MINGW32)
if [ ! -f /bin/unzip.exe ] ; then mingw-get.exe install msys-unzip; fi;\
if [ ! -d $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk ] ; then mkdir $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk; fi;\
if [ ! -d $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk/mingw32 ] ; then unzip -q -u $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk64-6.4.1-mingw32-newlib-build-3026.zip ; mv asdk-6.4.1/mingw32 $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk/mingw32 ; rm -rf asdk-6.4.1 ;fi
endif

ifeq ($(findstring Linux, $(OS)), Linux)
ifneq ("$(LBITS)", "64")
@echo ONLY 64-BIT LINUX IS SUPPORTED!
@exit -1
endif
if [ ! -f $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk-10.3.0-linux-newlib-build-3638-x86_64.tar.bz2 ] ; then cat $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk-10.3.0-linux-newlib-build-3638-x86_64.tar.bz2* > $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk-10.3.0-linux-newlib-build-3638-x86_64.tar.bz2; fi;\
if [ ! -d $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk ] ; then mkdir $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk; fi;\
if [ ! -d $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk/linux ] ; then tar -jxf $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk-10.3.0-linux-newlib-build-3638-x86_64.tar.bz2 -C $(SDKROOTDIR)/tools/arm-none-eabi-gcc/ ; mv $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk-10.3.0/linux $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk/linux ; rmdir $(SDKROOTDIR)/tools/arm-none-eabi-gcc/asdk-10.3.0; fi
endif
@echo Toolchain unzip done!

$(FAN_FILE): $(FAN_ZAP)
@mkdir -p $(OUTPUT_DIR)/codegen/zap-generated
@python3 $(CHIPDIR)/scripts/tools/zap/generate.py --no-prettify-output --templates src/app/zap-templates/matter-idl-server.json -z $(CHIPDIR)/src/app/zap-templates/zcl/zcl.json --output-dir $(OUTPUT_DIR)/codegen/zap-generated $^
@python3 $(CHIPDIR)/scripts/tools/zap/generate.py --no-prettify-output --templates src/app/zap-templates/app-templates.json -z $(CHIPDIR)/src/app/zap-templates/zcl/zcl.json --output-dir $(OUTPUT_DIR)/codegen/zap-generated $^
@python3 $(CHIPDIR)/scripts/codegen.py --generator cpp-app --output-dir $(OUTPUT_DIR)/codegen --expected-outputs $(MATTER_TOOLDIR)/codegen_helpers/expected.outputs $(BASEDIR)/fan-app.matter
@python3 $(CHIPDIR)/src/app/zap_cluster_list.py --zap_file $^ > $@
@python3 $(MATTER_TOOLDIR)/codegen_helpers/parse_clusters.py --cluster_file $@ --chip_path $(CHIPDIR)

.PHONY: fan
fan: toolchain $(FAN_FILE)
$(MAKE) -f lib_chip_fan_core.mk all
$(MAKE) -f lib_chip_fan_main.mk all

.PHONY: clean
clean:
@$(MAKE) -f lib_chip_fan_main.mk clean
@$(MAKE) -f lib_chip_fan_core.mk clean
rm -rf $(BUILDDIR)
rm -rf $(BASEDIR)/fan-app.matter
55 changes: 55 additions & 0 deletions component/common/application/matter/example/fan/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# FAN Example
This example is an implementation of the *FAN* device type. You will need a PWM fan.

| Peripheral | Pin |
| ----------- | ----------- |
| Fan | PA_23 |

## ZAP
Since there is no example ZAP file for the fan device type, we will use `fan-app.zap`.

## How it works
The fan can be controlled in two ways, by the Matter controller, or by external means. In this example, we only demonstrate control via Matter controller. If you wish to add more methods to control (eg. a push button), you will need to implement the `downlink` task and handler. See `lighting-app` for button example.
Thus, we only use 1 Uplink queue to for the fan to be controlled by the Matter controller.

### Peripheral Initialization
The initializations of the fan are handled in `matter_drivers.cpp`.

### Fan Attribute Change
Whenever the Matter controller changes the Fanmode/Fanspeed attribute of the fan, 2 types of callbacks will be invoked:
1. MatterPreAttributeChangeCallback - Change the Fanmode/Fanspeed before updating the Fanmode/Fanspeed attribute (TBD)
2. MatterPostAttributeChangeCallback - Change the Fanmode/Fanspeed after updating the Fanmode/Fanspeed attribute

These callbacks are defined in `core/matter_interaction.cpp`.
These callbacks will post an event to the uplink queue, which will be handled by `matter_driver_uplink_update_handler` in `matter_drivers.cpp`.
The driver codes will be called to carry out your actions depending on the Cluster and Attribute ID received.
You may add clusters and attributes handling in `matter_driver_uplink_update_handler` if they are not present.

## How to build

### Configurations
Enable `CONFIG_EXAMPLE_MATTER` and `CONFIG_EXAMPLE_MATTER_FAN` in `platform_opts.h`.
Ensure that `CONFIG_EXAMPLE_MATTER_CHIPTEST` is disabled.

### Setup the Build Environment

cd connectedhomeip
source scripts/activate.sh

### Build Matter Libraries

cd ambz2_matter/component/common/application/matter/example/fan
make fan

### Build the Final Firmware

cd ambz2_matter/project/realtek_amebaz2_v0_example/GCC-RELEASE/
make is_matter

### Flash the Image
Refer to this [guide](https://github.com/ambiot/ambz2_matter/blob/main/tools/AmebaZ2/Image_Tool_Linux/README.md) to flash the image with the Linux Image Tool

### Clean Matter Libraries

cd ambz2_matter/component/common/application/matter/example/fan
make clean
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include "FreeRTOS.h"
#include "task.h"
#include "platform/platform_stdlib.h"
#include "basic_types.h"
#include "platform_opts.h"
#include "section_config.h"
#include "wifi_constants.h"
#include "wifi/wifi_conf.h"
#include "chip_porting.h"
#include "matter_core.h"
#include "matter_drivers.h"
#include "matter_interaction.h"

#if defined(CONFIG_EXAMPLE_MATTER_FAN) && CONFIG_EXAMPLE_MATTER_FAN
static void example_matter_fan_task(void *pvParameters)
{
while(!(wifi_is_up(RTW_STA_INTERFACE) || wifi_is_up(RTW_AP_INTERFACE))) {
vTaskDelay(500);
}

ChipLogProgress(DeviceLayer, "Fan Example!\n");

CHIP_ERROR err = CHIP_NO_ERROR;

initPref(); // init NVS
//
err = matter_core_start();
if (err != CHIP_NO_ERROR)
ChipLogProgress(DeviceLayer, "matter_core_start failed!\n");

err = matter_driver_fan_init();
if (err != CHIP_NO_ERROR)
ChipLogProgress(DeviceLayer, "matter_driver_fan_init failed!\n");

err = matter_driver_fan_set_startup_value();
if (err != CHIP_NO_ERROR)
ChipLogProgress(DeviceLayer, "matter_driver_fan_set_startup_value failed!\n");

err = matter_interaction_start_uplink();
if (err != CHIP_NO_ERROR)
ChipLogProgress(DeviceLayer, "matter_interaction_start_uplink failed!\n");

vTaskDelete(NULL);
}

extern "C" void example_matter_fan(void)
{
if(xTaskCreate(example_matter_fan_task, ((const char*)"example_matter_fan_task"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
ChipLogProgress(DeviceLayer, "\n\r%s xTaskCreate(example_matter_fan) failed", __FUNCTION__);
}
#endif /* CONFIG_EXAMPLE_MATTER_FAN */
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef EXAMPLE_MATTER_FAN_H
#define EXAMPLE_MATTER_FAN_H

void example_matter_fan_task(void);

#endif /* EXAMPLE_MATTER_FAN_H */
Loading