diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index f8d0a2dc434631..0a2262a04d42b6 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -1451,3 +1451,4 @@ localedef nameserver nmcli tsan +bouffalolab diff --git a/.gitmodules b/.gitmodules index 99d22f909aa2b2..82d6d04b944a6a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -203,3 +203,7 @@ [submodule "third_party/efr32_sdk/wiseconnect-wifi-bt-sdk"] path = third_party/efr32_sdk/wiseconnect-wifi-bt-sdk url = https://github.com/SiliconLabs/wiseconnect-wifi-bt-sdk +[submodule "third_party/bouffalolab/bl602"] + path = third_party/bouffalolab/bl602_sdk/repo + url = https://github.com/bouffalolab/bl_iot_sdk_matter.git + branch = bl602_release diff --git a/BUILD.gn b/BUILD.gn index 09b8f29565265a..6ddfb3dc4d78c8 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -192,6 +192,9 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { # Set this to true to enable k32w builds by default. enable_k32w_builds = false + + # Set this to true to enable bl602 builds by default. + enable_bl602_builds = false } declare_args() { @@ -274,6 +277,9 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { # Build the k32w shell app example. enable_k32w_shell_app_build = enable_k32w_builds + # Build the bl602 lighting app example. + enable_bl602_lighting_app_build = enable_bl602_builds + enable_fake_tests = enable_default_builds && host_os == "linux" } diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index 7f770cf68f7cc5..99f26677c5419a 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn @@ -74,6 +74,8 @@ if (_chip_defaults.custom_toolchain != "") { } else if (target_os == "freertos") { if (target_cpu == "arm") { _default_toolchain = "${_build_overrides.build_root}/toolchain/arm_gcc" + } else if (target_cpu == "riscv") { + _default_toolchain = "${_build_overrides.build_root}/toolchain/riscv_gcc" } else { assert(false, "Unsupported target_cpu: ${target_cpu}") } diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 6c16e492d3b6bc..7c66e9638dd710 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn @@ -42,6 +42,8 @@ if (current_cpu == "arm" || current_cpu == "arm64") { import("${build_root}/config/arm.gni") } else if (current_cpu == "x86" || current_cpu == "x86_64") { import("${build_root}/config/x86.gni") +} else if (current_cpu == "riscv") { + import("${build_root}/config/riscv.gni") } config("release") { @@ -122,6 +124,26 @@ config("abi_default") { ] } } + if (current_cpu == "riscv") { + if (riscv_arch != "") { + cflags += [ "-march=${riscv_arch}" ] + } + if (riscv_cpu != "") { + cflags += [ "-mcpu=${riscv_cpu}" ] + } + if (riscv_tune != "") { + cflags += [ "-mtune=${riscv_tune}" ] + } + if (riscv_abi != "") { + cflags += [ "-mabi=${riscv_abi}" ] + } + if (riscv_fpu != "") { + cflags += [ "-mfpu=${riscv_fpu}" ] + } + if (riscv_float_abi != "") { + cflags += [ "-mfloat-abi=${riscv_float_abi}" ] + } + } } asmflags = cflags diff --git a/build/config/riscv.gni b/build/config/riscv.gni new file mode 100644 index 00000000000000..c7843d8ba51ba1 --- /dev/null +++ b/build/config/riscv.gni @@ -0,0 +1,64 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") + +if (current_cpu == "riscv") { + declare_args() { + # Build file to import for RISCV defaults. + riscv_platform_config = "" + } + + # Allow platforms to override how RISCV architecture flags are chosen by + # providing a file to import. + if (riscv_platform_config != "") { + _platform_defaults = { + import(riscv_platform_config) + } + } + + _defaults = { + riscv_arch = "" + riscv_cpu = "" + riscv_tune = "" + riscv_fpu = "" + riscv_float_abi = "" + riscv_abi = "" + + # Update defaults with platform values, if any. + if (riscv_platform_config != "") { + forward_variables_from(_platform_defaults, "*") + } + } + + declare_args() { + # RISCV architecture (value for -march flag). + riscv_arch = _defaults.riscv_arch + + # RISCV CPU (value for -mcpu flag). + riscv_cpu = _defaults.riscv_cpu + + # RISCV tuning (value for -mtune flag). + riscv_tune = _defaults.riscv_tune + + # RISCV FPU (value for -mfpu flag). + riscv_fpu = _defaults.riscv_fpu + + # RISCV float ABI (value for -mfloat-abi flag). + riscv_float_abi = _defaults.riscv_float_abi + + # RISCV ABI (value for -mabi flag). + riscv_abi = _defaults.riscv_abi + } +} diff --git a/build/toolchain/riscv_gcc/BUILD.gn b/build/toolchain/riscv_gcc/BUILD.gn new file mode 100644 index 00000000000000..9af62a3cc15e71 --- /dev/null +++ b/build/toolchain/riscv_gcc/BUILD.gn @@ -0,0 +1,21 @@ +# Copyright 2021 The Pigweed Authors +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("riscv_toolchain.gni") + +riscv_toolchain("riscv_gcc") { + toolchain_args = { + } +} diff --git a/build/toolchain/riscv_gcc/riscv_toolchain.gni b/build/toolchain/riscv_gcc/riscv_toolchain.gni new file mode 100644 index 00000000000000..48693dee67b8fb --- /dev/null +++ b/build/toolchain/riscv_gcc/riscv_toolchain.gni @@ -0,0 +1,35 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/bl602_sdk.gni") +import("//build_overrides/build.gni") + +import("${build_root}/toolchain/gcc_toolchain.gni") + +template("riscv_toolchain") { + gcc_toolchain(target_name) { + _tool_name_root = "${root_build_dir}/../../third_party/bouffalolab/bl602_sdk/repo/toolchain/riscv/Linux/bin/riscv64-unknown-elf-" + ar = _tool_name_root + "ar" + cc = _tool_name_root + "gcc" + cxx = _tool_name_root + "g++" + + toolchain_args = { + current_cpu = "riscv" + current_os = invoker.current_os + is_clang = false + + forward_variables_from(invoker.toolchain_args, "*") + } + } +} diff --git a/build_overrides/bl602_sdk.gni b/build_overrides/bl602_sdk.gni new file mode 100644 index 00000000000000..e74bf42d737d42 --- /dev/null +++ b/build_overrides/bl602_sdk.gni @@ -0,0 +1,18 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +declare_args() { + # Root directory for bl602 SDK build files. + bl602_sdk_build_root = "//third_party/bouffalolab/bl602_sdk" +} diff --git a/config/bouffalolab/bl602/lib/pw_rpc/BUILD.gn b/config/bouffalolab/bl602/lib/pw_rpc/BUILD.gn new file mode 100644 index 00000000000000..66ab51fc23adf0 --- /dev/null +++ b/config/bouffalolab/bl602/lib/pw_rpc/BUILD.gn @@ -0,0 +1,36 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") +import("$dir_pw_build/target_types.gni") + +static_library("pw_rpc") { + output_name = "libPwRpc" + + public_configs = [ "${dir_pigweed}/pw_hdlc:default_config" ] + + public_deps = [ + "$dir_pw_rpc:server", + "$dir_pw_rpc/nanopb:echo_service", + "${chip_root}/examples/platform/bl602/pw_sys_io:pw_sys_io_bl602", + "${dir_pigweed}/pw_hdlc:pw_rpc", + dir_pw_assert, + dir_pw_checksum, + dir_pw_hdlc, + dir_pw_log, + ] + + output_dir = "${root_out_dir}/lib" +} diff --git a/config/bouffalolab/bl602/lib/pw_rpc/pw_rpc.gni b/config/bouffalolab/bl602/lib/pw_rpc/pw_rpc.gni new file mode 100644 index 00000000000000..29f549efd4b088 --- /dev/null +++ b/config/bouffalolab/bl602/lib/pw_rpc/pw_rpc.gni @@ -0,0 +1,28 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") + +pw_log_BACKEND = "$dir_pw_log_basic" +pw_assert_BACKEND = "$dir_pw_assert_log" +pw_sys_io_BACKEND = + "${chip_root}/examples/platform/bl602/pw_sys_io:pw_sys_io_bl602" + +pw_build_LINK_DEPS = [ + "$dir_pw_assert:impl", + "$dir_pw_log:impl", +] + +dir_pw_third_party_nanopb = "${chip_root}/third_party/nanopb/repo" diff --git a/config/bouffalolab/bl602/toolchain/BUILD.gn b/config/bouffalolab/bl602/toolchain/BUILD.gn new file mode 100644 index 00000000000000..950b2732a57a05 --- /dev/null +++ b/config/bouffalolab/bl602/toolchain/BUILD.gn @@ -0,0 +1,39 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +import("${build_root}/toolchain/riscv_gcc/riscv_toolchain.gni") + +riscv_toolchain("bl602_lock_app") { + toolchain_args = { + current_os = "freertos" + import("${chip_root}/examples/lock-app/bl602/args.gni") + } +} + +riscv_toolchain("bl602_lighting_app") { + toolchain_args = { + current_os = "freertos" + import("${chip_root}/examples/lighting-app/bl602/args.gni") + } +} + +riscv_toolchain("bl602_window_app") { + toolchain_args = { + current_os = "freertos" + import("${chip_root}/examples/window-app/bl602/args.gni") + } +} diff --git a/examples/build_overrides/bl602_sdk.gni b/examples/build_overrides/bl602_sdk.gni new file mode 100644 index 00000000000000..f2ff1f1ee45cf5 --- /dev/null +++ b/examples/build_overrides/bl602_sdk.gni @@ -0,0 +1,19 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +declare_args() { + # Root directory for bl602 SDK. + bl602_sdk_build_root = + "//third_party/connectedhomeip/third_party/bouffalolab/bl602_sdk" +} diff --git a/examples/lighting-app/bouffalolab/bl602/.gn b/examples/lighting-app/bouffalolab/bl602/.gn new file mode 100644 index 00000000000000..27a24ca4db236b --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/.gn @@ -0,0 +1,28 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "riscv" + target_os = "freertos" + + import("//args.gni") +} diff --git a/examples/lighting-app/bouffalolab/bl602/BUILD.gn b/examples/lighting-app/bouffalolab/bl602/BUILD.gn new file mode 100644 index 00000000000000..25e4b8c92e95c9 --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/BUILD.gn @@ -0,0 +1,128 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/bl602_sdk.gni") +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +import("${bl602_sdk_build_root}/bl602_executable.gni") +import("${bl602_sdk_build_root}/bl602_sdk.gni") +import("${build_root}/config/defaults.gni") + +assert(current_os == "freertos") + +bl602_project_dir = "${chip_root}/examples/lighting-app/bouffalolab/bl602" +examples_plat_dir = "${chip_root}/examples/platform/bouffalolab/bl602" + +declare_args() { + # Dump memory usage at link time. + chip_print_memory_usage = true + + # PIN code for PASE session establishment. + setupPinCode = 20202021 + + # Monitor & log memory usage at runtime. + enable_heap_monitoring = false +} + +show_qr_code = false + +# BL-HWC-G1 (No LCD) +if (bl602_board == "BL-HWC-G1" || bl602_board == "IOT_DVK_3S") { + show_qr_code = false +} + +bl602_sdk("sdk") { + sources = [ + "${bl602_project_dir}/include/CHIPProjectConfig.h", + "${bl602_project_dir}/include/FreeRTOSConfig.h", + ] + + include_dirs = [ + "${chip_root}/src/platform/bouffalolab/BL602", + "${bl602_project_dir}/include", + "${examples_plat_dir}", + ] + + defines = [ + "CONFIG_PSM_EASYFLASH_SIZE=16384", + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE=${setupPinCode}", + ] +} + +bl602_executable("lighting_app") { + output_name = "chip-bl602-lighting-example.out" + + sources = [ + #"${bl602_project_dir}/include/CHIPProjectConfig.h", + "${examples_plat_dir}/InitPlatform.cpp", + "include/CHIPProjectConfig.h", + "src/AppTask.cpp", + "src/CHIPDeviceManager.cpp", + "src/DeviceCallbacks.cpp", + "src/LEDWidget.cpp", + "src/LightingManager.cpp", + "src/main.cpp", + ] + + deps = [ + ":sdk", + "${chip_root}/examples/common/QRCode", + "${chip_root}/examples/lighting-app/lighting-common", + "${chip_root}/src/lib", + "${chip_root}/src/setup_payload", + ] + + include_dirs = [ "include" ] + + if (bl602_board == "IOT_DVK_3S") { + defines = [ "BOARD_ID=0" ] + } else { + defines = [ "BOARD_ID=1" ] + } + + if (show_qr_code) { + sources += [ "${examples_plat_dir}/display/lcd.c" ] + + defines += [ "DISPLAY_ENABLED" ] + } + + if (enable_heap_monitoring) { + defines += [ "HEAP_MONITORING" ] + sources += [ "${examples_plat_dir}/MemMonitoring.cpp" ] + } + + ldscript = "${examples_plat_dir}/ldscripts/flash_rom.ld" + + ldflags = [ "-T" + rebase_path(ldscript, root_build_dir) ] + + inputs = [ ldscript ] + + if (chip_print_memory_usage) { + ldflags += [ + "-Wl,--print-memory-usage", + "-fstack-usage", + ] + } + + output_dir = root_out_dir +} + +group("bl602") { + deps = [ ":lighting_app" ] +} + +group("default") { + deps = [ ":bl602" ] +} diff --git a/examples/lighting-app/bouffalolab/bl602/README.md b/examples/lighting-app/bouffalolab/bl602/README.md new file mode 100644 index 00000000000000..b11e98aa1ed29d --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/README.md @@ -0,0 +1,80 @@ +#CHIP BL602 Lighting Example + +## Build + +- Install some additional tools(likely already present for CHIP developers): + + #Linux \$ sudo apt-get install git libwebkitgtk-1.0-0 ninja-build + + #Mac OS X \$ brew install ninja + +* Build the example application: + + `connectedhomeip$ ./scripts/build/build_examples.py --target bl602-lighting build` + +Generated files + + connectedhomeip/out/lighting_app_bl602/chip-bl602-lighting-example.bin + +- To delete generated executable, libraries and object files use: + + $ cd ~/connectedhomeip/ + $ rm -rf out/ + +## Flash + +- Download [FLASH_TOOL](https://dev.bouffalolab.com/download/). + +### Setting up Python Controller + +Once BL602 is up and running, we need to set up a device controller to perform +commissioning and cluster control. + +- Set up python controller. + + $ cd {path-to-connectedhomeip} + $ ./scripts/build_python.sh -m platform + +- Execute the controller. + + $ source ./out/python_env/bin/activate + $ chip-device-ctrl + +### Commissioning over BLE + +- Establish the secure session over BLE. BLE is the default mode in the + application and is configurable through menuconfig. + + - chip-device-ctrl > ble-scan + - chip-device-ctrl > set-pairing-wifi-credential TESTSSID P455W4RD + - chip-device-ctrl > connect -ble 3904 20202021 135246 + + Parameters: + 1. Discriminator: 3904 + 2. Setup-pin-code: 20202021 + 3. Node ID: Optional. + If not passed in this command, then it is auto-generated by the controller and displayed in the output of connect. + The same value should be used in the next commands. + We have chosen a random node ID which is 135246. + 4. TESTSSID : Wi-Fi SSID + 5. P455W4RD : Wi-Fi Password + +### Cluster control + +- After successful commissioning, use the OnOff cluster commands to control + the OnOff attribute. This allows you to toggle a parameter implemented by + the device to be On or Off. + + `chip-device-ctrl > zcl OnOff On 135246 1 1` + `chip-device-ctrl > zcl OnOff Off 135246 1 1` + +- Use the LevelControl cluster commands to control the CurrentLevel attribute. + This allows you to control the brightness of the led. + + `chip-device-ctrl > zcl LevelControl MoveToLevel 135246 1 1 level=10 transitionTime=0 optionMask=0 optionOverride=0` + +- Use the ColorControl cluster commands to control the CurrentHue and + CurrentSaturation attribute. + + `chip-device-ctrl > zcl ColorControl MoveToHue 135246 1 1 hue=100 direction=0 transitionTime=0 optionsMask=0 optionsOverride=0` + `chip-device-ctrl > zcl ColorControl MoveToSaturation 135245 1 1 saturation=200 transitionTime=0 optionsMask=0 optionsOverride=0` diff --git a/examples/lighting-app/bouffalolab/bl602/args.gni b/examples/lighting-app/bouffalolab/bl602/args.gni new file mode 100644 index 00000000000000..6ac49b227fe402 --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/args.gni @@ -0,0 +1,28 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("${chip_root}/src/platform/bouffalolab/BL602/args.gni") + +bl602_sdk_target = get_label_info(":sdk", "label_no_toolchain") + +pw_log_BACKEND = "${chip_root}/src/lib/support/pw_log_chip" +pw_assert_BACKEND = "$dir_pw_assert_log" + +chip_enable_openthread = false +declare_args() { + # Disable lock tracking, since our FreeRTOS configuration does not set + # INCLUDE_xSemaphoreGetMutexHolder + chip_stack_lock_tracking = "none" +} diff --git a/examples/lighting-app/bouffalolab/bl602/build_overrides b/examples/lighting-app/bouffalolab/bl602/build_overrides new file mode 120000 index 00000000000000..995884e6163eb5 --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/build_overrides @@ -0,0 +1 @@ +../../../build_overrides \ No newline at end of file diff --git a/examples/lighting-app/bouffalolab/bl602/include/AppConfig.h b/examples/lighting-app/bouffalolab/bl602/include/AppConfig.h new file mode 100644 index 00000000000000..4bc195187b2c69 --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/include/AppConfig.h @@ -0,0 +1,43 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +// #include "driver/gpio.h" + +extern "C" { +#include +} +// ---- Light Example App Config ---- + +#define APP_TASK_NAME "LIGHT-APP" + +// 3R: TODO +//#define SYSTEM_STATE_LED (25) +//#define LOCK_STATE_LED (26) + +//#define APP_LIGHT_BUTTON (34) +#define APP_FUNCTION_BUTTON (35) + +#define APP_BUTTON_DEBOUNCE_PERIOD_MS 50 + +#define APP_BUTTON_PRESSED 0 +#define APP_BUTTON_RELEASED 1 + +// Time it takes in ms for the simulated actuator to move from one +// state to another. +#define ACTUATOR_MOVEMENT_PERIOS_MS 2000 diff --git a/examples/lighting-app/bouffalolab/bl602/include/AppEvent.h b/examples/lighting-app/bouffalolab/bl602/include/AppEvent.h new file mode 100644 index 00000000000000..7a19b719edad25 --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/include/AppEvent.h @@ -0,0 +1,55 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2018 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +struct AppEvent; +typedef void (*EventHandler)(AppEvent *); + +struct AppEvent +{ + enum AppEventTypes + { + kEventType_Button = 0, + kEventType_Timer, + kEventType_Light, + kEventType_Install, + }; + + uint16_t Type; + + union + { + struct + { + uint8_t Action; + } ButtonEvent; + struct + { + void * Context; + } TimerEvent; + struct + { + uint8_t Action; + int32_t Actor; + } LightEvent; + }; + + EventHandler Handler; +}; diff --git a/examples/lighting-app/bouffalolab/bl602/include/AppTask.h b/examples/lighting-app/bouffalolab/bl602/include/AppTask.h new file mode 100644 index 00000000000000..d27d9332c21c25 --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/include/AppTask.h @@ -0,0 +1,94 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include "AppEvent.h" +#include "LightingManager.h" + +#include +#include +#include +#include + +// Application-defined error codes in the CHIP_ERROR space. +#define APP_ERROR_EVENT_QUEUE_FAILED CHIP_APPLICATION_ERROR(0x01) +#define APP_ERROR_CREATE_TASK_FAILED CHIP_APPLICATION_ERROR(0x02) +#define APP_ERROR_UNHANDLED_EVENT CHIP_APPLICATION_ERROR(0x03) +#define APP_ERROR_CREATE_TIMER_FAILED CHIP_APPLICATION_ERROR(0x04) +#define APP_ERROR_START_TIMER_FAILED CHIP_APPLICATION_ERROR(0x05) +#define APP_ERROR_STOP_TIMER_FAILED CHIP_APPLICATION_ERROR(0x06) + +void appError(CHIP_ERROR error); + +class AppTask +{ + +public: + CHIP_ERROR StartAppTask(); + static void AppTaskMain(void * pvParameter); + + void PostLightActionRequest(int32_t aActor, LightingManager::Action_t aAction); + void PostEvent(const AppEvent * event); + void ButtonEventHandler(uint8_t btnIdx, uint8_t btnAction); + void AppTask::OtaTask(void); + +private: + friend AppTask & GetAppTask(void); + + CHIP_ERROR Init(); + + static void ActionInitiated(LightingManager::Action_t aAction, int32_t aActor); + static void ActionCompleted(LightingManager::Action_t aAction); + + void CancelTimer(void); + + void DispatchEvent(AppEvent * event); + + static void FunctionTimerEventHandler(AppEvent * aEvent); + static void FunctionHandler(AppEvent * aEvent); + static void LightActionEventHandler(AppEvent * aEvent); + static void TimerEventHandler(TimerHandle_t xTimer); + + static void UpdateClusterState(void); + + void StartTimer(uint32_t aTimeoutMs); + + enum Function_t + { + kFunction_NoneSelected = 0, + kFunction_SoftwareUpdate = 0, + kFunction_StartBleAdv = 1, + kFunction_FactoryReset = 2, + + kFunction_Invalid + } Function; + + Function_t mFunction; + bool mFunctionTimerActive; + bool mSyncClusterToButtonAction; + + static AppTask sAppTask; +}; + +inline AppTask & GetAppTask(void) +{ + return AppTask::sAppTask; +} diff --git a/examples/lighting-app/bouffalolab/bl602/include/CHIPDeviceManager.h b/examples/lighting-app/bouffalolab/bl602/include/CHIPDeviceManager.h new file mode 100644 index 00000000000000..91d8c7c6c01d7b --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/include/CHIPDeviceManager.h @@ -0,0 +1,125 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file contains definitions for the CHIP DeviceManager Interface + * + * This object will co-ordinate multiple activities such as + * initialisation, rendezvous, session mgmt and other such + * activities within the CHIP stack. This is a singleton object. + */ + +#ifndef CHIP_LOCK_DEVICEMANAGER_H_ +#define CHIP_LOCK_DEVICEMANAGER_H_ + +#include +#include +#include + +#include + +#include +#include + +#include + +namespace chip { +namespace DeviceManager { + +/** + * @brief + * This class provides a skeleton for all the callback functions. The functions will be + * called by other objects within the CHIP stack for specific events. + * Applications interested in receiving specific callbacks can specialize this class and handle + * these events in their implementation of this class. + */ +class DLL_EXPORT CHIPDeviceManagerCallbacks +{ +public: + /** + * @brief + * Called when CHIP Device events (PublicEventTypes) are triggered. + * + * @param event ChipDeviceEvent that occurred + * @param arg arguments specific to the event, if any + */ + virtual void DeviceEventCallback(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + /** + * @brief + * Called after an attribute has been changed + * + * @param endpoint endpoint id + * @param clusterID cluster id + * @param attributeId attribute id that was changed + * @param mask mask of the attribute + * @param manufacturerCode manufacturer code + * @param type attribute type + * @param size size of the attribute + * @param value pointer to the new value + */ + virtual void PostAttributeChangeCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, chip::AttributeId attributeId, + uint8_t mask, uint8_t type, uint16_t size, uint8_t * value) + {} + virtual ~CHIPDeviceManagerCallbacks() {} +}; + +/** + * @brief + * A common class that drives other components of the CHIP stack + */ +class DLL_EXPORT CHIPDeviceManager +{ +public: + CHIPDeviceManager(const CHIPDeviceManager &) = delete; + CHIPDeviceManager(const CHIPDeviceManager &&) = delete; + CHIPDeviceManager & operator=(const CHIPDeviceManager &) = delete; + + static CHIPDeviceManager & GetInstance() + { + static CHIPDeviceManager instance; + return instance; + } + + /** + * @brief + * Initialise CHIPDeviceManager + * + * @param cb Application's instance of the CHIPDeviceManagerCallbacks for consuming events + */ + CHIP_ERROR Init(CHIPDeviceManagerCallbacks * cb); + /** + * @brief + * Fetch a pointer to the registered CHIPDeviceManagerCallbacks object. + * + */ + CHIPDeviceManagerCallbacks * GetCHIPDeviceManagerCallbacks() { return mCB; } + + /** + * Use internally for registration of the ChipDeviceEvents + */ + static void CommonDeviceEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + +private: + CHIPDeviceManagerCallbacks * mCB = nullptr; + CHIPDeviceManager() {} +}; + +} // namespace DeviceManager +} // namespace chip + +#endif /* CHIP_LOCK_DEVICEMANAGER_H_ */ diff --git a/examples/lighting-app/bouffalolab/bl602/include/CHIPProjectConfig.h b/examples/lighting-app/bouffalolab/bl602/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..6df15a52750fee --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/include/CHIPProjectConfig.h @@ -0,0 +1,129 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +/** + * CHIP_DEVICE_CONFIG_ENABLE_TEST_DEVICE_IDENTITY + * + * Enables the use of a hard-coded default Chip device id and credentials if no device id + * is found in Chip NV storage. + * + * This option is for testing only and should be disabled in production releases. + */ +#define CHIP_DEVICE_CONFIG_ENABLE_TEST_DEVICE_IDENTITY 34 + +// Use a default pairing code if one hasn't been provisioned in flash. +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#endif +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF40 + +// For convenience, Chip Security Test Mode can be enabled and the +// requirement for authentication in various protocols can be disabled. +// +// WARNING: These options make it possible to circumvent basic Chip security functionality, +// including message encryption. Because of this they MUST NEVER BE ENABLED IN PRODUCTION BUILDS. +// +#define CHIP_CONFIG_SECURITY_TEST_MODE 0 +#define CHIP_CONFIG_REQUIRE_AUTH 1 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + * + * 0x235A: Chip's Vendor Id. + * 0xFFF1: Test vendor + */ +//#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0x130D +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0xFFF1 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + * + * 0x534B: BL602 lock-app + * TODO: 3R + */ +//#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0xF001 +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8005 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_REVISION + * + * The product revision number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software revisions. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_REVISION 1 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_FIRMWARE_REVISION_STRING + * + * A string identifying the firmware revision running on the device. + * CHIP service currently expects the firmware version to be in the format + * {MAJOR_VERSION}.0d{MINOR_VERSION} + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_FIRMWARE_REVISION_STRING +#define CHIP_DEVICE_CONFIG_DEVICE_FIRMWARE_REVISION_STRING "0.1ALPHA" +#endif +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + * + * Enable support for Chip-over-BLE (CHIPoBLE). + */ +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote Chip Time service + * using the Chip Time Sync protocol. + */ +#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0 + +/** + * CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER + * + * Enables the use of a hard-coded default serial number if none + * is found in Chip NV storage. + */ +#define CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER "TEST_SN" + +/** + * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS + * + * Enable recording UTC timestamps. + */ +#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 + +/** + * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE + * + * A size, in bytes, of the individual debug event logging buffer. + */ +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) diff --git a/examples/lighting-app/bouffalolab/bl602/include/DeviceCallbacks.h b/examples/lighting-app/bouffalolab/bl602/include/DeviceCallbacks.h new file mode 100644 index 00000000000000..080c65751df181 --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/include/DeviceCallbacks.h @@ -0,0 +1,49 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file DeviceCallbacks.h + * + * Implementations for the DeviceManager callbacks for this application + * + **/ + +#pragma once + +#include "CHIPDeviceManager.h" +#include +#include +#include + +class DeviceCallbacks : public chip::DeviceManager::CHIPDeviceManagerCallbacks +{ +public: + virtual void DeviceEventCallback(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + virtual void PostAttributeChangeCallback(chip::EndpointId endpointId, chip::ClusterId clusterId, chip::AttributeId attributeId, + uint8_t mask, uint8_t type, uint16_t size, uint8_t * value); + +private: + void OnInternetConnectivityChange(const chip::DeviceLayer::ChipDeviceEvent * event); + void OnSessionEstablished(const chip::DeviceLayer::ChipDeviceEvent * event); + void OnOnOffPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); + void OnLevelControlAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); + void OnColorControlAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); + void OnIdentifyPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); + + bool mEndpointOnOffState[2]; +}; diff --git a/examples/lighting-app/bouffalolab/bl602/include/FreeRTOSConfig.h b/examples/lighting-app/bouffalolab/bl602/include/FreeRTOSConfig.h new file mode 100644 index 00000000000000..96948ea64e95d9 --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/include/FreeRTOSConfig.h @@ -0,0 +1,241 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*************************************************************************** + * # License + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is Third Party Software licensed by Silicon Labs from a third party + * and is governed by the sections of the MSLA applicable to Third Party + * Software and the additional terms set forth below. + * + ******************************************************************************/ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "platform.h" +#include + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +/* Tickless mode is not used. */ + +/* Some of the standard demo test tasks assume a tick rate of 1KHz, even +though that is faster than would normally be warranted by a real +application. */ +#define configTICK_RATE_HZ (1000) + +/* The full demo always has tasks to run so the tick will never be turned +off. The blinky demo will use the default tickless idle implementation to +turn the tick off. */ +#define configUSE_TICKLESS_IDLE (0) + +/* Hook function related definitions. */ +#define configUSE_TICK_HOOK (0) +#define configCHECK_FOR_STACK_OVERFLOW (2) +#define configUSE_MALLOC_FAILED_HOOK (1) +#define configUSE_IDLE_HOOK (0) + +#define configENERGY_MODE (sleepEM1) + +/* Main functions*/ +/* Run time stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS (0) + +/* Co-routine related definitions. */ +#define configUSE_CO_ROUTINES (0) +#define configMAX_CO_ROUTINE_PRIORITIES (2) + +/* Software timer related definitions. */ +#define configUSE_TIMERS (1) +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) /* Highest priority */ +#define configTIMER_QUEUE_LENGTH (4) +#define configTIMER_TASK_STACK_DEPTH (400) + +/* Cortex-M specific definitions. */ +#ifdef __NVIC_PRIO_BITS +/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ +#define configPRIO_BITS (__NVIC_PRIO_BITS) +#else +#define configPRIO_BITS 3 /* 7 priority levels */ +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" +function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY (0x07) + +/* The highest interrupt priority that can be used by any interrupt service +routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY (0x03) + +/* Interrupt priorities used by the kernel port layer itself. These are generic +to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) + +/* FreeRTOS MPU specific definitions. */ +#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS (0) + +#define configCPU_CLOCK_HZ (10 * 1000 * 1000) +#define configUSE_PREEMPTION (1) +#define configUSE_TIME_SLICING (1) +#define configUSE_PORT_OPTIMISED_TASK_SELECTION (1) +#define configUSE_TICKLESS_IDLE_SIMPLE_DEBUG (1) /* See into vPortSuppressTicksAndSleep source code for explanation */ +#define configMAX_PRIORITIES (32) +#define configMINIMAL_STACK_SIZE ((unsigned short) 112) /* Number of words to use for Idle and Timer stacks */ +#define configMAX_TASK_NAME_LEN (16) +#define configUSE_16_BIT_TICKS (0) +#define configIDLE_SHOULD_YIELD (1) +#define configUSE_MUTEXES (1) +#define configUSE_RECURSIVE_MUTEXES (1) +#define configUSE_COUNTING_SEMAPHORES (1) +#define configQUEUE_REGISTRY_SIZE (8) +// #define configUSE_QUEUE_SETS (0) +// #define configUSE_NEWLIB_REENTRANT (0) +#define configENABLE_BACKWARD_COMPATIBILITY (1) +#define configSUPPORT_STATIC_ALLOCATION (1) + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet (1) +#define INCLUDE_uxTaskPriorityGet (1) +#define INCLUDE_vTaskDelete (1) +#define INCLUDE_vTaskSuspend (1) +// #define INCLUDE_xResumeFromISR (1) +#define INCLUDE_vTaskDelayUntil (1) +#define INCLUDE_vTaskDelay (1) +#define INCLUDE_xTaskGetSchedulerState (0) +#define INCLUDE_xTaskGetCurrentTaskHandle (0) +#define INCLUDE_uxTaskGetStackHighWaterMark (1) +#define INCLUDE_xTaskGetIdleTaskHandle (0) +// #define INCLUDE_xTimerGetTimerDaemonTaskHandle (1) +// #define INCLUDE_pcTaskGetTaskName (1) +#define INCLUDE_eTaskGetState (1) +// #define INCLUDE_xEventGroupSetBitFromISR (1) +#define INCLUDE_xTimerPendFunctionCall (1) + +/* Stop if an assertion fails. */ +#define configASSERT(x) \ + if ((x) == 0) \ + vAssertCalled() + +// #define configASSERTNULL(x) \ +// if ((x) == NULL) \ +// { \ +// taskDISABLE_INTERRUPTS(); \ +// for (;;) \ +// ; \ +// } + +/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS +standard names. */ +// #define vPortSVCHandler SVC_Handler +// #define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler + +#ifdef __cplusplus +} +#endif diff --git a/examples/lighting-app/bouffalolab/bl602/include/LEDWidget.h b/examples/lighting-app/bouffalolab/bl602/include/LEDWidget.h new file mode 100644 index 00000000000000..a32bdd9151795d --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/include/LEDWidget.h @@ -0,0 +1,68 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2018 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include + +class LEDWidget +{ +public: + LEDWidget() { Init(0); } + + void Init(uint8_t gpioNum); + + void Set(bool state); + + void SetStateMask(bool state); + + void SetBrightness(uint8_t brightness); + + void Blink(uint32_t changeRateMS); + + void Blink(uint32_t onTimeMS, uint32_t offTimeMS); + + void BlinkOnError(); + + void Animate(); + void SetColor(uint8_t Hue, uint8_t Saturation); + + void HSB2rgb(uint16_t Hue, uint8_t Saturation, uint8_t brightness, uint8_t & red, uint8_t & green, uint8_t & blue); + +private: + int64_t mLastChangeTimeMS; + uint32_t mBlinkOnTimeMS; + uint32_t mBlinkOffTimeMS; + uint8_t mDefaultOnBrightness; + uint16_t mHue; // mHue [0, 360] + uint8_t mSaturation; // mSaturation [0, 100] + uint8_t mGPIONum; + int mVLED1; + int mVLED2; + bool mState; + bool mError; + TimerHandle_t errorTimer; + + void DoSet(bool state); + + friend void ClearErrorState(TimerHandle_t); +}; diff --git a/examples/lighting-app/bouffalolab/bl602/include/LightingManager.h b/examples/lighting-app/bouffalolab/bl602/include/LightingManager.h new file mode 100644 index 00000000000000..3aa9871e919074 --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/include/LightingManager.h @@ -0,0 +1,85 @@ +/* + * + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include "AppEvent.h" + +#include "FreeRTOS.h" +#include "timers.h" // provides FreeRTOS timer support + +#include + +class LightingManager +{ +public: + enum Action_t + { + ON_ACTION = 0, + OFF_ACTION, + + INVALID_ACTION + } Action; + + enum State_t + { + kState_OffInitiated = 0, + kState_OffCompleted, + kState_OnInitiated, + kState_OnCompleted, + } State; + + CHIP_ERROR Init(); + bool IsLightOn(); + void EnableAutoTurnOff(bool aOn); + void SetAutoTurnOffDuration(uint32_t aDurationInSecs); + bool IsActionInProgress(); + bool InitiateAction(int32_t aActor, Action_t aAction); + + typedef void (*Callback_fn_initiated)(Action_t, int32_t aActor); + typedef void (*Callback_fn_completed)(Action_t); + void SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB); + +private: + friend LightingManager & LightMgr(void); + State_t mState; + + Callback_fn_initiated mActionInitiated_CB; + Callback_fn_completed mActionCompleted_CB; + + bool mAutoTurnOff; + uint32_t mAutoTurnOffDuration; + bool mAutoTurnOffTimerArmed; + + void CancelTimer(void); + void StartTimer(uint32_t aTimeoutMs); + + static void TimerEventHandler(TimerHandle_t xTimer); + static void AutoTurnOffTimerEventHandler(AppEvent * aEvent); + static void ActuatorMovementTimerEventHandler(AppEvent * aEvent); + + static LightingManager sLight; +}; + +inline LightingManager & LightMgr(void) +{ + return LightingManager::sLight; +} diff --git a/examples/lighting-app/bouffalolab/bl602/src/AppTask.cpp b/examples/lighting-app/bouffalolab/bl602/src/AppTask.cpp new file mode 100644 index 00000000000000..8214b3a2a26f91 --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/src/AppTask.cpp @@ -0,0 +1,523 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTask.h" +#include "AppConfig.h" +#include "AppEvent.h" +#include "CHIPDeviceManager.h" +#include "DeviceCallbacks.h" +#include "LEDWidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define FACTORY_RESET_TRIGGER_TIMEOUT 3000 +#define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000 +#define APP_EVENT_QUEUE_SIZE 10 +#define APP_TASK_STACK_SIZE (8192) +#define APP_TASK_PRIORITY 2 +#define STATUS_LED_GPIO_NUM GPIO_NUM_2 // Use LED1 (blue LED) as status LED on DevKitC + +static const char * const TAG = "lighting-app"; +static xTaskHandle OTA_TASK_HANDLE; + +namespace { +TimerHandle_t sFunctionTimer; // FreeRTOS app sw timer. + +BaseType_t sAppTaskHandle; +QueueHandle_t sAppEventQueue; + +bool sHaveBLEConnections = false; + +StackType_t appStack[APP_TASK_STACK_SIZE / sizeof(StackType_t)]; +} // namespace + +using namespace ::chip; +using namespace ::chip::DeviceManager; +using namespace ::chip::DeviceLayer; +using namespace ::chip::Credentials; + +namespace { +chip::app::Clusters::NetworkCommissioning::Instance + sWiFiNetworkCommissioningInstance(0 /* Endpoint Id */, &(NetworkCommissioning::BLWiFiDriver::GetInstance())); +} // namespace + +using namespace ::chip::System; + +AppTask AppTask::sAppTask; +static DeviceCallbacks EchoCallbacks; + +CHIP_ERROR AppTask::StartAppTask() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + sAppEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent)); + if (sAppEventQueue == NULL) + { + log_error("Failed to allocate app event queue\r\n"); + return APP_ERROR_EVENT_QUEUE_FAILED; + } + + // Start App task. + sAppTaskHandle = xTaskCreate(AppTaskMain, APP_TASK_NAME, ArraySize(appStack), NULL, 1, NULL); + if (sAppTaskHandle) + { + err = CHIP_NO_ERROR; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR AppTask::Init() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + // Create FreeRTOS sw timer for Function Selection. + sFunctionTimer = xTimerCreate("FnTmr", // Just a text name, not used by the RTOS kernel + 1, // == default timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = app task obj context + TimerEventHandler // timer callback handler + ); + if (sFunctionTimer == NULL) + { + log_error("funct timer create failed\r\n"); + return APP_ERROR_CREATE_TIMER_FAILED; + } + + err = LightMgr().Init(); + if (err != CHIP_NO_ERROR) + { + log_error("LightMgr().Init() failed\r\n"); + return err; + } + + LightMgr().SetCallbacks(ActionInitiated, ActionCompleted); + + UpdateClusterState(); + + ConfigurationMgr().LogDeviceConfig(); + + PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE)); + return err; +} + +void AppTask::AppTaskMain(void * pvParameter) +{ + AppEvent event; + Clock::Timestamp lastChangeTime = Clock::kZero; + CHIP_ERROR err; + + log_info("App Task entered\r\n"); + + sWiFiNetworkCommissioningInstance.Init(); + chip::Server::GetInstance().Init(); + + // Initialize device attestation config + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); + + err = sAppTask.Init(); + if (err != CHIP_NO_ERROR) + { + log_error("AppTask.Init() failed due to %d\r\n", err); + return; + } + + while (true) + { + BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, pdMS_TO_TICKS(10)); + while (eventReceived == pdTRUE) + { + log_info("receiving event type: %d\r\n", event.Type); + sAppTask.DispatchEvent(&event); + eventReceived = xQueueReceive(sAppEventQueue, &event, 0); + } + // Collect connectivity and configuration state from the CHIP stack. Because + // the CHIP event loop is being run in a separate task, the stack must be + // locked while these values are queried. However we use a non-blocking + // lock request (TryLockCHIPStack()) to avoid blocking other UI activities + // when the CHIP task is busy (e.g. with a long crypto operation). + if (PlatformMgr().TryLockChipStack()) + { + sHaveBLEConnections = (ConnectivityMgr().NumBLEConnections() != 0); + PlatformMgr().UnlockChipStack(); + } + + // Update the status LED if factory reset has not been initiated. + // + // If system has "full connectivity", keep the LED On constantly. + // + // If no connectivity to the service OR subscriptions are not fully + // established THEN blink the LED Off for a short period of time. + // + // If the system has ble connection(s) uptill the stage above, THEN blink + // the LEDs at an even rate of 100ms. + // + // Otherwise, blink the LED ON for a very short time. + if (sAppTask.mFunction != kFunction_FactoryReset) + { + if (sHaveBLEConnections) + { + // TODO: 3R + // sStatusLED.Blink(100, 100); + } + else + { + // TODO: 3R + // sStatusLED.Blink(50, 950); + } + } + + // TODO: 3R + // sStatusLED.Animate(); + + Clock::Timestamp now = SystemClock().GetMonotonicTimestamp(); + Clock::Timestamp nextChangeTime = lastChangeTime + Clock::Seconds16(5); + + if (nextChangeTime < now) + { + lastChangeTime = now; + } + } +} + +void AppTask::LightActionEventHandler(AppEvent * aEvent) +{ + bool initiated = false; + LightingManager::Action_t action; + int32_t actor; + CHIP_ERROR err = CHIP_NO_ERROR; + + if (aEvent->Type == AppEvent::kEventType_Light) + { + action = static_cast(aEvent->LightEvent.Action); + actor = aEvent->LightEvent.Actor; + } + else if (aEvent->Type == AppEvent::kEventType_Button) + { + if (LightMgr().IsLightOn()) + { + action = LightingManager::OFF_ACTION; + } + else + { + action = LightingManager::ON_ACTION; + } + actor = AppEvent::kEventType_Button; + } + else + { + err = APP_ERROR_UNHANDLED_EVENT; + } + + if (err == CHIP_NO_ERROR) + { + initiated = LightMgr().InitiateAction(actor, action); + + if (!initiated) + { + log_info("Action is already in progress or active.\r\n"); + } + } +} + +void AppTask::ButtonEventHandler(uint8_t btnIdx, uint8_t btnAction) +{ +#if 0 // TODO: 3R + if (btnIdx != APP_LOCK_BUTTON && btnIdx != APP_FUNCTION_BUTTON) + { + return; + } +#endif + + AppEvent button_event = {}; + button_event.Type = AppEvent::kEventType_Button; + // button_event.ButtonEvent.PinNo = btnIdx; + button_event.ButtonEvent.Action = btnAction; + + /* if (btnIdx == APP_LOCK_BUTTON && btnAction == APP_BUTTON_PRESSED) + { + button_event.Handler = LockActionEventHandler; + log_info("posting button_event(lock button)\r\n"); + sAppTask.PostEvent(&button_event); + } + else */ + if (btnIdx == APP_FUNCTION_BUTTON) + { + button_event.Handler = FunctionHandler; + log_info("posting button_event(function button)\r\n"); + sAppTask.PostEvent(&button_event); + } +} + +void AppTask::TimerEventHandler(TimerHandle_t xTimer) +{ + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.TimerEvent.Context = (void *) xTimer; + event.Handler = FunctionTimerEventHandler; + sAppTask.PostEvent(&event); +} + +void AppTask::FunctionTimerEventHandler(AppEvent * aEvent) +{ + if (aEvent->Type != AppEvent::kEventType_Timer) + { + return; + } + + // If we reached here, the button was held past FACTORY_RESET_TRIGGER_TIMEOUT, + // initiate factory reset + if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_StartBleAdv) + { + log_info("Factory Reset Triggered. Release button within %ums to cancel.\r\n", FACTORY_RESET_CANCEL_WINDOW_TIMEOUT); + + // Start timer for FACTORY_RESET_CANCEL_WINDOW_TIMEOUT to allow user to + // cancel, if required. + sAppTask.StartTimer(FACTORY_RESET_CANCEL_WINDOW_TIMEOUT); + + sAppTask.mFunction = kFunction_FactoryReset; + } + else if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_FactoryReset) + { + // Actually trigger Factory Reset + sAppTask.mFunction = kFunction_NoneSelected; + ConfigurationMgr().InitiateFactoryReset(); + } +} + +void AppTask::FunctionHandler(AppEvent * aEvent) +{ + // To trigger software update: press the APP_FUNCTION_BUTTON button briefly (< + // FACTORY_RESET_TRIGGER_TIMEOUT) To initiate factory reset: press the + // APP_FUNCTION_BUTTON for FACTORY_RESET_TRIGGER_TIMEOUT + + // FACTORY_RESET_CANCEL_WINDOW_TIMEOUT All LEDs start blinking after + // FACTORY_RESET_TRIGGER_TIMEOUT to signal factory reset has been initiated. + // To cancel factory reset: release the APP_FUNCTION_BUTTON once all LEDs + // start blinking within the FACTORY_RESET_CANCEL_WINDOW_TIMEOUT + if (aEvent->ButtonEvent.Action == APP_BUTTON_PRESSED) + { + if (!sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_NoneSelected) + { + sAppTask.StartTimer(FACTORY_RESET_TRIGGER_TIMEOUT); + sAppTask.mFunction = kFunction_StartBleAdv; + } + } + else + { + // If the button was released before factory reset got initiated, start BLE advertissement in fast mode + if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_StartBleAdv) + { + sAppTask.CancelTimer(); + sAppTask.mFunction = kFunction_NoneSelected; + + if (!ConnectivityMgr().IsThreadProvisioned()) + { + // Enable BLE advertisements + ConnectivityMgr().SetBLEAdvertisingEnabled(true); + ConnectivityMgr().SetBLEAdvertisingMode(ConnectivityMgr().kFastAdvertising); + } + else + { + log_warn("Network is already provisioned, Ble advertissement not enabled\r\n"); + } + } + else if (sAppTask.mFunctionTimerActive && sAppTask.mFunction == kFunction_FactoryReset) + { +#if 0 // TODO: 3R + // Set lock status LED back to show state of lock. + sLockLED.Set(!BoltLockMgr().IsUnlocked()); +#endif + + sAppTask.CancelTimer(); + + // Change the function to none selected since factory reset has been + // canceled. + sAppTask.mFunction = kFunction_NoneSelected; + + log_info("Factory Reset has been Canceled\r\n"); + } + } +} + +void AppTask::CancelTimer() +{ + if (xTimerStop(sFunctionTimer, 0) == pdFAIL) + { + log_error("app timer stop() failed\r\n"); + return; + } + + mFunctionTimerActive = false; +} +void AppTask::StartTimer(uint32_t aTimeoutInMs) +{ + if (xTimerIsTimerActive(sFunctionTimer)) + { + log_warn("app timer already started!\r\n"); + CancelTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sFunctionTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS) + { + log_error("app timer start() failed\r\n"); + return; + } + + mFunctionTimerActive = true; +} + +void AppTask::ActionInitiated(LightingManager::Action_t aAction, int32_t aActor) +{ + // Action initiated, update the light led + if (aAction == LightingManager::ON_ACTION) + { + log_info("Turning light ON\r\n"); +#if 0 // TODO: 3R + sLightLED.Set(true); +#endif + } + else if (aAction == LightingManager::OFF_ACTION) + { + log_info("Turning light OFF\r\n"); +#if 0 // TODO: 3R + sLightLED.Set(false); +#endif + } + + if (aActor == AppEvent::kEventType_Button) + { + sAppTask.mSyncClusterToButtonAction = true; + } +} + +void AppTask::ActionCompleted(LightingManager::Action_t aAction) +{ + // action has been completed bon the light + if (aAction == LightingManager::ON_ACTION) + { + log_info("Light ON\r\n"); + } + else if (aAction == LightingManager::OFF_ACTION) + { + log_info("Light OFF\r\n"); + } + + if (sAppTask.mSyncClusterToButtonAction) + { + UpdateClusterState(); + sAppTask.mSyncClusterToButtonAction = false; + } +} + +void AppTask::PostLightActionRequest(int32_t aActor, LightingManager::Action_t aAction) +{ + AppEvent event; + event.Type = AppEvent::kEventType_Light; + event.LightEvent.Actor = aActor; + event.LightEvent.Action = aAction; + event.Handler = LightActionEventHandler; + PostEvent(&event); +} + +void AppTask::PostEvent(const AppEvent * aEvent) +{ + if (sAppEventQueue != NULL) + { + BaseType_t status; + if (xPortIsInsideInterrupt()) + { + BaseType_t higherPrioTaskWoken = pdFALSE; + log_info("sending event type from isr: %d\r\n", aEvent->Type); + status = xQueueSendFromISR(sAppEventQueue, aEvent, &higherPrioTaskWoken); + +#ifdef portYIELD_FROM_ISR + portYIELD_FROM_ISR(higherPrioTaskWoken); +#elif portEND_SWITCHING_ISR // portYIELD_FROM_ISR or portEND_SWITCHING_ISR + portEND_SWITCHING_ISR(higherPrioTaskWoken); +#else // portYIELD_FROM_ISR or portEND_SWITCHING_ISR +#error "Must have portYIELD_FROM_ISR or portEND_SWITCHING_ISR" +#endif // portYIELD_FROM_ISR or portEND_SWITCHING_ISR + } + else + { + log_info("sending event type: %d\r\n", aEvent->Type); + status = xQueueSend(sAppEventQueue, aEvent, 1); + } + + if (!status) + log_error("Failed to post event to app task event queue\r\n"); + } + else + { + log_error("Event Queue is NULL should never happen\r\n"); + } +} + +void AppTask::DispatchEvent(AppEvent * aEvent) +{ + if (aEvent->Handler) + { + aEvent->Handler(aEvent); + } + else + { + log_warn("Event received with no handler. Dropping event.\r\n"); + } +} + +void AppTask::UpdateClusterState(void) +{ + uint8_t newValue = LightMgr().IsLightOn(); + + // write the new on/off value + EmberAfStatus status = emberAfWriteAttribute(1, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, + (uint8_t *) &newValue, ZCL_BOOLEAN_ATTRIBUTE_TYPE); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + log_error("ERR: updating on/off %x\r\n", status); + } +} + +void AppTask::OtaTask(void) +{ + int ret; + const char * const task_name = "ota task"; + + ret = xTaskCreate(ota_tcp_server, task_name, 512, NULL, 6, &OTA_TASK_HANDLE); + if (ret != pdPASS) + { + printf("unable to start task client task"); + return; + } +} diff --git a/examples/lighting-app/bouffalolab/bl602/src/CHIPDeviceManager.cpp b/examples/lighting-app/bouffalolab/bl602/src/CHIPDeviceManager.cpp new file mode 100644 index 00000000000000..0e64a4f0513248 --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/src/CHIPDeviceManager.cpp @@ -0,0 +1,107 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file implements the CHIP Device Interface that is used by + * applications to interact with the CHIP stack + * + */ + +#include + +#include "CHIPDeviceManager.h" +#include +#include +#include +#include +#include +#include + +using namespace ::chip; + +namespace chip { + +namespace DeviceManager { + +using namespace ::chip::DeviceLayer; + +void CHIPDeviceManager::CommonDeviceEventHandler(const ChipDeviceEvent * event, intptr_t arg) +{ + CHIPDeviceManagerCallbacks * cb = reinterpret_cast(arg); + if (cb != nullptr) + { + cb->DeviceEventCallback(event, reinterpret_cast(cb)); + } +} + +CHIP_ERROR CHIPDeviceManager::Init(CHIPDeviceManagerCallbacks * cb) +{ + CHIP_ERROR err; + mCB = cb; + RendezvousInformationFlags flags = RendezvousInformationFlags(CONFIG_RENDEZVOUS_MODE); + + err = Platform::MemoryInit(); + SuccessOrExit(err); + + // Initialize the CHIP stack. + err = PlatformMgr().InitChipStack(); + SuccessOrExit(err); + + if (flags.Has(RendezvousInformationFlag::kBLE)) + { + ConnectivityMgr().SetBLEAdvertisingEnabled(true); + } + else if (flags.Has(RendezvousInformationFlag::kSoftAP)) + { + // TODO(cecille): Fix for the case where BLE and SoftAP are both enabled.` + ConnectivityMgr().SetBLEAdvertisingEnabled(false); + ConnectivityMgr().SetWiFiAPMode(ConnectivityManager::kWiFiAPMode_Enabled); + } + else + { + // If rendezvous is bypassed, enable SoftAP so that the device can still + // be communicated with via its SoftAP as needed. + // ConnectivityMgr().SetWiFiAPMode(ConnectivityManager::kWiFiAPMode_Enabled); + ConnectivityMgr().IsWiFiStationEnabled(); + } + + // Register a function to receive events from the CHIP device layer. Note that calls to + // this function will happen on the CHIP event loop thread, not the app_main thread. + PlatformMgr().AddEventHandler(CHIPDeviceManager::CommonDeviceEventHandler, reinterpret_cast(cb)); + + // Start a task to run the CHIP Device event loop. + err = PlatformMgr().StartEventLoopTask(); + SuccessOrExit(err); + +exit: + return err; +} +} // namespace DeviceManager +} // namespace chip + +void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t mask, uint8_t type, + uint16_t size, uint8_t * value) +{ + chip::DeviceManager::CHIPDeviceManagerCallbacks * cb = + chip::DeviceManager::CHIPDeviceManager::GetInstance().GetCHIPDeviceManagerCallbacks(); + if (cb != nullptr) + { + cb->PostAttributeChangeCallback(attributePath.mEndpointId, attributePath.mClusterId, attributePath.mAttributeId, mask, type, + size, value); + } +} diff --git a/examples/lighting-app/bouffalolab/bl602/src/DeviceCallbacks.cpp b/examples/lighting-app/bouffalolab/bl602/src/DeviceCallbacks.cpp new file mode 100644 index 00000000000000..caf5a38ec1e0c2 --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/src/DeviceCallbacks.cpp @@ -0,0 +1,252 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file DeviceCallbacks.cpp + * + * Implements all the callbacks to the application from the CHIP Stack + * + **/ +#include "DeviceCallbacks.h" + +#include "CHIPDeviceManager.h" +#include "LEDWidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::System; +using namespace ::chip::DeviceLayer; + +uint32_t identifyTimerCount; +constexpr uint32_t kIdentifyTimerDelayMS = 250; + +static LEDWidget statusLED1; +// static LEDWidget statusLED2; + +void DeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) +{ + switch (event->Type) + { + case DeviceEventType::kInternetConnectivityChange: + OnInternetConnectivityChange(event); + break; + + case DeviceEventType::kSessionEstablished: + OnSessionEstablished(event); + break; + + case DeviceEventType::kCHIPoBLEConnectionEstablished: + log_info("CHIPoBLE connection established\r\n"); + break; + + case DeviceEventType::kCHIPoBLEConnectionClosed: + log_info("CHIPoBLE disconnected\r\n"); + break; + + case DeviceEventType::kCommissioningComplete: + log_info("Commissioning complete\r\n"); + break; + + case DeviceEventType::kWiFiConnectivityChange: + log_info("Got ip, start advertise\r\n"); + // chip::app::DnssdServer::Instance().AdvertiseOperational(); + chip::app::DnssdServer::Instance().StartServer(); + GetAppTask().OtaTask(); + NetworkCommissioning::BLWiFiDriver::GetInstance().SaveConfiguration(); + break; + + case DeviceEventType::kInterfaceIpAddressChanged: + if ((event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV4_Assigned) || + (event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV6_Assigned)) + { + // MDNS server restart on any ip assignment: if link local ipv6 is configured, that + // will not trigger a 'internet connectivity change' as there is no internet + // connectivity. MDNS still wants to refresh its listening interfaces to include the + // newly selected address. + chip::app::DnssdServer::Instance().StartServer(); + } + break; + } +} + +void DeviceCallbacks::PostAttributeChangeCallback(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId, uint8_t mask, + uint8_t type, uint16_t size, uint8_t * value) +{ + log_info("PostAttributeChangeCallback - Cluster ID: '0x%04x', EndPoint ID: '0x%02x', Attribute ID: '0x%04x'\r\n", clusterId, + endpointId, attributeId); + + switch (clusterId) + { + case ZCL_ON_OFF_CLUSTER_ID: + OnOnOffPostAttributeChangeCallback(endpointId, attributeId, value); + break; + + case ZCL_IDENTIFY_CLUSTER_ID: + OnIdentifyPostAttributeChangeCallback(endpointId, attributeId, value); + break; + + case ZCL_LEVEL_CONTROL_CLUSTER_ID: + OnLevelControlAttributeChangeCallback(endpointId, attributeId, value); + break; + case ZCL_COLOR_CONTROL_CLUSTER_ID: + OnColorControlAttributeChangeCallback(endpointId, attributeId, value); + break; + default: + log_info("Unhandled cluster ID: %d\r\n", clusterId); + break; + } + + // TODO + // log_info("Current free heap: %zu\r\n\n", heap_caps_get_free_size(MALLOC_CAP_8BIT)); +} + +void DeviceCallbacks::OnInternetConnectivityChange(const ChipDeviceEvent * event) +{ + if (event->InternetConnectivityChange.IPv4 == kConnectivity_Established) + { + log_info("Server ready at: %s:%d\r\n", event->InternetConnectivityChange.address, CHIP_PORT); + // TODO + // wifiLED.Set(true); + chip::app::DnssdServer::Instance().StartServer(); + } + else if (event->InternetConnectivityChange.IPv4 == kConnectivity_Lost) + { + log_info("Lost IPv4 connectivity...\r\n"); + // TODO + // wifiLED.Set(false); + } + if (event->InternetConnectivityChange.IPv6 == kConnectivity_Established) + { + log_info("IPv6 Server ready...\r\n"); + chip::app::DnssdServer::Instance().StartServer(); + } + else if (event->InternetConnectivityChange.IPv6 == kConnectivity_Lost) + { + log_info("Lost IPv6 connectivity...\r\n"); + } +} + +void DeviceCallbacks::OnSessionEstablished(const ChipDeviceEvent * event) +{ + if (event->SessionEstablished.IsCommissioner) + { + log_info("Commissioner detected!\r\n"); + } +} + +void DeviceCallbacks::OnOnOffPostAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value) +{ + VerifyOrExit(attributeId == ZCL_ON_OFF_ATTRIBUTE_ID, log_info("Unhandled Attribute ID: '0x%04x\r\n", attributeId)); + VerifyOrExit(endpointId == 1 || endpointId == 2, log_info("Unexpected EndPoint ID: `0x%02x'\r\n", endpointId)); + + // At this point we can assume that value points to a bool value. + mEndpointOnOffState[endpointId - 1] = *value; + statusLED1.Set(*value); + +exit: + return; +} + +void DeviceCallbacks::OnLevelControlAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value) +{ + bool onOffState = mEndpointOnOffState[endpointId - 1]; + uint8_t brightness = onOffState ? *value : 0; + + VerifyOrExit(attributeId == ZCL_CURRENT_LEVEL_ATTRIBUTE_ID, log_info("Unhandled Attribute ID: '0x%04x\r\n", attributeId)); + VerifyOrExit(endpointId == 1 || endpointId == 2, log_error("Unexpected EndPoint ID: `0x%02x'\r\n", endpointId)); + + // At this point we can assume that value points to a bool value. + statusLED1.SetBrightness(brightness); + +exit: + return; +} + +void DeviceCallbacks::OnColorControlAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value) +{ + VerifyOrExit(attributeId == ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID || + attributeId == ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID, + log_info("Unhandled AttributeId ID: '0x%04x\r\n", attributeId)); + VerifyOrExit(endpointId == 1 || endpointId == 2, log_error("Unexpected EndPoint ID: `0x%02x'\r\n", endpointId)); + if (endpointId == 1) + { + uint8_t hue, saturation; + if (attributeId == ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID) + { + hue = *value; + emberAfReadServerAttribute(endpointId, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID, + &saturation, sizeof(uint8_t)); + } + else + { + saturation = *value; + emberAfReadServerAttribute(endpointId, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID, &hue, + sizeof(uint8_t)); + } + statusLED1.SetColor(hue, saturation); + } +exit: + return; +} + +void IdentifyTimerHandler(Layer * systemLayer, void * appState) +{ + statusLED1.Animate(); + + if (identifyTimerCount) + { + systemLayer->StartTimer(Clock::Milliseconds32(kIdentifyTimerDelayMS), IdentifyTimerHandler, appState); + // Decrement the timer count. + identifyTimerCount--; + } +} + +void DeviceCallbacks::OnIdentifyPostAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value) +{ + VerifyOrExit(attributeId == ZCL_IDENTIFY_TIME_ATTRIBUTE_ID, log_info("Unhandled Attribute ID: '0x%04x\r\n", attributeId)); + VerifyOrExit(endpointId == 1, log_error("Unexpected EndPoint ID: `0x%02x'\r\n", endpointId)); + + statusLED1.Blink(kIdentifyTimerDelayMS * 2); + + // timerCount represents the number of callback executions before we stop the timer. + // value is expressed in seconds and the timer is fired every 250ms, so just multiply value by 4. + // Also, we want timerCount to be odd number, so the ligth state ends in the same state it starts. + identifyTimerCount = (*value) * 4; + + DeviceLayer::SystemLayer().CancelTimer(IdentifyTimerHandler, this); + DeviceLayer::SystemLayer().StartTimer(Clock::Milliseconds32(kIdentifyTimerDelayMS), IdentifyTimerHandler, this); + +exit: + return; +} + +bool emberAfBasicClusterMfgSpecificPingCallback(chip::app::CommandHandler * commandObj) +{ + emberAfSendDefaultResponse(emberAfCurrentCommand(), EMBER_ZCL_STATUS_SUCCESS); + return true; +} diff --git a/examples/lighting-app/bouffalolab/bl602/src/LEDWidget.cpp b/examples/lighting-app/bouffalolab/bl602/src/LEDWidget.cpp new file mode 100644 index 00000000000000..b79f5b64b6e400 --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/src/LEDWidget.cpp @@ -0,0 +1,240 @@ +/* + * + * Copyright (c) 2018 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file LEDWidget.cpp + * + * Implements an LED Widget controller that is usually tied to a GPIO + * It also updates the display widget if it's enabled + */ + +#include "LEDWidget.h" +#include "AppTask.h" +#include + +#include + +#define IOT_DVK_3S 0 + +#if BOARD_ID == IOT_DVK_3S +hosal_pwm_dev_t pwmR = { .port = 0xff }; +#endif + +static void showRGB(uint8_t red, uint8_t green, uint8_t blue) +{ + +#if BOARD_ID == IOT_DVK_3S + + uint32_t level = (red * 10000) / UINT8_MAX; + log_info("red level: %d\r\n", level); + + if (pwmR.port == 0xff) + { + pwmR.port = 0; + pwmR.config.pin = 0; + pwmR.config.duty_cycle = level; // duty_cycle range is 0~10000 correspond to 0~100% + pwmR.config.freq = 1000; + hosal_pwm_init(&pwmR); + vTaskDelay(50); + hosal_pwm_start(&pwmR); + } + else + { + pwmR.config.duty_cycle = level; // duty_cycle range is 0~10000 correspond to 0~100% + pwmR.config.freq = 1000; + hosal_pwm_para_chg(&pwmR, pwmR.config); + } +#else + + hosal_pwm_dev_t pwmR, pwmG, pwmB; + + uint32_t level = (red * 10000) / UINT8_MAX; + log_info("red level: %d\r\n", level); + pwmR.port = 0; + pwmR.config.pin = 20; + pwmR.config.duty_cycle = level; // duty_cycle range is 0~10000 correspond to 0~100% + pwmR.config.freq = 1000; + hosal_pwm_init(&pwmR); + // vTaskDelay(100); + + level = (green * 10000) / UINT8_MAX; + log_info("green level: %d\r\n", level); + pwmG.port = 1; + pwmG.config.pin = 21; + pwmG.config.duty_cycle = level; // duty_cycle range is 0~10000 correspond to 0~100% + pwmG.config.freq = 1000; + hosal_pwm_init(&pwmG); + // vTaskDelay(100); + + level = (blue * 10000) / UINT8_MAX; + log_info("blue level: %d\r\n", level); + pwmB.port = 2; + pwmB.config.pin = 17; + pwmB.config.duty_cycle = level; // duty_cycle range is 0~10000 correspond to 0~100% + pwmB.config.freq = 1000; + hosal_pwm_init(&pwmB); + vTaskDelay(50); + + hosal_pwm_start(&pwmG); + hosal_pwm_start(&pwmR); + hosal_pwm_start(&pwmB); +#endif +} + +void LEDWidget::Init(uint8_t gpioNum) +{ + mLastChangeTimeMS = 0; + mBlinkOnTimeMS = 0; + mBlinkOffTimeMS = 0; + mGPIONum = gpioNum; + mVLED1 = -1; + mVLED2 = -1; + mState = false; + mError = false; + errorTimer = NULL; + + mDefaultOnBrightness = UINT8_MAX; + mHue = 0; + mSaturation = 0; +} + +void LEDWidget::Set(bool state) +{ + log_info("state: %d\r\n", state); + mBlinkOnTimeMS = mBlinkOffTimeMS = 0; + DoSet(state); +} + +void LEDWidget::SetBrightness(uint8_t brightness) +{ + uint8_t red, green, blue; + log_info("mDefaultOnBrightness: %d, brightness: %d\r\n", mDefaultOnBrightness, brightness); + HSB2rgb(mHue, mSaturation, brightness, red, green, blue); + log_info("brightness: %d, mHue: %d, mSaturation: %d, red: %d, green: %d, blue: %d\r\n", brightness, mHue, mSaturation, red, + green, blue); + showRGB(red, green, blue); + + if (brightness > 0) + { + mDefaultOnBrightness = brightness; + } +} + +void LEDWidget::Blink(uint32_t changeRateMS) +{ + Blink(changeRateMS, changeRateMS); +} + +void LEDWidget::Blink(uint32_t onTimeMS, uint32_t offTimeMS) +{ + mBlinkOnTimeMS = onTimeMS; + mBlinkOffTimeMS = offTimeMS; + Animate(); +} + +void ClearErrorState(TimerHandle_t handle) {} + +void LEDWidget::BlinkOnError() {} + +void LEDWidget::Animate() +{ + if (mBlinkOnTimeMS != 0 && mBlinkOffTimeMS != 0) + { + uint64_t nowMS = chip::System::SystemClock().GetMonotonicMilliseconds64().count(); + uint64_t stateDurMS = ((mState) ? mBlinkOnTimeMS : mBlinkOffTimeMS); + uint64_t nextChangeTimeMS = mLastChangeTimeMS + stateDurMS; + + if (nextChangeTimeMS < nowMS) + { + // DoSet(!mState); + mLastChangeTimeMS = nowMS; + } + } +} + +void LEDWidget::DoSet(bool state) +{ + bool stateChange = (mState != state); + mState = state; + + uint8_t red, green, blue; + uint8_t brightness = state ? mDefaultOnBrightness : 0; + log_info("state: %d, mDefaultOnBrightness: %d, brightness: %d\r\n", state, mDefaultOnBrightness, brightness); + HSB2rgb(mHue, mSaturation, brightness, red, green, blue); + log_info("brightness: %d, mHue: %d, mSaturation: %d, red: %d, green: %d, blue: %d\r\n", brightness, mHue, mSaturation, red, + green, blue); + showRGB(red, green, blue); +} + +void LEDWidget::SetColor(uint8_t Hue, uint8_t Saturation) +{ + uint8_t red, green, blue; + uint8_t brightness = mState ? mDefaultOnBrightness : 0; + mHue = static_cast(Hue) * 360 / 254; // mHue [0, 360] + mSaturation = static_cast(Saturation) * 100 / 254; // mSaturation [0 , 100] + + HSB2rgb(mHue, mSaturation, brightness, red, green, blue); + + log_info("mDefaultOnBrightness: %d, mHue: %d, mSaturation: %d\r\n", mDefaultOnBrightness, mHue, mSaturation); + HSB2rgb(mHue, mSaturation, brightness, red, green, blue); + log_info("brightness: %d, red: %d, green: %d, blue: %d\r\n", brightness, red, green, blue); + showRGB(red, green, blue); +} + +void LEDWidget::HSB2rgb(uint16_t Hue, uint8_t Saturation, uint8_t brightness, uint8_t & red, uint8_t & green, uint8_t & blue) +{ + uint16_t i = Hue / 60; + uint16_t rgb_max = brightness; + uint16_t rgb_min = rgb_max * (100 - Saturation) / 100; + uint16_t diff = Hue % 60; + uint16_t rgb_adj = (rgb_max - rgb_min) * diff / 60; + + switch (i) + { + case 0: + red = rgb_max; + green = rgb_min + rgb_adj; + blue = rgb_min; + break; + case 1: + red = rgb_max - rgb_adj; + green = rgb_max; + blue = rgb_min; + break; + case 2: + red = rgb_min; + green = rgb_max; + blue = rgb_min + rgb_adj; + break; + case 3: + red = rgb_min; + green = rgb_max - rgb_adj; + blue = rgb_max; + break; + case 4: + red = rgb_min + rgb_adj; + green = rgb_min; + blue = rgb_max; + break; + default: + red = rgb_max; + green = rgb_min; + blue = rgb_max - rgb_adj; + break; + } +} diff --git a/examples/lighting-app/bouffalolab/bl602/src/LightingManager.cpp b/examples/lighting-app/bouffalolab/bl602/src/LightingManager.cpp new file mode 100644 index 00000000000000..ca4723c3b26f86 --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/src/LightingManager.cpp @@ -0,0 +1,225 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "LightingManager.h" + +#include "AppConfig.h" +#include "AppTask.h" +#include + +LightingManager LightingManager::sLight; + +TimerHandle_t sLightTimer; + +CHIP_ERROR LightingManager::Init() +{ + // Create FreeRTOS sw timer for light timer. + sLightTimer = xTimerCreate("lightTmr", // Just a text name, not used by the RTOS kernel + 1, // == default timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = light obj context + TimerEventHandler // timer callback handler + ); + + if (sLightTimer == NULL) + { + log_error("sLightTimer timer create failed\r\n"); + return APP_ERROR_CREATE_TIMER_FAILED; + } + + mState = kState_OffCompleted; + mAutoTurnOffTimerArmed = false; + mAutoTurnOff = false; + mAutoTurnOffDuration = 0; + + return CHIP_NO_ERROR; +} + +void LightingManager::SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB) +{ + mActionInitiated_CB = aActionInitiated_CB; + mActionCompleted_CB = aActionCompleted_CB; +} + +bool LightingManager::IsActionInProgress() +{ + return (mState == kState_OffInitiated || mState == kState_OnInitiated); +} + +bool LightingManager::IsLightOn() +{ + return (mState == kState_OnCompleted); +} + +void LightingManager::EnableAutoTurnOff(bool aOn) +{ + mAutoTurnOff = aOn; +} + +void LightingManager::SetAutoTurnOffDuration(uint32_t aDurationInSecs) +{ + mAutoTurnOffDuration = aDurationInSecs; +} + +bool LightingManager::InitiateAction(int32_t aActor, Action_t aAction) +{ + bool action_initiated = false; + State_t new_state; + + // Initiate Turn On/Off Action only when the previous one is complete. + if (mState == kState_OffCompleted && aAction == ON_ACTION) + { + action_initiated = true; + + new_state = kState_OnInitiated; + } + else if (mState == kState_OnCompleted && aAction == OFF_ACTION) + { + action_initiated = true; + + new_state = kState_OffInitiated; + } + + if (action_initiated) + { + if (mAutoTurnOffTimerArmed && new_state == kState_OffInitiated) + { + // If auto turn off timer has been armed and someone initiates turning off, + // cancel the timer and continue as normal. + mAutoTurnOffTimerArmed = false; + + CancelTimer(); + } + + StartTimer(ACTUATOR_MOVEMENT_PERIOS_MS); + + // Since the timer started successfully, update the state and trigger callback + mState = new_state; + + if (mActionInitiated_CB) + { + mActionInitiated_CB(aAction, aActor); + } + } + + return action_initiated; +} + +void LightingManager::StartTimer(uint32_t aTimeoutMs) +{ + if (xTimerIsTimerActive(sLightTimer)) + { + log_error("app timer already started!\r\n"); + CancelTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sLightTimer, (aTimeoutMs / portTICK_PERIOD_MS), 100) != pdPASS) + { + log_error("sLightTimer timer start() failed\r\n"); + appError(APP_ERROR_START_TIMER_FAILED); + } +} + +void LightingManager::CancelTimer(void) +{ + if (xTimerStop(sLightTimer, 0) == pdFAIL) + { + log_error("sLightTimer stop() failed\r\n"); + appError(APP_ERROR_STOP_TIMER_FAILED); + } +} + +void LightingManager::TimerEventHandler(TimerHandle_t xTimer) +{ + // Get light obj context from timer id. + LightingManager * light = static_cast(pvTimerGetTimerID(xTimer)); + + // The timer event handler will be called in the context of the timer task + // once sLightTimer expires. Post an event to apptask queue with the actual handler + // so that the event can be handled in the context of the apptask. + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.TimerEvent.Context = light; + if (light->mAutoTurnOffTimerArmed) + { + event.Handler = AutoTurnOffTimerEventHandler; + } + else + { + event.Handler = ActuatorMovementTimerEventHandler; + } + GetAppTask().PostEvent(&event); +} + +void LightingManager::AutoTurnOffTimerEventHandler(AppEvent * aEvent) +{ + LightingManager * light = static_cast(aEvent->TimerEvent.Context); + int32_t actor = 0; + + // Make sure auto turn off timer is still armed. + if (!light->mAutoTurnOffTimerArmed) + { + return; + } + + light->mAutoTurnOffTimerArmed = false; + + log_info("Auto Turn Off has been triggered!\r\n"); + + light->InitiateAction(actor, OFF_ACTION); +} + +void LightingManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent) +{ + Action_t actionCompleted = INVALID_ACTION; + + LightingManager * light = static_cast(aEvent->TimerEvent.Context); + + if (light->mState == kState_OffInitiated) + { + light->mState = kState_OffCompleted; + actionCompleted = OFF_ACTION; + } + else if (light->mState == kState_OnInitiated) + { + light->mState = kState_OnCompleted; + actionCompleted = ON_ACTION; + } + + if (actionCompleted != INVALID_ACTION) + { + if (light->mActionCompleted_CB) + { + light->mActionCompleted_CB(actionCompleted); + } + + if (light->mAutoTurnOff && actionCompleted == ON_ACTION) + { + // Start the timer for auto turn off + light->StartTimer(light->mAutoTurnOffDuration * 1000); + + light->mAutoTurnOffTimerArmed = true; + + log_info("Auto Turn off enabled. Will be triggered in %u seconds\r\n", light->mAutoTurnOffDuration); + } + } +} diff --git a/examples/lighting-app/bouffalolab/bl602/src/main.cpp b/examples/lighting-app/bouffalolab/bl602/src/main.cpp new file mode 100644 index 00000000000000..9f0cc914fb8095 --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/src/main.cpp @@ -0,0 +1,113 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTask.h" +#include "CHIPDeviceManager.h" +#include "DeviceCallbacks.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#if CONFIG_ENABLE_PW_RPC +#include "PigweedLogger.h" +#include "Rpc.h" +#endif + +#include + +using namespace ::chip; +using namespace ::chip::DeviceManager; +using namespace ::chip::DeviceLayer; +using namespace ::chip::Credentials; + +void appError(int err) +{ + log_error("!!!!!!!!!!!! App Critical Error: %d !!!!!!!!!!!\r\n", err); + portDISABLE_INTERRUPTS(); + while (1) + ; +} + +void appError(CHIP_ERROR error) +{ + appError(static_cast(error.AsInteger())); +} + +static const char * TAG = "light-app"; + +static DeviceCallbacks EchoCallbacks; + +namespace { +app::Clusters::NetworkCommissioning::Instance + sWiFiNetworkCommissioningInstance(0 /* Endpoint Id */, &(NetworkCommissioning::BLWiFiDriver::GetInstance())); +} // namespace + +static void InitServer(intptr_t context) +{ + chip::Server::GetInstance().Init(); + + // Initialize device attestation config + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); + + sWiFiNetworkCommissioningInstance.Init(); +} + +extern "C" int main() +{ + InitPlatform(); + +#if CONFIG_ENABLE_PW_RPC + chip::rpc::Init(); +#endif + + log_info("==================================================\r\n"); + log_info("chip-bl602-lighting-example starting\r\n"); + log_info("==================================================\r\n"); + +#if CONFIG_ENABLE_CHIP_SHELL + chip::LaunchShell(); +#endif + + log_info("------------------------Starting App Task---------------------------\r\n"); + + CHIPDeviceManager & deviceMgr = CHIPDeviceManager::GetInstance(); + CHIP_ERROR error = deviceMgr.Init(&EchoCallbacks); + if (error != CHIP_NO_ERROR) + { + log_info("device init failed: %s", ErrorStr(error)); + return; + } + + CHIP_ERROR err = GetAppTask().StartAppTask(); + if (err != CHIP_NO_ERROR) + { + log_error("GetAppTask().Init() failed\r\n"); + return 1; + } +} diff --git a/examples/lighting-app/bouffalolab/bl602/third_party/connectedhomeip b/examples/lighting-app/bouffalolab/bl602/third_party/connectedhomeip new file mode 120000 index 00000000000000..59307833b4fee9 --- /dev/null +++ b/examples/lighting-app/bouffalolab/bl602/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../.. \ No newline at end of file diff --git a/examples/platform/bouffalolab/bl602/BUILD.gn b/examples/platform/bouffalolab/bl602/BUILD.gn new file mode 100644 index 00000000000000..f7897e69f17d8a --- /dev/null +++ b/examples/platform/bouffalolab/bl602/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/bl602_sdk.gni") +import("//build_overrides/chip.gni") + +import("${bl602_sdk_build_root}/bl602_sdk.gni") + +config("chip_examples_project_config") { + include_dirs = [ "project_include" ] +} diff --git a/examples/platform/bouffalolab/bl602/InitPlatform.cpp b/examples/platform/bouffalolab/bl602/InitPlatform.cpp new file mode 100644 index 00000000000000..1df65555ed1dfe --- /dev/null +++ b/examples/platform/bouffalolab/bl602/InitPlatform.cpp @@ -0,0 +1,219 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void user_vAssertCalled(void) __attribute__((weak, alias("vAssertCalled"))); +void vAssertCalled(void) +{ + volatile uint32_t ulSetTo1ToExitFunction = 0; + + taskDISABLE_INTERRUPTS(); + while (ulSetTo1ToExitFunction != 1) + { + __asm volatile("NOP"); + } +} + +void vApplicationMallocFailedHook(void) +{ + printf("Memory Allocate Failed. Current left size is %d bytes\r\n", xPortGetFreeHeapSize()); + while (1) + { + /*empty here*/ + } +} + +void vApplicationIdleHook(void) +{ + __asm volatile(" wfi "); + /*empty*/ +} + +#if (configUSE_TICKLESS_IDLE != 0) +void vApplicationSleep(TickType_t xExpectedIdleTime_ms) +{ +#if defined(CFG_BLE_PDS) + int32_t bleSleepDuration_32768cycles = 0; + int32_t expectedIdleTime_32768cycles = 0; + eSleepModeStatus eSleepStatus; + bool freertos_max_idle = false; + + if (pds_start == 0) + return; + + if (xExpectedIdleTime_ms + xTaskGetTickCount() == portMAX_DELAY) + { + freertos_max_idle = true; + } + else + { + xExpectedIdleTime_ms -= 1; + expectedIdleTime_32768cycles = 32768 * xExpectedIdleTime_ms / 1000; + } + + if ((!freertos_max_idle) && (expectedIdleTime_32768cycles < TIME_5MS_IN_32768CYCLE)) + { + return; + } + + /*Disable mtimer interrrupt*/ + *(volatile uint8_t *) configCLIC_TIMER_ENABLE_ADDRESS = 0; + + eSleepStatus = eTaskConfirmSleepModeStatus(); + if (eSleepStatus == eAbortSleep || ble_controller_sleep_is_ongoing()) + { + /*A task has been moved out of the Blocked state since this macro was + executed, or a context siwth is being held pending.Restart the tick + and exit the critical section. */ + /*Enable mtimer interrrupt*/ + *(volatile uint8_t *) configCLIC_TIMER_ENABLE_ADDRESS = 1; + // printf("%s:not do ble sleep\r\n", __func__); + return; + } + + bleSleepDuration_32768cycles = ble_controller_sleep(); + + if (bleSleepDuration_32768cycles < TIME_5MS_IN_32768CYCLE) + { + /*BLE controller does not allow sleep. Do not enter a sleep state.Restart the tick + and exit the critical section. */ + /*Enable mtimer interrrupt*/ + // printf("%s:not do pds sleep\r\n", __func__); + *(volatile uint8_t *) configCLIC_TIMER_ENABLE_ADDRESS = 1; + } + else + { + printf("%s:bleSleepDuration_32768cycles=%ld\r\n", __func__, bleSleepDuration_32768cycles); + if (eSleepStatus == eStandardSleep && + ((!freertos_max_idle) && (expectedIdleTime_32768cycles < bleSleepDuration_32768cycles))) + { + hal_pds_enter_with_time_compensation(1, expectedIdleTime_32768cycles - 40); // 40);//20); + } + else + { + hal_pds_enter_with_time_compensation(1, bleSleepDuration_32768cycles - 40); // 40);//20); + } + } +#endif +} +#endif + +void vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, + uint32_t * pulIdleTaskStackSize) +{ + /* If the buffers to be provided to the Idle task are declared inside this + function then they must be declared static - otherwise they will be allocated on + the stack and so not exists after this function exits. */ + static StaticTask_t xIdleTaskTCB; + // static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; + static StackType_t uxIdleTaskStack[512]; + + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + state will be stored. */ + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + //*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; + *pulIdleTaskStackSize = 512; // size 512 words is For ble pds mode, otherwise stack overflow of idle task will happen. +} + +static void event_cb_key_event(input_event_t * event, void * private_data) +{ + switch (event->code) + { + case KEY_1: { + log_info("[KEY_1] [EVT] INIT DONE %lld\r\n", aos_now_ms()); + log_info("short press \r\n"); + + log_info("factory reset. erasing easyflash...\r\n"); + ef_port_erase_all(); + log_info("factory reset. rebooting...\r\n"); + hal_reboot(); + } + break; + case KEY_2: { + log_info("[KEY_2] [EVT] INIT DONE %lld\r\n", aos_now_ms()); + log_info("long press \r\n"); + } + break; + case KEY_3: { + log_info("[KEY_3] [EVT] INIT DONE %lld\r\n", aos_now_ms()); + log_info("longlong press \r\n"); + // xTaskCreate(task_factory_reset, "factory-reset", 256, NULL, 10, NULL); + } + break; + default: { + log_info("[KEY] [EVT] Unknown code %u, %lld\r\n", event->code, aos_now_ms()); + /*nothing*/ + } + } +} + +extern int get_dts_addr(const char * name, uint32_t * start, uint32_t * off); + +void InitPlatform(void) +{ + bl_sys_init(); + + uint32_t fdt = 0, offset = 0; + if (0 == get_dts_addr("gpio", &fdt, &offset)) + { + hal_gpio_init_from_dts(fdt, offset); + fdt_button_module_init((const void *) fdt, (int) offset); + } + + aos_register_event_filter(EV_KEY, event_cb_key_event, NULL); +} + +#ifdef __cplusplus +} +#endif diff --git a/examples/platform/bouffalolab/bl602/InitPlatform.h b/examples/platform/bouffalolab/bl602/InitPlatform.h new file mode 100644 index 00000000000000..c8300268216c5c --- /dev/null +++ b/examples/platform/bouffalolab/bl602/InitPlatform.h @@ -0,0 +1,33 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*******************************************************************************/ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +// #include "board_features.h" +// #include "hal-config-board.h" +#include + +void InitPlatform(void); + +#ifdef __cplusplus +} +#endif diff --git a/examples/platform/bouffalolab/bl602/LEDWidget.cpp b/examples/platform/bouffalolab/bl602/LEDWidget.cpp new file mode 100644 index 00000000000000..8810de566452ed --- /dev/null +++ b/examples/platform/bouffalolab/bl602/LEDWidget.cpp @@ -0,0 +1,94 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "LEDWidget.h" + +#include + +void LEDWidget::InitGpio(void) +{ + // Sets gpio pin mode for ALL board Leds. + // BSP_LedsInit(); + // TODO: 3R +} + +void LEDWidget::Init(int ledNum) +{ + mLastChangeTimeUS = 0; + mBlinkOnTimeMS = 0; + mBlinkOffTimeMS = 0; + mLedNum = ledNum; + + Set(false); +} + +void LEDWidget::Invert(void) +{ + Set(!mState); +} + +void LEDWidget::Set(bool state) +{ + mLastChangeTimeUS = mBlinkOnTimeMS = mBlinkOffTimeMS = 0; + DoSet(state); +} + +void LEDWidget::Blink(uint32_t changeRateMS) +{ + Blink(changeRateMS, changeRateMS); +} + +void LEDWidget::Blink(uint32_t onTimeMS, uint32_t offTimeMS) +{ + mBlinkOnTimeMS = onTimeMS; + mBlinkOffTimeMS = offTimeMS; + Animate(); +} + +void LEDWidget::Animate() +{ + if (mBlinkOnTimeMS != 0 && mBlinkOffTimeMS != 0) + { + int64_t nowUS = ::chip::System::Layer::GetClock_MonotonicHiRes(); + int64_t stateDurUS = ((mState) ? mBlinkOnTimeMS : mBlinkOffTimeMS) * 1000LL; + int64_t nextChangeTimeUS = mLastChangeTimeUS + stateDurUS; + + if (nowUS > nextChangeTimeUS) + { + DoSet(!mState); + mLastChangeTimeUS = nowUS; + } + } +} + +void LEDWidget::DoSet(bool state) +{ + mState = state; + + if (state) + { + // BSP_LedSet(mLedNum); + // TODO: 3R + } + else + { + // BSP_LedClear(mLedNum); + // TODO: 3R + } +} diff --git a/examples/platform/bouffalolab/bl602/MemMonitoring.cpp b/examples/platform/bouffalolab/bl602/MemMonitoring.cpp new file mode 100644 index 00000000000000..edeea2ddf06281 --- /dev/null +++ b/examples/platform/bouffalolab/bl602/MemMonitoring.cpp @@ -0,0 +1,102 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MemMonitoring.h" + +#include "AppConfig.h" +#include "FreeRTOS.h" +#include +#include + +static StackType_t monitoringStack[MONITORING_STACK_SIZE_byte / sizeof(StackType_t)]; +static StaticTask_t monitoringTaskStruct; + +size_t nbAllocSuccess = 0; +size_t nbFreeSuccess = 0; +size_t largestBlockAllocated = 0; + +void MemMonitoring::startHeapMonitoring() +{ + xTaskCreateStatic(HeapMonitoring, "Monitoring", MONITORING_STACK_SIZE_byte / sizeof(StackType_t), NULL, 1, monitoringStack, + &monitoringTaskStruct); +} + +void MemMonitoring::HeapMonitoring(void * pvParameter) +{ + + UBaseType_t appTaskValue; + UBaseType_t bleEventTaskValue; + UBaseType_t bleTaskValue; + UBaseType_t linkLayerTaskValue; + UBaseType_t openThreadTaskValue; + UBaseType_t eventLoopTaskValue; + UBaseType_t lwipTaskValue; + + TaskHandle_t eventLoopHandleStruct = xTaskGetHandle(CHIP_DEVICE_CONFIG_CHIP_TASK_NAME); + TaskHandle_t lwipHandle = xTaskGetHandle(TCPIP_THREAD_NAME); + TaskHandle_t otTaskHandle = xTaskGetHandle(CHIP_DEVICE_CONFIG_THREAD_TASK_NAME); + TaskHandle_t appTaskHandle = xTaskGetHandle(APP_TASK_NAME); + TaskHandle_t bleStackTaskHandle = xTaskGetHandle(BLE_STACK_TASK_NAME); + TaskHandle_t bleLinkTaskHandle = xTaskGetHandle(BLE_LINK_TASK_NAME); + TaskHandle_t bleEventTaskHandle = xTaskGetHandle(CHIP_DEVICE_CONFIG_BLE_APP_TASK_NAME); + + while (1) + { + appTaskValue = uxTaskGetStackHighWaterMark(appTaskHandle); + bleEventTaskValue = uxTaskGetStackHighWaterMark(bleEventTaskHandle); + bleTaskValue = uxTaskGetStackHighWaterMark(bleStackTaskHandle); + linkLayerTaskValue = uxTaskGetStackHighWaterMark(bleLinkTaskHandle); + openThreadTaskValue = uxTaskGetStackHighWaterMark(otTaskHandle); + eventLoopTaskValue = uxTaskGetStackHighWaterMark(eventLoopHandleStruct); + lwipTaskValue = uxTaskGetStackHighWaterMark(lwipHandle); + + EFR32_LOG("============================="); + EFR32_LOG(" "); + EFR32_LOG("Largest Block allocated 0x%x", largestBlockAllocated); + EFR32_LOG("Number Of Successful Alloc 0x%x", nbAllocSuccess); + EFR32_LOG("Number Of Successful Frees 0x%x", nbFreeSuccess); + EFR32_LOG(" "); + EFR32_LOG("App Task most bytes ever Free 0x%x", (appTaskValue * 4)); + EFR32_LOG("BLE Event most bytes ever Free 0x%x", (bleEventTaskValue * 4)); + EFR32_LOG("BLE Stack most bytes ever Free 0x%x", (bleTaskValue * 4)); + EFR32_LOG("Link Layer Task most bytes ever Free 0x%x", (linkLayerTaskValue * 4)); + EFR32_LOG("OpenThread Task most bytes ever Free 0x%x", (openThreadTaskValue * 4)); + EFR32_LOG("Event Loop Task most bytes ever Free 0x%x", (eventLoopTaskValue * 4)); + EFR32_LOG("LWIP Task most bytes ever Free 0x%x", (lwipTaskValue * 4)); + EFR32_LOG(" "); + EFR32_LOG("============================="); + vTaskDelay(pdMS_TO_TICKS(5000)); + } +} + +extern "C" void memMonitoringTrackAlloc(void * ptr, size_t size) +{ + if (ptr != NULL) + { + nbAllocSuccess++; + if (largestBlockAllocated < size) + { + largestBlockAllocated = size; + } + } +} + +extern "C" void memMonitoringTrackFree(void * ptr, size_t size) +{ + nbFreeSuccess++; +} diff --git a/examples/platform/bouffalolab/bl602/MemMonitoring.h b/examples/platform/bouffalolab/bl602/MemMonitoring.h new file mode 100644 index 00000000000000..ffc430ccaf3193 --- /dev/null +++ b/examples/platform/bouffalolab/bl602/MemMonitoring.h @@ -0,0 +1,35 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#ifdef HEAP_MONITORING +#include "FreeRTOS.h" + +#define MONITORING_STACK_SIZE_byte 1024 + +class MemMonitoring +{ +public: + static void startHeapMonitoring(); + +private: + static void HeapMonitoring(void * pvParameter); +}; + +#endif diff --git a/examples/platform/bouffalolab/bl602/PigweedLogger.cpp b/examples/platform/bouffalolab/bl602/PigweedLogger.cpp new file mode 100644 index 00000000000000..065161021f6b51 --- /dev/null +++ b/examples/platform/bouffalolab/bl602/PigweedLogger.cpp @@ -0,0 +1,103 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file PigweedLogger.cpp + * + * This file contains basic string writing function, based on Pigweed HDLC + * over UART transport. It allows to send log messages even if the application + * needs to use HDLC/UART for another purpose like the RPC server. + */ + +#include + +#include "semphr.h" +#include +#include +#include + +#include +#include +#include +#include + +namespace PigweedLogger { +namespace { + +constexpr uint8_t kLogHdlcAddress = 1; // Send log messages to HDLC address 1 (other than RPC communication) +constexpr size_t kWriteBufferSize = 128; // Buffer for constructing HDLC frames + +// Exclusive access to the backend is needed to make sure that log messages coming +// from different threads are not interwoven. +SemaphoreHandle_t sLoggerLock; + +static pw::stream::SysIoWriter sWriter; +static size_t sWriteBufferPos; +static char sWriteBuffer[kWriteBufferSize]; + +static void send(void) +{ + pw::hdlc::WriteUIFrame(kLogHdlcAddress, std::as_bytes(std::span(sWriteBuffer, sWriteBufferPos)), sWriter); + sWriteBufferPos = 0; +} + +} // namespace + +void init(void) +{ + sLoggerLock = xSemaphoreCreateMutex(); + assert(sLoggerLock != NULL); + + pw_sys_io_Init(); +} + +int putString(const char * buffer, size_t size) +{ + assert(sWriteBufferPos < kWriteBufferSize); + + xSemaphoreTake(sLoggerLock, portMAX_DELAY); + + for (size_t i = 0; i < size; ++i) + { + // Send each line excluding "\r\n" in a separate frame + + if (buffer[i] == '\r') + continue; + + if (buffer[i] == '\n') + { + send(); + continue; + } + + sWriteBuffer[sWriteBufferPos++] = buffer[i]; + + if (sWriteBufferPos == kWriteBufferSize) + send(); + } + + xSemaphoreGive(sLoggerLock); + return size; +} + +SemaphoreHandle_t * GetSemaphore() +{ + return &sLoggerLock; +} + +} // namespace PigweedLogger diff --git a/examples/platform/bouffalolab/bl602/PigweedLogger.h b/examples/platform/bouffalolab/bl602/PigweedLogger.h new file mode 100644 index 00000000000000..9907ade58772da --- /dev/null +++ b/examples/platform/bouffalolab/bl602/PigweedLogger.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "semphr.h" +#include + +namespace PigweedLogger { + +void init(void); +int putString(const char * buffer, size_t size); +SemaphoreHandle_t * GetSemaphore(); + +} // namespace PigweedLogger diff --git a/examples/platform/bouffalolab/bl602/Service.cpp b/examples/platform/bouffalolab/bl602/Service.cpp new file mode 100644 index 00000000000000..521550c9b44335 --- /dev/null +++ b/examples/platform/bouffalolab/bl602/Service.cpp @@ -0,0 +1,102 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Service.h" + +#include "AppConfig.h" +#include "FreeRTOS.h" +#include "task.h" +#include +#include + +#include "lwip/err.h" +#include "lwip/sockets.h" +#include "lwip/sys.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::Transport; +using namespace ::chip::DeviceLayer; + +static char sDeviceName[128] = { 0 }; +// Hardcode UDP BroadcastPort. Temporary use for demo with OTBR +constexpr uint16_t kUDPBroadcastPort = 23367; + +void SetDeviceName(const char * newDeviceName) +{ + strncpy(sDeviceName, newDeviceName, sizeof(sDeviceName) - 1); +} + +void PublishService() +{ + chip::Inet::IPAddress addr; + if (!ConnectivityMgrImpl().IsThreadAttached()) + { + return; + } + ThreadStackMgrImpl().LockThreadStack(); + otError error = OT_ERROR_NONE; + otMessageInfo messageInfo; + otUdpSocket mSocket; + otMessage * message = nullptr; + + memset(&mSocket, 0, sizeof(mSocket)); + memset(&messageInfo, 0, sizeof(messageInfo)); + + // Use mesh local EID by default, if we have GUA, use that IP address. + memcpy(&messageInfo.mSockAddr, otThreadGetMeshLocalEid(ThreadStackMgrImpl().OTInstance()), sizeof(messageInfo.mSockAddr)); + + // Select a address to send + const otNetifAddress * otAddrs = otIp6GetUnicastAddresses(ThreadStackMgrImpl().OTInstance()); + for (const otNetifAddress * otAddr = otAddrs; otAddr != NULL; otAddr = otAddr->mNext) + { + addr = chip::DeviceLayer::Internal::ToIPAddress(otAddr->mAddress); + if (otAddr->mValid && addr.IsIPv6GlobalUnicast()) + { + memcpy(&messageInfo.mSockAddr, &(otAddr->mAddress), sizeof(otAddr->mAddress)); + break; + } + } + + message = otUdpNewMessage(ThreadStackMgrImpl().OTInstance(), nullptr); + otIp6AddressFromString("ff03::1", &messageInfo.mPeerAddr); + messageInfo.mPeerPort = kUDPBroadcastPort; + otMessageAppend(message, sDeviceName, static_cast(strlen(sDeviceName))); + + error = otUdpSend(ThreadStackMgrImpl().OTInstance(), &mSocket, message, &messageInfo); + + if (error != OT_ERROR_NONE && message != nullptr) + { + otMessageFree(message); + log_error("Failed to otUdpSend: %d", error); + } + ThreadStackMgrImpl().UnlockThreadStack(); +} diff --git a/examples/platform/bouffalolab/bl602/Service.h b/examples/platform/bouffalolab/bl602/Service.h new file mode 100644 index 00000000000000..1426ec65adec71 --- /dev/null +++ b/examples/platform/bouffalolab/bl602/Service.h @@ -0,0 +1,21 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +void SetDeviceName(const char * newDeviceName); +void PublishService(); diff --git a/examples/platform/bouffalolab/bl602/args.gni b/examples/platform/bouffalolab/bl602/args.gni new file mode 100644 index 00000000000000..62d03a209dc9e0 --- /dev/null +++ b/examples/platform/bouffalolab/bl602/args.gni @@ -0,0 +1,24 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") + +chip_ble_project_config_include = "" +chip_device_project_config_include = "" +chip_project_config_include = "" +chip_inet_project_config_include = "" +chip_system_project_config_include = "" + +chip_project_config_include_dirs = + [ "${chip_root}/examples/lighting-app/bouffalolab/bl602/include" ] diff --git a/examples/platform/bouffalolab/bl602/board_config.h b/examples/platform/bouffalolab/bl602/board_config.h new file mode 100644 index 00000000000000..b832acf584bcdf --- /dev/null +++ b/examples/platform/bouffalolab/bl602/board_config.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file includes dev borad compile-time configuration constants for efr32. + * + */ + +#pragma once + +/// Dev board suppports OQPSK modulation in 2.4GHz band. +#if (BRD4161A || BRD4163A || BRD4164A || BRD4166A || BRD4170A || BRD4304A || BRD4180A) +#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 +#else +#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 0 +#endif + +/// Dev board doesn't support OQPSK modulation in 915MHz band. +#if (BRD4170A) +#define RADIO_CONFIG_915MHZ_OQPSK_SUPPORT 1 +#else +#define RADIO_CONFIG_915MHZ_OQPSK_SUPPORT 0 +#endif + +/// The PA(s) is(are) fed from the DCDC +#if (BRD4166A) +#define RADIO_CONFIG_PA_USES_DCDC 1 +#else +#define RADIO_CONFIG_PA_USES_DCDC 0 +#endif + +#ifndef RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT +#define RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT 0 /// Set to 1 to enable debug counters in radio.c +#endif + +#ifndef RADIO_CONFIG_DMP_SUPPORT +#define RADIO_CONFIG_DMP_SUPPORT 0 /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c +#endif diff --git a/examples/platform/bouffalolab/bl602/board_features.h b/examples/platform/bouffalolab/bl602/board_features.h new file mode 100644 index 00000000000000..182cdd9bb9ae2c --- /dev/null +++ b/examples/platform/bouffalolab/bl602/board_features.h @@ -0,0 +1,246 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/******************************************************************************* + * @file + * @brief board_features.h + ******************************************************************************* + * # License + * Copyright 2018 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#pragma once + +// Generated plugin macros + +#ifdef EMBER_AF_BOARD_TYPE +#undef EMBER_AF_BOARD_TYPE +#endif +#define EMBER_AF_BOARD_TYPE BOARD_ID + +/* Indicate if LCD is supported */ +#if (EMBER_AF_BOARD_TYPE == BRD4100A) || (EMBER_AF_BOARD_TYPE == BRD4101B) || (EMBER_AF_BOARD_TYPE == BRD4103A) || \ + (EMBER_AF_BOARD_TYPE == BRD4104A) || (EMBER_AF_BOARD_TYPE == BRD4105A) || (EMBER_AF_BOARD_TYPE == BRD4150A) || \ + (EMBER_AF_BOARD_TYPE == BRD4150B) || (EMBER_AF_BOARD_TYPE == BRD4150C) || (EMBER_AF_BOARD_TYPE == BRD4151A) || \ + (EMBER_AF_BOARD_TYPE == BRD4153A) || (EMBER_AF_BOARD_TYPE == BRD4158A) || (EMBER_AF_BOARD_TYPE == BRD4159A) || \ + (EMBER_AF_BOARD_TYPE == BRD4161A) || (EMBER_AF_BOARD_TYPE == BRD4162A) || (EMBER_AF_BOARD_TYPE == BRD4163A) || \ + (EMBER_AF_BOARD_TYPE == BRD4164A) || (EMBER_AF_BOARD_TYPE == BRD4165B) || (EMBER_AF_BOARD_TYPE == BRD4167A) || \ + (EMBER_AF_BOARD_TYPE == BRD4168A) || (EMBER_AF_BOARD_TYPE == BRD4169A) || (EMBER_AF_BOARD_TYPE == BRD4169B) || \ + (EMBER_AF_BOARD_TYPE == BRD4170A) || (EMBER_AF_BOARD_TYPE == BRD4171A) || (EMBER_AF_BOARD_TYPE == BRD4172A) || \ + (EMBER_AF_BOARD_TYPE == BRD4172B) || (EMBER_AF_BOARD_TYPE == BRD4173A) || (EMBER_AF_BOARD_TYPE == BRD4174A) || \ + (EMBER_AF_BOARD_TYPE == BRD4174B) || (EMBER_AF_BOARD_TYPE == BRD4175A) || (EMBER_AF_BOARD_TYPE == BRD4180A) || \ + (EMBER_AF_BOARD_TYPE == BRD4180B) || (EMBER_AF_BOARD_TYPE == BRD4181A) || (EMBER_AF_BOARD_TYPE == BRD4181B) || \ + (EMBER_AF_BOARD_TYPE == BRD4182A) || (EMBER_AF_BOARD_TYPE == BRD4300A) || (EMBER_AF_BOARD_TYPE == BRD4302A) || \ + (EMBER_AF_BOARD_TYPE == BRD4303A) || (EMBER_AF_BOARD_TYPE == BRD4304A) || (EMBER_AF_BOARD_TYPE == BRD4305A) || \ + (EMBER_AF_BOARD_TYPE == BRD4305C) || (EMBER_AF_BOARD_TYPE == BRD4305D) || (EMBER_AF_BOARD_TYPE == BRD4305E) || \ + (EMBER_AF_BOARD_TYPE == BRD4306A) || (EMBER_AF_BOARD_TYPE == BRD4306B) || (EMBER_AF_BOARD_TYPE == BRD4306C) || \ + (EMBER_AF_BOARD_TYPE == BRD4306D) || (EMBER_AF_BOARD_TYPE == BRD4308A) || (EMBER_AF_BOARD_TYPE == BRD4308B) || \ + (EMBER_AF_BOARD_TYPE == BRD4310A) || (EMBER_AF_BOARD_TYPE == BRD4311A) +#define FEATURE_LCD_SUPPORT +#endif + +/* Indicate if the same pins are used for LEDs and Buttons on the WSTK */ +#if (EMBER_AF_BOARD_TYPE == BRD4101B) || (EMBER_AF_BOARD_TYPE == BRD4300A) || (EMBER_AF_BOARD_TYPE == BRD4301A) || \ + (EMBER_AF_BOARD_TYPE == BRD4304A) || (EMBER_AF_BOARD_TYPE == BRD4306A) || (EMBER_AF_BOARD_TYPE == BRD4306B) || \ + (EMBER_AF_BOARD_TYPE == BRD4306C) || (EMBER_AF_BOARD_TYPE == BRD4306D) || (EMBER_AF_BOARD_TYPE == BRD4308A) || \ + (EMBER_AF_BOARD_TYPE == BRD4308B) || (EMBER_AF_BOARD_TYPE == BRD4309A) || (EMBER_AF_BOARD_TYPE == BRD4310A) || \ + (EMBER_AF_BOARD_TYPE == BRD4311A) +#define FEATURE_LED_BUTTON_ON_SAME_PIN +#endif + +#if (EMBER_AF_BOARD_TYPE == BRD4100A) || (EMBER_AF_BOARD_TYPE == BRD4101B) || (EMBER_AF_BOARD_TYPE == BRD4103A) || \ + (EMBER_AF_BOARD_TYPE == BRD4104A) || (EMBER_AF_BOARD_TYPE == BRD4105A) || (EMBER_AF_BOARD_TYPE == BRD4150A) || \ + (EMBER_AF_BOARD_TYPE == BRD4150B) || (EMBER_AF_BOARD_TYPE == BRD4150C) || (EMBER_AF_BOARD_TYPE == BRD4151A) || \ + (EMBER_AF_BOARD_TYPE == BRD4153A) || (EMBER_AF_BOARD_TYPE == BRD4158A) || (EMBER_AF_BOARD_TYPE == BRD4159A) || \ + (EMBER_AF_BOARD_TYPE == BRD4160A) || (EMBER_AF_BOARD_TYPE == BRD4161A) || (EMBER_AF_BOARD_TYPE == BRD4162A) || \ + (EMBER_AF_BOARD_TYPE == BRD4163A) || (EMBER_AF_BOARD_TYPE == BRD4164A) || (EMBER_AF_BOARD_TYPE == BRD4165B) || \ + (EMBER_AF_BOARD_TYPE == BRD4166A) || (EMBER_AF_BOARD_TYPE == BRD4167A) || (EMBER_AF_BOARD_TYPE == BRD4168A) || \ + (EMBER_AF_BOARD_TYPE == BRD4169A) || (EMBER_AF_BOARD_TYPE == BRD4169B) || (EMBER_AF_BOARD_TYPE == BRD4170A) || \ + (EMBER_AF_BOARD_TYPE == BRD4171A) || (EMBER_AF_BOARD_TYPE == BRD4172A) || (EMBER_AF_BOARD_TYPE == BRD4172B) || \ + (EMBER_AF_BOARD_TYPE == BRD4173A) || (EMBER_AF_BOARD_TYPE == BRD4174A) || (EMBER_AF_BOARD_TYPE == BRD4174B) || \ + (EMBER_AF_BOARD_TYPE == BRD4175A) || (EMBER_AF_BOARD_TYPE == BRD4182A) || (EMBER_AF_BOARD_TYPE == BRD4183A) || \ + (EMBER_AF_BOARD_TYPE == BRD4184A) || (EMBER_AF_BOARD_TYPE == BRD4301A) || (EMBER_AF_BOARD_TYPE == BRD4302A) || \ + (EMBER_AF_BOARD_TYPE == BRD4303A) || (EMBER_AF_BOARD_TYPE == BRD4304A) || (EMBER_AF_BOARD_TYPE == BRD4305A) || \ + (EMBER_AF_BOARD_TYPE == BRD4305C) || (EMBER_AF_BOARD_TYPE == BRD4305D) || (EMBER_AF_BOARD_TYPE == BRD4305E) || \ + (EMBER_AF_BOARD_TYPE == BRD4306A) || (EMBER_AF_BOARD_TYPE == BRD4306B) || (EMBER_AF_BOARD_TYPE == BRD4306C) || \ + (EMBER_AF_BOARD_TYPE == BRD4306D) || (EMBER_AF_BOARD_TYPE == BRD4310A) || (EMBER_AF_BOARD_TYPE == BRD4311A) +#define FEATURE_SPI_FLASH +#endif + +#if (EMBER_AF_BOARD_TYPE == BRD4101B) +#define FEATURE_IOEXPANDER +#endif + +#if (EMBER_AF_BOARD_TYPE == BRD4150B) || (EMBER_AF_BOARD_TYPE == BRD4151A) || (EMBER_AF_BOARD_TYPE == BRD4158A) || \ + (EMBER_AF_BOARD_TYPE == BRD4161A) || (EMBER_AF_BOARD_TYPE == BRD4164A) || (EMBER_AF_BOARD_TYPE == BRD4165B) || \ + (EMBER_AF_BOARD_TYPE == BRD4168A) || (EMBER_AF_BOARD_TYPE == BRD4169B) || (EMBER_AF_BOARD_TYPE == BRD4170A) || \ + (EMBER_AF_BOARD_TYPE == BRD4171A) || (EMBER_AF_BOARD_TYPE == BRD4172A) || (EMBER_AF_BOARD_TYPE == BRD4172B) || \ + (EMBER_AF_BOARD_TYPE == BRD4174A) || (EMBER_AF_BOARD_TYPE == BRD4174B) || (EMBER_AF_BOARD_TYPE == BRD4180A) || \ + (EMBER_AF_BOARD_TYPE == BRD4180B) || (EMBER_AF_BOARD_TYPE == BRD4181A) || (EMBER_AF_BOARD_TYPE == BRD4181B) || \ + (EMBER_AF_BOARD_TYPE == BRD4304A) || (EMBER_AF_BOARD_TYPE == BRD4305A) || (EMBER_AF_BOARD_TYPE == BRD4305E) || \ + (EMBER_AF_BOARD_TYPE == BRD4306B) || (EMBER_AF_BOARD_TYPE == BRD4306D) || (EMBER_AF_BOARD_TYPE == BRD4308A) || \ + (EMBER_AF_BOARD_TYPE == BRD4308B) || (EMBER_AF_BOARD_TYPE == BRD4309A) +#define FEATURE_PA_INPUT_FROM_VBAT +#endif + +#if (EMBER_AF_BOARD_TYPE == BRD4182A) || (EMBER_AF_BOARD_TYPE == BRD4183A) || (EMBER_AF_BOARD_TYPE == BRD4184A) || \ + (EMBER_AF_BOARD_TYPE == BRD4310A) || (EMBER_AF_BOARD_TYPE == BRD4311A) +#define FEATURE_EXP_HEADER_USART1 +#endif + +#if (EMBER_AF_BOARD_TYPE == BRD4103A) || (EMBER_AF_BOARD_TYPE == BRD4161A) || (EMBER_AF_BOARD_TYPE == BRD4162A) || \ + (EMBER_AF_BOARD_TYPE == BRD4163A) || (EMBER_AF_BOARD_TYPE == BRD4164A) || (EMBER_AF_BOARD_TYPE == BRD4170A) +#define FEATURE_EXP_HEADER_USART3 +#endif + +#if (EMBER_AF_BOARD_TYPE == BRD4100A) || (EMBER_AF_BOARD_TYPE == BRD4101B) || (EMBER_AF_BOARD_TYPE == BRD4103A) || \ + (EMBER_AF_BOARD_TYPE == BRD4104A) || (EMBER_AF_BOARD_TYPE == BRD4105A) || (EMBER_AF_BOARD_TYPE == BRD4150A) || \ + (EMBER_AF_BOARD_TYPE == BRD4150B) || (EMBER_AF_BOARD_TYPE == BRD4150C) || (EMBER_AF_BOARD_TYPE == BRD4151A) || \ + (EMBER_AF_BOARD_TYPE == BRD4153A) || (EMBER_AF_BOARD_TYPE == BRD4158A) || (EMBER_AF_BOARD_TYPE == BRD4159A) || \ + (EMBER_AF_BOARD_TYPE == BRD4160A) || (EMBER_AF_BOARD_TYPE == BRD4161A) || (EMBER_AF_BOARD_TYPE == BRD4162A) || \ + (EMBER_AF_BOARD_TYPE == BRD4163A) || (EMBER_AF_BOARD_TYPE == BRD4164A) || (EMBER_AF_BOARD_TYPE == BRD4165B) || \ + (EMBER_AF_BOARD_TYPE == BRD4166A) || (EMBER_AF_BOARD_TYPE == BRD4167A) || (EMBER_AF_BOARD_TYPE == BRD4168A) || \ + (EMBER_AF_BOARD_TYPE == BRD4169A) || (EMBER_AF_BOARD_TYPE == BRD4169B) || (EMBER_AF_BOARD_TYPE == BRD4170A) || \ + (EMBER_AF_BOARD_TYPE == BRD4171A) || (EMBER_AF_BOARD_TYPE == BRD4172A) || (EMBER_AF_BOARD_TYPE == BRD4172B) || \ + (EMBER_AF_BOARD_TYPE == BRD4173A) || (EMBER_AF_BOARD_TYPE == BRD4174A) || (EMBER_AF_BOARD_TYPE == BRD4174B) || \ + (EMBER_AF_BOARD_TYPE == BRD4175A) || (EMBER_AF_BOARD_TYPE == BRD4179B) || (EMBER_AF_BOARD_TYPE == BRD4180A) || \ + (EMBER_AF_BOARD_TYPE == BRD4180B) || (EMBER_AF_BOARD_TYPE == BRD4181A) || (EMBER_AF_BOARD_TYPE == BRD4181B) || \ + (EMBER_AF_BOARD_TYPE == BRD4182A) || (EMBER_AF_BOARD_TYPE == BRD4183A) || (EMBER_AF_BOARD_TYPE == BRD4184A) || \ + (EMBER_AF_BOARD_TYPE == BRD4300A) || (EMBER_AF_BOARD_TYPE == BRD4301A) || (EMBER_AF_BOARD_TYPE == BRD4302A) || \ + (EMBER_AF_BOARD_TYPE == BRD4303A) || (EMBER_AF_BOARD_TYPE == BRD4304A) || (EMBER_AF_BOARD_TYPE == BRD4305A) || \ + (EMBER_AF_BOARD_TYPE == BRD4305C) || (EMBER_AF_BOARD_TYPE == BRD4305D) || (EMBER_AF_BOARD_TYPE == BRD4305E) || \ + (EMBER_AF_BOARD_TYPE == BRD4306A) || (EMBER_AF_BOARD_TYPE == BRD4306B) || (EMBER_AF_BOARD_TYPE == BRD4306C) || \ + (EMBER_AF_BOARD_TYPE == BRD4306D) || (EMBER_AF_BOARD_TYPE == BRD4308A) || (EMBER_AF_BOARD_TYPE == BRD4308B) || \ + (EMBER_AF_BOARD_TYPE == BRD4309A) || (EMBER_AF_BOARD_TYPE == BRD4310A) || (EMBER_AF_BOARD_TYPE == BRD4311A) +#define FEATURE_PTI_SUPPORT +#endif + +#if (EMBER_AF_BOARD_TYPE == BRD4100A) || (EMBER_AF_BOARD_TYPE == BRD4101B) || (EMBER_AF_BOARD_TYPE == BRD4103A) || \ + (EMBER_AF_BOARD_TYPE == BRD4104A) || (EMBER_AF_BOARD_TYPE == BRD4105A) || (EMBER_AF_BOARD_TYPE == BRD4150A) || \ + (EMBER_AF_BOARD_TYPE == BRD4150B) || (EMBER_AF_BOARD_TYPE == BRD4150C) || (EMBER_AF_BOARD_TYPE == BRD4151A) || \ + (EMBER_AF_BOARD_TYPE == BRD4153A) || (EMBER_AF_BOARD_TYPE == BRD4158A) || (EMBER_AF_BOARD_TYPE == BRD4159A) || \ + (EMBER_AF_BOARD_TYPE == BRD4161A) || (EMBER_AF_BOARD_TYPE == BRD4162A) || (EMBER_AF_BOARD_TYPE == BRD4163A) || \ + (EMBER_AF_BOARD_TYPE == BRD4164A) || (EMBER_AF_BOARD_TYPE == BRD4165B) || (EMBER_AF_BOARD_TYPE == BRD4167A) || \ + (EMBER_AF_BOARD_TYPE == BRD4168A) || (EMBER_AF_BOARD_TYPE == BRD4169A) || (EMBER_AF_BOARD_TYPE == BRD4169B) || \ + (EMBER_AF_BOARD_TYPE == BRD4170A) || (EMBER_AF_BOARD_TYPE == BRD4172A) || (EMBER_AF_BOARD_TYPE == BRD4172B) || \ + (EMBER_AF_BOARD_TYPE == BRD4173A) || (EMBER_AF_BOARD_TYPE == BRD4174A) || (EMBER_AF_BOARD_TYPE == BRD4174B) || \ + (EMBER_AF_BOARD_TYPE == BRD4175A) || (EMBER_AF_BOARD_TYPE == BRD4179B) || (EMBER_AF_BOARD_TYPE == BRD4180A) || \ + (EMBER_AF_BOARD_TYPE == BRD4180B) || (EMBER_AF_BOARD_TYPE == BRD4181A) || (EMBER_AF_BOARD_TYPE == BRD4181B) || \ + (EMBER_AF_BOARD_TYPE == BRD4182A) || (EMBER_AF_BOARD_TYPE == BRD4183A) || (EMBER_AF_BOARD_TYPE == BRD4300A) || \ + (EMBER_AF_BOARD_TYPE == BRD4301A) || (EMBER_AF_BOARD_TYPE == BRD4302A) || (EMBER_AF_BOARD_TYPE == BRD4303A) || \ + (EMBER_AF_BOARD_TYPE == BRD4304A) || (EMBER_AF_BOARD_TYPE == BRD4305A) || (EMBER_AF_BOARD_TYPE == BRD4305C) || \ + (EMBER_AF_BOARD_TYPE == BRD4305D) || (EMBER_AF_BOARD_TYPE == BRD4305E) || (EMBER_AF_BOARD_TYPE == BRD4306A) || \ + (EMBER_AF_BOARD_TYPE == BRD4306B) || (EMBER_AF_BOARD_TYPE == BRD4306C) || (EMBER_AF_BOARD_TYPE == BRD4306D) || \ + (EMBER_AF_BOARD_TYPE == BRD4308A) || (EMBER_AF_BOARD_TYPE == BRD4308B) || (EMBER_AF_BOARD_TYPE == BRD4309A) || \ + (EMBER_AF_BOARD_TYPE == BRD4310A) || (EMBER_AF_BOARD_TYPE == BRD4311A) +#define FEATURE_HW_FLOW_CONTROL +#endif + +#if (EMBER_AF_BOARD_TYPE == BRD4100A) || (EMBER_AF_BOARD_TYPE == BRD4101B) || (EMBER_AF_BOARD_TYPE == BRD4103A) || \ + (EMBER_AF_BOARD_TYPE == BRD4104A) || (EMBER_AF_BOARD_TYPE == BRD4105A) || (EMBER_AF_BOARD_TYPE == BRD4150A) || \ + (EMBER_AF_BOARD_TYPE == BRD4150B) || (EMBER_AF_BOARD_TYPE == BRD4150C) || (EMBER_AF_BOARD_TYPE == BRD4151A) || \ + (EMBER_AF_BOARD_TYPE == BRD4153A) || (EMBER_AF_BOARD_TYPE == BRD4158A) || (EMBER_AF_BOARD_TYPE == BRD4159A) || \ + (EMBER_AF_BOARD_TYPE == BRD4160A) || (EMBER_AF_BOARD_TYPE == BRD4161A) || (EMBER_AF_BOARD_TYPE == BRD4162A) || \ + (EMBER_AF_BOARD_TYPE == BRD4163A) || (EMBER_AF_BOARD_TYPE == BRD4164A) || (EMBER_AF_BOARD_TYPE == BRD4165B) || \ + (EMBER_AF_BOARD_TYPE == BRD4166A) || (EMBER_AF_BOARD_TYPE == BRD4167A) || (EMBER_AF_BOARD_TYPE == BRD4168A) || \ + (EMBER_AF_BOARD_TYPE == BRD4169A) || (EMBER_AF_BOARD_TYPE == BRD4169B) || (EMBER_AF_BOARD_TYPE == BRD4170A) || \ + (EMBER_AF_BOARD_TYPE == BRD4171A) || (EMBER_AF_BOARD_TYPE == BRD4172A) || (EMBER_AF_BOARD_TYPE == BRD4172B) || \ + (EMBER_AF_BOARD_TYPE == BRD4173A) || (EMBER_AF_BOARD_TYPE == BRD4174A) || (EMBER_AF_BOARD_TYPE == BRD4174B) || \ + (EMBER_AF_BOARD_TYPE == BRD4175A) || (EMBER_AF_BOARD_TYPE == BRD4182A) || (EMBER_AF_BOARD_TYPE == BRD4184A) || \ + (EMBER_AF_BOARD_TYPE == BRD4300A) || (EMBER_AF_BOARD_TYPE == BRD4301A) || (EMBER_AF_BOARD_TYPE == BRD4302A) || \ + (EMBER_AF_BOARD_TYPE == BRD4303A) || (EMBER_AF_BOARD_TYPE == BRD4304A) || (EMBER_AF_BOARD_TYPE == BRD4305A) || \ + (EMBER_AF_BOARD_TYPE == BRD4305C) || (EMBER_AF_BOARD_TYPE == BRD4305D) || (EMBER_AF_BOARD_TYPE == BRD4305E) || \ + (EMBER_AF_BOARD_TYPE == BRD4306A) || (EMBER_AF_BOARD_TYPE == BRD4306B) || (EMBER_AF_BOARD_TYPE == BRD4306C) || \ + (EMBER_AF_BOARD_TYPE == BRD4306D) || (EMBER_AF_BOARD_TYPE == BRD4310A) || (EMBER_AF_BOARD_TYPE == BRD4311A) +#define FEATURE_I2C_SENSOR +#endif + +#if (EMBER_AF_BOARD_TYPE == BRD4100A) || (EMBER_AF_BOARD_TYPE == BRD4101B) || (EMBER_AF_BOARD_TYPE == BRD4103A) || \ + (EMBER_AF_BOARD_TYPE == BRD4104A) || (EMBER_AF_BOARD_TYPE == BRD4105A) || (EMBER_AF_BOARD_TYPE == BRD4150A) || \ + (EMBER_AF_BOARD_TYPE == BRD4150B) || (EMBER_AF_BOARD_TYPE == BRD4150C) || (EMBER_AF_BOARD_TYPE == BRD4151A) || \ + (EMBER_AF_BOARD_TYPE == BRD4153A) || (EMBER_AF_BOARD_TYPE == BRD4158A) || (EMBER_AF_BOARD_TYPE == BRD4159A) || \ + (EMBER_AF_BOARD_TYPE == BRD4160A) || (EMBER_AF_BOARD_TYPE == BRD4161A) || (EMBER_AF_BOARD_TYPE == BRD4162A) || \ + (EMBER_AF_BOARD_TYPE == BRD4163A) || (EMBER_AF_BOARD_TYPE == BRD4164A) || (EMBER_AF_BOARD_TYPE == BRD4165B) || \ + (EMBER_AF_BOARD_TYPE == BRD4166A) || (EMBER_AF_BOARD_TYPE == BRD4167A) || (EMBER_AF_BOARD_TYPE == BRD4168A) || \ + (EMBER_AF_BOARD_TYPE == BRD4169A) || (EMBER_AF_BOARD_TYPE == BRD4169B) || (EMBER_AF_BOARD_TYPE == BRD4170A) || \ + (EMBER_AF_BOARD_TYPE == BRD4172A) || (EMBER_AF_BOARD_TYPE == BRD4172B) || (EMBER_AF_BOARD_TYPE == BRD4173A) || \ + (EMBER_AF_BOARD_TYPE == BRD4174A) || (EMBER_AF_BOARD_TYPE == BRD4174B) || (EMBER_AF_BOARD_TYPE == BRD4175A) || \ + (EMBER_AF_BOARD_TYPE == BRD4179B) || (EMBER_AF_BOARD_TYPE == BRD4180A) || (EMBER_AF_BOARD_TYPE == BRD4180B) || \ + (EMBER_AF_BOARD_TYPE == BRD4181A) || (EMBER_AF_BOARD_TYPE == BRD4181B) || (EMBER_AF_BOARD_TYPE == BRD4182A) || \ + (EMBER_AF_BOARD_TYPE == BRD4183A) || (EMBER_AF_BOARD_TYPE == BRD4184A) || (EMBER_AF_BOARD_TYPE == BRD4300A) || \ + (EMBER_AF_BOARD_TYPE == BRD4301A) || (EMBER_AF_BOARD_TYPE == BRD4302A) || (EMBER_AF_BOARD_TYPE == BRD4303A) || \ + (EMBER_AF_BOARD_TYPE == BRD4304A) || (EMBER_AF_BOARD_TYPE == BRD4305A) || (EMBER_AF_BOARD_TYPE == BRD4305C) || \ + (EMBER_AF_BOARD_TYPE == BRD4305D) || (EMBER_AF_BOARD_TYPE == BRD4305E) || (EMBER_AF_BOARD_TYPE == BRD4306A) || \ + (EMBER_AF_BOARD_TYPE == BRD4306B) || (EMBER_AF_BOARD_TYPE == BRD4306C) || (EMBER_AF_BOARD_TYPE == BRD4306D) || \ + (EMBER_AF_BOARD_TYPE == BRD4308A) || (EMBER_AF_BOARD_TYPE == BRD4308B) || (EMBER_AF_BOARD_TYPE == BRD4310A) +#define FEATURE_LFXO +#endif + +#if (EMBER_AF_BOARD_TYPE == BRD4179B) +#define FEATURE_EFP +#endif + +#if (EMBER_AF_BOARD_TYPE == BRD4100A) || (EMBER_AF_BOARD_TYPE == BRD4101B) || (EMBER_AF_BOARD_TYPE == BRD4103A) || \ + (EMBER_AF_BOARD_TYPE == BRD4104A) || (EMBER_AF_BOARD_TYPE == BRD4105A) || (EMBER_AF_BOARD_TYPE == BRD4150A) || \ + (EMBER_AF_BOARD_TYPE == BRD4150B) || (EMBER_AF_BOARD_TYPE == BRD4150C) || (EMBER_AF_BOARD_TYPE == BRD4151A) || \ + (EMBER_AF_BOARD_TYPE == BRD4153A) || (EMBER_AF_BOARD_TYPE == BRD4158A) || (EMBER_AF_BOARD_TYPE == BRD4159A) || \ + (EMBER_AF_BOARD_TYPE == BRD4160A) || (EMBER_AF_BOARD_TYPE == BRD4161A) || (EMBER_AF_BOARD_TYPE == BRD4162A) || \ + (EMBER_AF_BOARD_TYPE == BRD4163A) || (EMBER_AF_BOARD_TYPE == BRD4164A) || (EMBER_AF_BOARD_TYPE == BRD4165B) || \ + (EMBER_AF_BOARD_TYPE == BRD4166A) || (EMBER_AF_BOARD_TYPE == BRD4167A) || (EMBER_AF_BOARD_TYPE == BRD4168A) || \ + (EMBER_AF_BOARD_TYPE == BRD4169A) || (EMBER_AF_BOARD_TYPE == BRD4169B) || (EMBER_AF_BOARD_TYPE == BRD4170A) || \ + (EMBER_AF_BOARD_TYPE == BRD4171A) || (EMBER_AF_BOARD_TYPE == BRD4172A) || (EMBER_AF_BOARD_TYPE == BRD4172B) || \ + (EMBER_AF_BOARD_TYPE == BRD4173A) || (EMBER_AF_BOARD_TYPE == BRD4174A) || (EMBER_AF_BOARD_TYPE == BRD4174B) || \ + (EMBER_AF_BOARD_TYPE == BRD4175A) || (EMBER_AF_BOARD_TYPE == BRD4179B) || (EMBER_AF_BOARD_TYPE == BRD4180A) || \ + (EMBER_AF_BOARD_TYPE == BRD4180B) || (EMBER_AF_BOARD_TYPE == BRD4181A) || (EMBER_AF_BOARD_TYPE == BRD4181B) || \ + (EMBER_AF_BOARD_TYPE == BRD4182A) || (EMBER_AF_BOARD_TYPE == BRD4183A) || (EMBER_AF_BOARD_TYPE == BRD4184A) || \ + (EMBER_AF_BOARD_TYPE == BRD4300A) || (EMBER_AF_BOARD_TYPE == BRD4301A) || (EMBER_AF_BOARD_TYPE == BRD4302A) || \ + (EMBER_AF_BOARD_TYPE == BRD4303A) || (EMBER_AF_BOARD_TYPE == BRD4304A) || (EMBER_AF_BOARD_TYPE == BRD4305A) || \ + (EMBER_AF_BOARD_TYPE == BRD4305C) || (EMBER_AF_BOARD_TYPE == BRD4305D) || (EMBER_AF_BOARD_TYPE == BRD4305E) || \ + (EMBER_AF_BOARD_TYPE == BRD4306A) || (EMBER_AF_BOARD_TYPE == BRD4306B) || (EMBER_AF_BOARD_TYPE == BRD4306C) || \ + (EMBER_AF_BOARD_TYPE == BRD4306D) || (EMBER_AF_BOARD_TYPE == BRD4308A) || (EMBER_AF_BOARD_TYPE == BRD4308B) || \ + (EMBER_AF_BOARD_TYPE == BRD4309A) || (EMBER_AF_BOARD_TYPE == BRD4310A) || (EMBER_AF_BOARD_TYPE == BRD4311A) || \ + (EMBER_AF_BOARD_TYPE == RD_0057_0101) +#define FEATURE_BOARD_DETECTED +#endif + +#if (EMBER_AF_BOARD_TYPE == CUSTOM_BOARD) +// Uncomment the corresponding line in case of using Silicon Labs board feature in your design. +// For using the selected feature you may need additional drivers. Check an appropriate SDK example for reference. + +// #define FEATURE_LCD_SUPPORT +// #define FEATURE_LED_BUTTON_ON_SAME_PIN +// #define FEATURE_SPI_FLASH +// #define FEATURE_IOEXPANDER +// #define FEATURE_PA_INPUT_FROM_VBAT +// #define FEATURE_EXP_HEADER_USART1 +// #define FEATURE_EXP_HEADER_USART3 +// #define FEATURE_PTI_SUPPORT +// #define FEATURE_HW_FLOW_CONTROL +// #define FEATURE_I2C_SENSOR +// #define FEATURE_LFXO +// #define FEATURE_EFP +// #define FEATURE_BOARD_DETECTED +#endif diff --git a/examples/platform/bouffalolab/bl602/display/lcd.c b/examples/platform/bouffalolab/bl602/display/lcd.c new file mode 100644 index 00000000000000..54f246c681f9fe --- /dev/null +++ b/examples/platform/bouffalolab/bl602/display/lcd.c @@ -0,0 +1,129 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "lcd.h" + +#include "display.h" +#include "dmd.h" +#include "glib.h" +#include "qrcodegen.h" + +#define LCD_SIZE 128 +#define QR_CODE_VERSION 4 +#define QR_CODE_MODULE_SIZE 3 +#define QR_CODE_BORDER_SIZE 0 + +static GLIB_Context_t glibContext; +static uint8_t qrCode[qrcodegen_BUFFER_LEN_FOR_VERSION(QR_CODE_VERSION)]; +static uint8_t workBuffer[qrcodegen_BUFFER_LEN_FOR_VERSION(QR_CODE_VERSION)]; + +static void LCDFillRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h); + +void initLCD(void) +{ + EMSTATUS status; + + /* Initialize the DMD module for the DISPLAY device driver. */ + status = DMD_init(0); + if (DMD_OK != status) + { + EFR32_LOG("DMD init failed %d", status); + } + + /* Initialize the glib context */ + status = GLIB_contextInit(&glibContext); + if (GLIB_OK != status) + { + EFR32_LOG("Glib context init failed %d", status); + } + + glibContext.backgroundColor = White; + glibContext.foregroundColor = Black; + status = GLIB_clear(&glibContext); + if (GLIB_OK != status) + { + EFR32_LOG("Glib clear failed %d", status); + } +} + +/* This function is necessary because currently glib.h cannot be used within a C++ context. */ +void * LCDContext() +{ + return (void *) &glibContext; +} + +int LCD_clear(void * pContext) +{ + return GLIB_clear((GLIB_Context_t *) pContext); +} + +int LCD_drawPixel(void * pContext, int32_t x, int32_t y) +{ + return GLIB_drawPixel((GLIB_Context_t *) pContext, x, y); +} + +int LCD_update(void) +{ + return DMD_updateDisplay(); +} + +void LCDWriteQRCode(uint8_t * str) +{ + if (!qrcodegen_encodeText((const char *) str, workBuffer, qrCode, qrcodegen_Ecc_LOW, QR_CODE_VERSION, QR_CODE_VERSION, + qrcodegen_Mask_AUTO, true)) + { + EFR32_LOG("qrcodegen_encodeText() failed"); + return; + } + + const int size = qrcodegen_getSize(qrCode); + + GLIB_clear(&glibContext); + + const int displaySize = (2 * QR_CODE_BORDER_SIZE + size) * QR_CODE_MODULE_SIZE; + const int displayX = (LCD_SIZE - displaySize) / 2; + const int displayY = displayX; + + for (int y = 0; y < size; ++y) + { + for (int x = 0; x < size; ++x) + { + if (qrcodegen_getModule(qrCode, x, y)) + { + LCDFillRect(displayX + (QR_CODE_BORDER_SIZE + x) * QR_CODE_MODULE_SIZE, + displayY + (QR_CODE_BORDER_SIZE + y) * QR_CODE_MODULE_SIZE, QR_CODE_MODULE_SIZE, QR_CODE_MODULE_SIZE); + } + } + } + + DMD_updateDisplay(); +} + +void LCDFillRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h) +{ + for (int i = 0; i < h; i++) + { + for (int j = 0; j < w; j++) + { + GLIB_drawPixel(&glibContext, x + j, y + i); + } + } +} diff --git a/examples/platform/bouffalolab/bl602/hal-config-app-common.h b/examples/platform/bouffalolab/bl602/hal-config-app-common.h new file mode 100644 index 00000000000000..b19a61575b89e2 --- /dev/null +++ b/examples/platform/bouffalolab/bl602/hal-config-app-common.h @@ -0,0 +1,121 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/****************************************************************************** + * @file + * @brief hal-config-app-common.h + ******************************************************************************* + * # License + * Copyright 2018 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#pragma once + +#include "em_device.h" +#include "hal-config-types.h" + +#if defined(FEATURE_IOEXPANDER) +#include "hal-config-ioexp.h" +#endif + +#define HAL_EXTFLASH_FREQUENCY (1000000) + +#define HAL_PTI_ENABLE (1) +#define HAL_PTI_MODE (HAL_PTI_MODE_UART) +#define HAL_PTI_BAUD_RATE (1600000) + +#define HAL_PA_RAMP (10) +#define HAL_PA_2P4_LOWPOWER (0) +#define HAL_PA_POWER (252) +#define HAL_PA_CURVE_HEADER "pa_curves_efr32.h" + +#define HAL_PA_VOLTAGE BSP_PA_VOLTAGE + +// Select antenna path on EFR32xG2x devices: +// - RF2G2_IO1: 0 +// - RF2G2_IO2: 1 +#define GECKO_RF_ANTENNA 1 +#if defined(FEATURE_EXP_HEADER_USART3) + +#define BSP_EXP_USART USART3 + +#define BSP_EXP_USART_CTS_PIN BSP_USART3_CTS_PIN +#define BSP_EXP_USART_CTS_PORT BSP_USART3_CTS_PORT +#define BSP_EXP_USART_CTS_LOC BSP_USART3_CTS_LOC + +#define BSP_EXP_USART_RTS_PIN BSP_USART3_RTS_PIN +#define BSP_EXP_USART_RTS_PORT BSP_USART3_RTS_PORT +#define BSP_EXP_USART_RTS_LOC BSP_USART3_RTS_LOC + +#define BSP_EXP_USART_RX_PIN BSP_USART3_RX_PIN +#define BSP_EXP_USART_RX_PORT BSP_USART3_RX_PORT +#define BSP_EXP_USART_RX_LOC BSP_USART3_RX_LOC + +#define BSP_EXP_USART_TX_PIN BSP_USART3_TX_PIN +#define BSP_EXP_USART_TX_PORT BSP_USART3_TX_PORT +#define BSP_EXP_USART_TX_LOC BSP_USART3_TX_LOC + +#elif defined(FEATURE_EXP_HEADER_USART1) + +#define BSP_EXP_USART USART1 + +#define BSP_EXP_USART_CTS_PIN BSP_USART1_CTS_PIN +#define BSP_EXP_USART_CTS_PORT BSP_USART1_CTS_PORT +#define BSP_EXP_USART_CTS_LOC BSP_USART1_CTS_LOC + +#define BSP_EXP_USART_RTS_PIN BSP_USART1_RTS_PIN +#define BSP_EXP_USART_RTS_PORT BSP_USART1_RTS_PORT +#define BSP_EXP_USART_RTS_LOC BSP_USART1_RTS_LOC + +#define BSP_EXP_USART_RX_PIN BSP_USART1_RX_PIN +#define BSP_EXP_USART_RX_PORT BSP_USART1_RX_PORT +#define BSP_EXP_USART_RX_LOC BSP_USART1_RX_LOC + +#define BSP_EXP_USART_TX_PIN BSP_USART1_TX_PIN +#define BSP_EXP_USART_TX_PORT BSP_USART1_TX_PORT +#define BSP_EXP_USART_TX_LOC BSP_USART1_TX_LOC + +#else + +#define BSP_EXP_USART USART0 + +#define BSP_EXP_USART_CTS_PIN BSP_USART0_CTS_PIN +#define BSP_EXP_USART_CTS_PORT BSP_USART0_CTS_PORT +#define BSP_EXP_USART_CTS_LOC BSP_USART0_CTS_LOC + +#define BSP_EXP_USART_RTS_PIN BSP_USART0_RTS_PIN +#define BSP_EXP_USART_RTS_PORT BSP_USART0_RTS_PORT +#define BSP_EXP_USART_RTS_LOC BSP_USART0_RTS_LOC + +#define BSP_EXP_USART_RX_PIN BSP_USART0_RX_PIN +#define BSP_EXP_USART_RX_PORT BSP_USART0_RX_PORT +#define BSP_EXP_USART_RX_LOC BSP_USART0_RX_LOC + +#define BSP_EXP_USART_TX_PIN BSP_USART0_TX_PIN +#define BSP_EXP_USART_TX_PORT BSP_USART0_TX_PORT +#define BSP_EXP_USART_TX_LOC BSP_USART0_TX_LOC + +#endif // FEATURE_EXP_HEADER_USART3 diff --git a/examples/platform/bouffalolab/bl602/lcd.h b/examples/platform/bouffalolab/bl602/lcd.h new file mode 100644 index 00000000000000..52680109932c10 --- /dev/null +++ b/examples/platform/bouffalolab/bl602/lcd.h @@ -0,0 +1,39 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "AppConfig.h" +#include "board_features.h" + +#define MAX_STR_LEN 48 + +void initLCD(void); +void * LCDContext(); +int LCD_clear(void * pContext); +int LCD_drawPixel(void * pContext, int32_t x, int32_t y); +int LCD_update(void); +void LCDWriteQRCode(uint8_t * text); + +#ifdef __cplusplus +} +#endif diff --git a/examples/platform/bouffalolab/bl602/ldscripts/flash_rom.ld b/examples/platform/bouffalolab/bl602/ldscripts/flash_rom.ld new file mode 100644 index 00000000000000..45ec9eacc10192 --- /dev/null +++ b/examples/platform/bouffalolab/bl602/ldscripts/flash_rom.ld @@ -0,0 +1,272 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( bl602_start ) + +__EM_SIZE = DEFINED(ble_controller_init) ? 8K : 0K; +__RFTLV_SIZE_OFFSET = 1K; +__RFTLV_SIZE_HOLE = 2K; +__RFTLV_HEAD1_H = (0x46524C42); /* BLRF */ +__RFTLV_HEAD1_L = (0x41524150); /* PAPA */ + +__RAM_START = 0x4200C000; +__RAM_END = 0x4200C000 + 256K - __EM_SIZE; /* leave 8K left for BLE */ + +__RAM_TCM_LEN = (16K + 16K + 48K + 64K + 64K - 16K); +__RAM_WIFI_LEN = (__RAM_END - __RAM_START - __RAM_TCM_LEN); + +MEMORY +{ + rom (rxai!w) : ORIGIN = 0x21015000, LENGTH = 44K + flash (rxai!w) : ORIGIN = 0x23000000, LENGTH = 4M + + /* ram_tcm (wxa) : ORIGIN = 0x4200C000, LENGTH = (16K + 16K + 48K + 64K + 64K + 8K - __EM_SIZE) put itcm with dtam and also OCRAM*/ + /* ram_wifi (wxa) : ORIGIN = 0x42042000 - __EM_SIZE, LENGTH = (8K + 104K - 64K - 8K) leave 8K left for BLE*/ + + ram_tcm (wxa) : ORIGIN = __RAM_START, LENGTH = __RAM_TCM_LEN + ram_wifi (wxa) : ORIGIN = __RAM_START + __RAM_TCM_LEN, LENGTH = __RAM_WIFI_LEN +} + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 2K; + BOOT2_PT_ADDR = 0x42049C00; + BOOT2_FLASHCFG_ADDR = 0x42049c18; + + .init : + { + KEEP (*(SORT_NONE(.init))) + } > flash + + /* value for rftlv */ + + .rftlv.tool : + { + . = ORIGIN(flash) + __RFTLV_SIZE_OFFSET; + PROVIDE( _ld_symbol_rftlv_address = . ); + LONG(__RFTLV_HEAD1_H); + LONG(__RFTLV_HEAD1_L); + . = ORIGIN(flash) + __RFTLV_SIZE_OFFSET + __RFTLV_SIZE_HOLE; + } > flash + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } > flash + + .rodata : + { + *(.rdata) + *(.rodata .rodata.*) + *(.sdata2.*) + + /* static cli cmds */ + . = ALIGN(4); + _bl_static_cli_cmds_start = .; + KEEP(*(.static_cli_cmds)) + *(.static_cli_cmds) + _bl_static_cli_cmds_end = .; + + /* CI cmds */ + . = ALIGN(4); + KEEP(*(.ctest)) + + /* static fw attribute entry */ + . = ALIGN(4); + _bl_static_fw_cfg_entry_start = .; + KEEP(*(.wifi.cfg.entry)) + _bl_static_fw_cfg_entry_end = .; + + /* static blog code1 */ + . = ALIGN(4); + _bl_static_blogcomponent_code_start = .; + KEEP(SORT(*)(.static_blogcomponent_code*)) + *(.static_blogcomponent_code*) + _bl_static_blogcomponent_code_end = .; + + /* static blog code2 */ + . = ALIGN(4); + _bl_static_blogfile_code_start = .; + KEEP(SORT(*)(.static_blogfile_code*)) + *(.static_blogfile_code*) + _bl_static_blogfile_code_end = .; + + /* static blog code3 */ + . = ALIGN(4); + _bl_static_blogpri_code_start = .; + KEEP(SORT(*)(.static_blogpri_code*)) + *(.static_blogpri_code*) + _bl_static_blogpri_code_end = .; + + *(.gnu.linkonce.r.*) + + /*Framework table section, use ALIGN here to avoid fill section*/ + . = ALIGN(4); + _rom_framework_audio_device_start = .; + KEEP(*(.framework.audio_device)) + _rom_framework_audio_device_end = .; + } > flash + + .preinit_array : + { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } > flash + + .init_array : + { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } > flash + + /*put wifibss in the first place*/ + .wifibss (NOLOAD) : + { + PROVIDE( __wifi_bss_start = ADDR(.wifibss) ); + PROVIDE( __wifi_bss_end = ADDR(.wifibss) + SIZEOF(.wifibss) ); + *ipc_shared.o(COMMON) + *sdu_shared.o(COMMON) + *hal_desc.o(COMMON) + *txl_buffer_shared.o(COMMON) + *txl_frame_shared.o(COMMON) + *scan_shared.o(COMMON) + *scanu_shared.o(COMMON) + *mfp_bip.o(COMMON) + *me_mic.o(COMMON) + *bl_sta_mgmt_others.o(COMMON) + *bl_pmk_mgmt.o(COMMON) + *bl_pmk_mgmt_internal.o(COMMON) + *libwifi_drv.a:bl_utils.o(COMMON) + *libwifi_drv.a:bl_utils.o(.bss*) + *(.wifi_ram*) + . = ALIGN(16); + } > ram_wifi + + PROVIDE( _heap_wifi_start = . ); + PROVIDE( _heap_wifi_size = ORIGIN(ram_wifi) + LENGTH(ram_wifi) - _heap_wifi_start ); + + .romdata : + { + /*always put freetos under global_pointer with the following order. No change!*/ + PROVIDE( __global_pointer_head$ = . ); + PROVIDE( __global_pointer$ = . + 0x7F0 ); + . = . + 0x498; + } > ram_tcm AT > flash + + .data : + { + PROVIDE( _data_load = LOADADDR(.data) ); + PROVIDE( _data_run = ADDR(.data) ); + PROVIDE( _data_run_end = ADDR(.data) + SIZEOF(.data)); + + *(.tcm_code) + *(.tcm_const) + *(.sclock_rlt_code) + *(.sclock_rlt_const) + *(.data .data.*) + *(.gnu.linkonce.d.*) + + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + + . = ALIGN(8); + *(._k_queue.static.*) + *(._k_sem.static.*) + *(._k_mutex.static.*) + _bt_gatt_service_static_list_start = .; + KEEP(*(SORT_BY_NAME("._bt_gatt_service_static.static.*"))) + _bt_gatt_service_static_list_end = .; + _bt_l2cap_fixed_chan_list_start = .; + KEEP(*(SORT_BY_NAME("._bt_l2cap_fixed_chan.static.*"))) + _bt_l2cap_fixed_chan_list_end = .; + + /* For BFLB Coredump */ + _coredump_binary_id_start = . - ADDR(.data) + LOADADDR(.data); + KEEP(*(.coredump_binary_id)) + + } > ram_tcm AT > flash + + .boot2 (NOLOAD) : + { + PROVIDE ( __boot2_pt_addr_start = . ); + *(.bss.boot2_partition_table) + PROVIDE ( __boot2_pt_addr_end = . ); + + PROVIDE ( __boot2_flashCfg_start = . ); + *(.bss.boot2_flashCfg) + PROVIDE ( __boot2_flashCfg_end = . ); + + } > ram_tcm + + .bss (NOLOAD) : + { + PROVIDE( __bss_start = ADDR(.bss) ); + PROVIDE( __bss_end = ADDR(.bss) + SIZEOF(.bss) ); + + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + } > ram_tcm + + .stack (NOLOAD) : + { + PROVIDE ( _sp_base = . ); + . = ALIGN(16); + . = . + __stack_size; + PROVIDE( _sp_main = . ); + __freertos_irq_stack_top = .; + } + + PROVIDE( _heap_start = . ); + PROVIDE( _heap_size = ORIGIN(ram_tcm) + LENGTH(ram_tcm) - _heap_start ); + + /*SYMOBOL used in code*/ + PROVIDE( _ld_bl_static_cli_cmds_start = _bl_static_cli_cmds_start ); + PROVIDE( _ld_bl_static_cli_cmds_end = _bl_static_cli_cmds_end ); + + /*CFG FW used in code*/ + PROVIDE( _ld_bl_static_cfg_entry_start = _bl_static_fw_cfg_entry_start ); + PROVIDE( _ld_bl_static_cfg_entry_end = _bl_static_fw_cfg_entry_end ); + + /* blog */ + PROVIDE( _ld_bl_static_blogcomponent_code_start = _bl_static_blogcomponent_code_start ); + PROVIDE( _ld_bl_static_blogcomponent_code_end = _bl_static_blogcomponent_code_end ); + PROVIDE( _ld_bl_static_blogfile_code_start = _bl_static_blogfile_code_start ); + PROVIDE( _ld_bl_static_blogfile_code_end = _bl_static_blogfile_code_end ); + PROVIDE( _ld_bl_static_blogpri_code_start = _bl_static_blogpri_code_start ); + PROVIDE( _ld_bl_static_blogpri_code_end = _bl_static_blogpri_code_end ); + + PROVIDE( _ld_ram_size0 = LENGTH(flash) ); + PROVIDE( _ld_ram_addr0 = ORIGIN(flash) ); + PROVIDE( _ld_ram_size1 = LENGTH(ram_tcm) ); + PROVIDE( _ld_ram_addr1 = ORIGIN(ram_tcm) ); + PROVIDE( _ld_ram_size2 = LENGTH(ram_wifi) ); + PROVIDE( _ld_ram_addr2 = ORIGIN(ram_wifi) ); + + + /*BOOT2 sections*/ + PROVIDE ( __boot2_pt_addr_src = BOOT2_PT_ADDR ); + PROVIDE ( __boot2_flashCfg_src = BOOT2_FLASHCFG_ADDR ); + + PROVIDE(__LD_CONFIG_EM_SEL = __EM_SIZE); + + PROVIDE( _ld_symbol_rom_framework_audio_device_start = _rom_framework_audio_device_start); + PROVIDE( _ld_symbol_rom_framework_audio_device_end = _rom_framework_audio_device_end); + +} diff --git a/examples/platform/bouffalolab/bl602/project_include/OpenThreadConfig.h b/examples/platform/bouffalolab/bl602/project_include/OpenThreadConfig.h new file mode 100644 index 00000000000000..1569c08558848a --- /dev/null +++ b/examples/platform/bouffalolab/bl602/project_include/OpenThreadConfig.h @@ -0,0 +1,60 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Overrides to default OpenThread configuration. + * + */ + +#pragma once + +#include + +// Disable the SiLabs-supplied OpenThread logging facilities and use +// the facilities provided by the Device Layer (see +// src/platform/EFR32/Logging.cpp). +#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_APP + +// Turn on a moderate level of logging in OpenThread +// Enable use of external heap allocator (calloc/free) for OpenThread. +#define OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE 1 + +// EFR32MG21A020F1024IM32 has 96k of RAM. Reduce the number of buffers to +// conserve RAM for this Series 2 part. +#if defined(EFR32MG21) +#define OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS 22 +#define OPENTHREAD_CONFIG_CLI_UART_TX_BUFFER_SIZE 512 +#define OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE 512 +#endif + +#define OPENTHREAD_CONFIG_JOINER_ENABLE 1 +#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE 1 +#define OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE 1 + +#define OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE 1 +#define OPENTHREAD_CONFIG_ECDSA_ENABLE 1 + +// Use the SiLabs-supplied default platform configuration for remainder +// of OpenThread config options. +// +// NB: This file gets included during the build of OpenThread. Hence +// it cannot use "openthread" in the path to the included file. +// +#include "openthread-core-efr32-config.h" diff --git a/examples/platform/bouffalolab/bl602/pw_sys_io/BUILD.gn b/examples/platform/bouffalolab/bl602/pw_sys_io/BUILD.gn new file mode 100644 index 00000000000000..c7001f3271284c --- /dev/null +++ b/examples/platform/bouffalolab/bl602/pw_sys_io/BUILD.gn @@ -0,0 +1,39 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") + +import("$dir_pw_build/target_types.gni") + +examples_plat_dir = "${chip_root}/examples/platform/bl602" + +config("default_config") { + include_dirs = [ "public" ] +} + +pw_source_set("pw_sys_io_bl602") { + sources = [ "sys_io_bl602.cc" ] + + deps = [ + "$dir_pw_sys_io:default_putget_bytes", + "$dir_pw_sys_io:facade", + ] + + cflags = [ "-Wconversion" ] + + public_configs = [ ":default_config" ] + + include_dirs = [ "${examples_plat_dir}" ] +} diff --git a/examples/platform/bouffalolab/bl602/pw_sys_io/public/pw_sys_io_efr32/init.h b/examples/platform/bouffalolab/bl602/pw_sys_io/public/pw_sys_io_efr32/init.h new file mode 100644 index 00000000000000..f11f5e928f3e14 --- /dev/null +++ b/examples/platform/bouffalolab/bl602/pw_sys_io/public/pw_sys_io_efr32/init.h @@ -0,0 +1,27 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "pw_preprocessor/util.h" + +PW_EXTERN_C_START + +// The actual implement of PreMainInit() in sys_io_BACKEND. +void pw_sys_io_Init(); + +PW_EXTERN_C_END diff --git a/examples/platform/bouffalolab/bl602/pw_sys_io/sys_io_efr32.cc b/examples/platform/bouffalolab/bl602/pw_sys_io/sys_io_efr32.cc new file mode 100644 index 00000000000000..aff53278e1a2af --- /dev/null +++ b/examples/platform/bouffalolab/bl602/pw_sys_io/sys_io_efr32.cc @@ -0,0 +1,81 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "pw_sys_io/sys_io.h" +#include +#include +#include +#include + +#include "uart.h" + +int16_t console_getchar(char * chr) +{ + int16_t retVal = 0; + + // Busy wait for pw_rcp reads + while (retVal == 0) + { + retVal = uartConsoleRead(chr, 1); + } + return retVal; +} + +int16_t console_putchar(const char * chr) +{ + return uartConsoleWrite(chr, 1); +} + +extern "C" void pw_sys_io_Init() +{ + uartConsoleInit(); +} + +namespace pw::sys_io { + +Status ReadByte(std::byte * dest) +{ + if (!dest) + return Status::InvalidArgument(); + + int16_t ret = console_getchar(reinterpret_cast(dest)); + return ret < 0 ? Status::FailedPrecondition() : OkStatus(); +} + +Status WriteByte(std::byte b) +{ + int16_t ret = console_putchar(reinterpret_cast(&b)); + return ret < 0 ? Status::FailedPrecondition() : OkStatus(); +} + +// Writes a string using pw::sys_io, and add newline characters at the end. +StatusWithSize WriteLine(const std::string_view & s) +{ + size_t chars_written = 0; + StatusWithSize result = WriteBytes(std::as_bytes(std::span(s))); + if (!result.ok()) + { + return result; + } + chars_written += result.size(); + result = WriteBytes(std::as_bytes(std::span("\r\n", 2))); + chars_written += result.size(); + + return StatusWithSize(result.status(), chars_written); +} + +} // namespace pw::sys_io diff --git a/examples/platform/bouffalolab/bl602/uart.c b/examples/platform/bouffalolab/bl602/uart.c new file mode 100644 index 00000000000000..d47ac3938ed177 --- /dev/null +++ b/examples/platform/bouffalolab/bl602/uart.c @@ -0,0 +1,307 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "uart.h" +#include "AppConfig.h" +#include "assert.h" +#include "em_core.h" +#include "em_usart.h" +#include "hal-config.h" +#include "sl_uartdrv_usart_vcom_config.h" +#include "uartdrv.h" +#include +#include + +#if !defined(MIN) +#define MIN(A, B) ((A) < (B) ? (A) : (B)) +#endif + +#define HELPER1(x) USART##x##_RX_IRQn +#define HELPER2(x) HELPER1(x) +#define USART_IRQ HELPER2(SL_UARTDRV_USART_VCOM_PERIPHERAL_NO) + +#define HELPER3(x) USART##x##_RX_IRQHandler +#define HELPER4(x) HELPER3(x) +#define USART_IRQHandler HELPER4(SL_UARTDRV_USART_VCOM_PERIPHERAL_NO) + +DEFINE_BUF_QUEUE(EMDRV_UARTDRV_MAX_CONCURRENT_RX_BUFS, sUartRxQueue); +DEFINE_BUF_QUEUE(EMDRV_UARTDRV_MAX_CONCURRENT_TX_BUFS, sUartTxQueue); + +typedef struct +{ + // The data buffer + uint8_t * pBuffer; + // The offset of the first item written to the list. + volatile uint16_t Head; + // The offset of the next item to be written to the list. + volatile uint16_t Tail; + // Maxium size of data that can be hold in buffer before overwriting + uint16_t MaxSize; +} Fifo_t; + +#define UART_CONSOLE_ERR -1 // Negative value in case of UART Console action failed. Triggers a failure for PW_RPC +#define MAX_BUFFER_SIZE 256 +#define MAX_DMA_BUFFER_SIZE (MAX_BUFFER_SIZE / 2) +// In order to reduce the probability of data loss during the dmaFull callback handler we use +// two duplicate receive buffers so we can always have one "active" receive queue. +static uint8_t sRxDmaBuffer[MAX_DMA_BUFFER_SIZE]; +static uint8_t sRxDmaBuffer2[MAX_DMA_BUFFER_SIZE]; +static uint16_t lastCount; // Nb of bytes already processed from the active dmaBuffer + +// Rx buffer for the receive Fifo +static uint8_t sRxFifoBuffer[MAX_BUFFER_SIZE]; +static Fifo_t sReceiveFifo; + +static UARTDRV_HandleData_t sUartHandleData; +static UARTDRV_Handle_t sUartHandle = &sUartHandleData; + +static void UART_rx_callback(UARTDRV_Handle_t handle, Ecode_t transferStatus, uint8_t * data, UARTDRV_Count_t transferCount); + +static bool InitFifo(Fifo_t * fifo, uint8_t * pDataBuffer, uint16_t bufferSize) +{ + if (fifo == NULL || pDataBuffer == NULL) + { + return false; + } + + fifo->pBuffer = pDataBuffer; + fifo->MaxSize = bufferSize; + fifo->Tail = fifo->Head = 0; + + return true; +} + +/* + * @brief Get the amount of unprocessed bytes in the fifo buffer + * @param Ptr to the fifo + * @return Nb of "unread" bytes available in the fifo + */ +static uint16_t AvailableDataCount(Fifo_t * fifo) +{ + uint16_t size = 0; + + // if equal there is no data return 0 directly + if (fifo->Tail != fifo->Head) + { + // determine if a wrap around occurred to get the right data size available. + size = (fifo->Tail < fifo->Head) ? (fifo->MaxSize - fifo->Head + fifo->Tail) : (fifo->Tail - fifo->Head); + } + + return size; +} + +/* + * @brief Get the available space in the fifo buffer to insert new data + * @param Ptr to the fifo + * @return Nb of free bytes left in te buffer + */ +static uint16_t RemainingSpace(Fifo_t * fifo) +{ + return fifo->MaxSize - AvailableDataCount(fifo); +} + +/* + * @brief Write data in the fifo as a circular buffer + * @param Ptr to the fifo, ptr of the data to write, nb of bytes to write + */ +static void WriteToFifo(Fifo_t * fifo, uint8_t * pDataToWrite, uint16_t SizeToWrite) +{ + assert(fifo); + assert(pDataToWrite); + assert(SizeToWrite <= fifo->MaxSize); + + // Overwrite is not allowed + if (RemainingSpace(fifo) >= SizeToWrite) + { + uint16_t nBytesBeforWrap = (fifo->MaxSize - fifo->Tail); + if (SizeToWrite > nBytesBeforWrap) + { + // The number of bytes to write is bigger than the remaining bytes + // in the buffer, we have to wrap around + memcpy(fifo->pBuffer + fifo->Tail, pDataToWrite, nBytesBeforWrap); + memcpy(fifo->pBuffer, pDataToWrite + nBytesBeforWrap, SizeToWrite - nBytesBeforWrap); + } + else + { + memcpy(fifo->pBuffer + fifo->Tail, pDataToWrite, SizeToWrite); + } + + fifo->Tail = (fifo->Tail + SizeToWrite) % fifo->MaxSize; // increment tail with wraparound + } +} + +/* + * @brief Write data in the fifo as a circular buffer + * @param Ptr to the fifo, ptr to contain the data to process, nb of bytes to pull from the fifo + * @return Nb of bytes that were retrieved. + */ +static uint8_t RetrieveFromFifo(Fifo_t * fifo, uint8_t * pData, uint16_t SizeToRead) +{ + assert(fifo); + assert(pData); + assert(SizeToRead <= fifo->MaxSize); + + uint16_t ReadSize = MIN(SizeToRead, AvailableDataCount(fifo)); + uint16_t nBytesBeforWrap = (fifo->MaxSize - fifo->Head); + + if (ReadSize > nBytesBeforWrap) + { + memcpy(pData, fifo->pBuffer + fifo->Head, nBytesBeforWrap); + memcpy(pData + nBytesBeforWrap, fifo->pBuffer, ReadSize - nBytesBeforWrap); + } + else + { + memcpy(pData, (fifo->pBuffer + fifo->Head), ReadSize); + } + + fifo->Head = (fifo->Head + ReadSize) % fifo->MaxSize; // increment tail with wraparound + + return ReadSize; +} + +/* + * @brief Init the the UART for serial communication, Start DMA reception + * and init Fifo to handle the received data from this uart + * + * @Note This UART is used for pigweed rpc + */ +void uartConsoleInit(void) +{ + UARTDRV_Init_t uartInit = { + .port = USART0, + .baudRate = HAL_SERIAL_APP_BAUD_RATE, +#if defined(_USART_ROUTELOC0_MASK) + .portLocationTx = BSP_SERIAL_APP_TX_LOC, + .portLocationRx = BSP_SERIAL_APP_RX_LOC, +#elif defined(_USART_ROUTE_MASK) +#error This configuration is not supported +#elif defined(_GPIO_USART_ROUTEEN_MASK) + .txPort = BSP_SERIAL_APP_TX_PORT, /* USART Tx port number */ + .rxPort = BSP_SERIAL_APP_RX_PORT, /* USART Rx port number */ + .txPin = BSP_SERIAL_APP_TX_PIN, /* USART Tx pin number */ + .rxPin = BSP_SERIAL_APP_RX_PIN, /* USART Rx pin number */ + .uartNum = 0, /* UART instance number */ +#endif +#if defined(USART_CTRL_MVDIS) + .mvdis = false, +#endif + .stopBits = (USART_Stopbits_TypeDef) USART_FRAME_STOPBITS_ONE, + .parity = (USART_Parity_TypeDef) USART_FRAME_PARITY_NONE, + .oversampling = (USART_OVS_TypeDef) USART_CTRL_OVS_X16, + .fcType = HAL_SERIAL_APP_FLOW_CONTROL, + .ctsPort = BSP_SERIAL_APP_CTS_PORT, + .ctsPin = BSP_SERIAL_APP_CTS_PIN, + .rtsPort = BSP_SERIAL_APP_RTS_PORT, + .rtsPin = BSP_SERIAL_APP_RTS_PIN, + .rxQueue = (UARTDRV_Buffer_FifoQueue_t *) &sUartRxQueue, + .txQueue = (UARTDRV_Buffer_FifoQueue_t *) &sUartTxQueue, +#if defined(_USART_ROUTELOC1_MASK) + .portLocationCts = BSP_SERIAL_APP_CTS_LOC, + .portLocationRts = BSP_SERIAL_APP_RTS_LOC, +#endif + }; + + // Init a fifo for the data received on the uart + InitFifo(&sReceiveFifo, sRxFifoBuffer, MAX_BUFFER_SIZE); + + UARTDRV_InitUart(sUartHandle, &uartInit); + // Activate 2 dma queues to always have one active + UARTDRV_Receive(sUartHandle, sRxDmaBuffer, MAX_DMA_BUFFER_SIZE, UART_rx_callback); + UARTDRV_Receive(sUartHandle, sRxDmaBuffer2, MAX_DMA_BUFFER_SIZE, UART_rx_callback); + + // Enable USART0 interrupt to wake OT task when data arrives + NVIC_ClearPendingIRQ(USART_IRQ); + NVIC_EnableIRQ(USART_IRQ); + USART_IntEnable(SL_UARTDRV_USART_VCOM_PERIPHERAL, USART_IF_RXDATAV); +} + +void USART_IRQHandler(void) +{ +#ifndef PW_RPC_ENABLED + otSysEventSignalPending(); +#endif +} + +/* + * @brief Callback triggered when a UARTDRV DMA buffer is full + */ +static void UART_rx_callback(UARTDRV_Handle_t handle, Ecode_t transferStatus, uint8_t * data, UARTDRV_Count_t transferCount) +{ + (void) transferStatus; + + uint8_t writeSize = (transferCount - lastCount); + if (RemainingSpace(&sReceiveFifo) >= writeSize) + { + WriteToFifo(&sReceiveFifo, data + lastCount, writeSize); + lastCount = 0; + } + + UARTDRV_Receive(sUartHandle, data, transferCount, UART_rx_callback); +#ifndef PW_RPC_ENABLED + otSysEventSignalPending(); +#endif +} + +/* + * @brief Read the data available from the console Uart + * @param Buffer that contains the data to write, number bytes to write. + * @return Amount of bytes written or ERROR (-1) + */ +int16_t uartConsoleWrite(const char * Buf, uint16_t BufLength) +{ + if (Buf == NULL || BufLength < 1) + { + return UART_CONSOLE_ERR; + } + + // Use of ForceTransmit here. Transmit with DMA was causing errors with PW_RPC + // TODO Use DMA and find/fix what causes the issue with PW + if (UARTDRV_ForceTransmit(sUartHandle, (uint8_t *) Buf, BufLength) == ECODE_EMDRV_UARTDRV_OK) + { + return BufLength; + } + + return UART_CONSOLE_ERR; +} + +/* + * @brief Read the data available from the console Uart + * @param Buffer for the data to be read, number bytes to read. + * @return Amount of bytes that was read from the rx fifo or ERROR (-1) + */ +int16_t uartConsoleRead(char * Buf, uint16_t NbBytesToRead) +{ + uint8_t * data; + UARTDRV_Count_t count, remaining; + + if (Buf == NULL || NbBytesToRead < 1) + { + return UART_CONSOLE_ERR; + } + + if (NbBytesToRead > AvailableDataCount(&sReceiveFifo)) + { + // Not enough data available in the fifo for the read size request + // If there is data available in dma buffer, get it now. + CORE_ATOMIC_SECTION(UARTDRV_GetReceiveStatus(sUartHandle, &data, &count, &remaining); if (count > lastCount) { + WriteToFifo(&sReceiveFifo, data + lastCount, count - lastCount); + lastCount = count; + }) + } + + return (int16_t) RetrieveFromFifo(&sReceiveFifo, (uint8_t *) Buf, NbBytesToRead); +} diff --git a/examples/platform/bouffalolab/bl602/uart.h b/examples/platform/bouffalolab/bl602/uart.h new file mode 100644 index 00000000000000..f708030223b2f7 --- /dev/null +++ b/examples/platform/bouffalolab/bl602/uart.h @@ -0,0 +1,40 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void uartConsoleInit(void); +int16_t uartConsoleWrite(const char * Buf, uint16_t BufLength); +int16_t uartConsoleRead(char * Buf, uint16_t NbBytesToRead); + +// Implemented by in openthread code +#ifndef PW_RPC_ENABLED +extern void otPlatUartReceived(const uint8_t * aBuf, uint16_t aBufLength); +extern void otPlatUartSendDone(void); +extern void otSysEventSignalPending(void); +#endif + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/scripts/build/BUILD.gn b/scripts/build/BUILD.gn index 127430285611b1..6b253df6a04ff3 100644 --- a/scripts/build/BUILD.gn +++ b/scripts/build/BUILD.gn @@ -34,6 +34,7 @@ pw_python_package("build_examples") { "builders/__init__.py", "builders/ameba.py", "builders/android.py", + "builders/bl602.py", "builders/builder.py", "builders/efr32.py", "builders/esp32.py", diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index 13a46ef4d07ec4..1c0a79b72304d6 100644 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -31,6 +31,7 @@ from builders.qpg import QpgApp, QpgBoard, QpgBuilder from builders.telink import TelinkApp, TelinkBoard, TelinkBuilder from builders.tizen import TizenApp, TizenBoard, TizenBuilder +from builders.bl602 import Bl602App, Bl602Board, Bl602Builder class Target: @@ -483,6 +484,12 @@ def QorvoTargets(): yield target.Extend('persistent-storage', board=QpgBoard.QPG6105, app=QpgApp.PERSISTENT_STORAGE) +def Bl602Targets(): + target = Target('bl602', Bl602Builder) + + yield target.Extend('light', board=Bl602Board.BL602BOARD, app=Bl602App.LIGHT) + + ALL = [] target_generators = [ @@ -498,6 +505,7 @@ def QorvoTargets(): cc13x2x7_26x2x7Targets(), Cyw30739Targets(), QorvoTargets(), + Bl602Targets(), ] for generator in target_generators: diff --git a/scripts/build/builders/bl602.py b/scripts/build/builders/bl602.py new file mode 100644 index 00000000000000..e559a068ecd0ec --- /dev/null +++ b/scripts/build/builders/bl602.py @@ -0,0 +1,81 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +from enum import Enum, auto + +from .gn import GnBuilder + + +class Bl602App(Enum): + LOCK = auto() + LIGHT = auto() + ALL_CLUSTERS = auto() + + def ExampleName(self): + if self == Bl602App.LIGHT: + return 'lighting-app' + else: + raise Exception('Unknown app type: %r' % self) + + def AppNamePrefix(self): + if self == Bl602App.LIGHT: + return 'chip-bl602-lighting-example' + else: + raise Exception('Unknown app type: %r' % self) + + def FlashBundleName(self): + if self == Bl602App.LOCK: + return 'lighting_app.flashbundle.txt' + else: + raise Exception('Unknown app type: %r' % self) + + +class Bl602Board(Enum): + BL602BOARD = 1 + + def GnArgName(self): + if self == Bl602Board.BL602BOARD: + return 'BL-HWC-G1' + + +class Bl602Builder(GnBuilder): + + def __init__(self, + root, + runner, + app: Bl602App = Bl602App.LIGHT, + board: Bl602Board = Bl602Board.BL602BOARD): + super(Bl602Builder, self).__init__( + root=os.path.join(root, 'examples', + app.ExampleName(), 'bouffalolab', 'bl602'), + runner=runner) + + self.app = app + self.board = board + + def GnBuildArgs(self): + return ['bl602_board="%s"' % self.board.GnArgName()] + + def build_outputs(self): + items = { + '%s.out' % self.app.AppNamePrefix(): + os.path.join(self.output_dir, '%s.out' % + self.app.AppNamePrefix()), + '%s.out.map' % self.app.AppNamePrefix(): + os.path.join(self.output_dir, + '%s.out.map' % self.app.AppNamePrefix()), + } + + return items diff --git a/scripts/build/testdata/all_targets_except_host.txt b/scripts/build/testdata/all_targets_except_host.txt index 185ccc69a86fec..464a4c7294b686 100644 --- a/scripts/build/testdata/all_targets_except_host.txt +++ b/scripts/build/testdata/all_targets_except_host.txt @@ -14,6 +14,7 @@ android-arm64-chip-tv-casting-app android-arm64-chip-tvserver android-x64-chip-tool android-x86-chip-tool +bl602-light cc13x2x7_26x2x7-lock-ftd cc13x2x7_26x2x7-lock-mtd cc13x2x7_26x2x7-pump diff --git a/scripts/build/testdata/build_all_except_host.txt b/scripts/build/testdata/build_all_except_host.txt index d9baa35cf9543f..7ad5c54a89da61 100644 --- a/scripts/build/testdata/build_all_except_host.txt +++ b/scripts/build/testdata/build_all_except_host.txt @@ -166,6 +166,9 @@ gn gen --check --fail-on-unused-args {out}/android-x86-chip-tool '--args=target_ # Accepting NDK licenses @ tools bash -c 'yes | TEST_ANDROID_HOME/tools/bin/sdkmanager --licenses >/dev/null' +# Generating bl602-light +gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/examples/lighting-app/bouffalolab/bl602 '--args=bl602_board="BL-HWC-G1"' {out}/bl602-light + # Generating cc13x2x7_26x2x7-lock-ftd gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/examples/lock-app/cc13x2x7_26x2x7 '--args=ti_sysconfig_root="TEST_TI_SYSCONFIG_ROOT" chip_openthread_ftd=true' {out}/cc13x2x7_26x2x7-lock-ftd @@ -1125,6 +1128,9 @@ cp {out}/android-x86-chip-tool/lib/src/platform/android/AndroidPlatform.jar {roo # Building APP android-x86-chip-tool {root}/src/android/CHIPTool/gradlew -p {root}/src/android/CHIPTool -PmatterBuildSrcDir={out}/android-x86-chip-tool -PmatterSdkSourceBuild=false -PbuildDir={out}/android-x86-chip-tool assembleDebug +# Building bl602-light +ninja -C {out}/bl602-light + # Building cc13x2x7_26x2x7-lock-ftd ninja -C {out}/cc13x2x7_26x2x7-lock-ftd diff --git a/scripts/build/testdata/glob_star_targets_except_host.txt b/scripts/build/testdata/glob_star_targets_except_host.txt index 815344ef4ea39d..3adfb5b384ab2e 100644 --- a/scripts/build/testdata/glob_star_targets_except_host.txt +++ b/scripts/build/testdata/glob_star_targets_except_host.txt @@ -14,6 +14,7 @@ android-arm64-chip-tv-casting-app android-arm64-chip-tvserver android-x64-chip-tool android-x86-chip-tool +bl602-light cc13x2x7_26x2x7-lock-ftd cc13x2x7_26x2x7-lock-mtd cc13x2x7_26x2x7-pump diff --git a/scripts/examples/gn_bl602_example.sh b/scripts/examples/gn_bl602_example.sh new file mode 100755 index 00000000000000..9b6d02b3927b3f --- /dev/null +++ b/scripts/examples/gn_bl602_example.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +# +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -e +# Build script for GN BL602 examples GitHub workflow. +source "$(dirname "$0")/../../scripts/activate.sh" + +set -x +env + +# Build steps +EXAMPLE_DIR=$1 +shift +OUTPUT_DIR=out/example_app +BL602_BOARD=BL-HWC-G1 +MATTER_BL_ROOT=$PWD +export BL602_SDK_ROOT="$MATTER_BL_ROOT"/third_party/bouffalolab/bl602_sdk/repo +export PATH="$BL602_SDK_ROOT/toolchain/riscv/Linux/bin:$PATH" + +if [[ ! -z "$1" ]]; then + OUTPUT_DIR=$1 + shift +fi + +GN_ARGS=() +NINJA_ARGS=() + +for arg; do + case $arg in + -v) + NINJA_ARGS+=(-v) + ;; + *=*) + GN_ARGS+=("$arg") + ;; + *import*) + GN_ARGS+=("$arg") + ;; + *) + echo >&2 "invalid argument: $arg" + exit 2 + ;; + esac +done + +#gn clean out/lighting_app_bl602 +gn gen "$OUTPUT_DIR" --root="$EXAMPLE_DIR" --args="${GN_ARGS[*]}" +ninja -C "$OUTPUT_DIR" "${NINJA_ARGS[@]}" diff --git a/scripts/flashing/bl602_firmware_utils.py b/scripts/flashing/bl602_firmware_utils.py new file mode 100755 index 00000000000000..a07e7dbf51c3e2 --- /dev/null +++ b/scripts/flashing/bl602_firmware_utils.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python3 +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Flash an BL602 device. + +This is layered so that a caller can perform individual operations +through an `Flasher` instance, or operations according to a command line. +For `Flasher`, see the class documentation. For the parse_command() +interface or standalone execution: + +usage: bl602_firmware_utils.py [-h] [--verbose] [--erase] [--application FILE] + [--verify_application] [--reset] [--skip_reset] + [--commander FILE] [--device DEVICE] + [--serialno SERIAL] + +Flash BL602 device + +optional arguments: + -h, --help show this help message and exit + +configuration: + --verbose, -v Report more verbosely + --commander FILE File name of the commander executable + --device DEVICE, -d DEVICE + Device family or platform to target + --serialno SERIAL, -s SERIAL + Serial number of device to flash + +operations: + --erase Erase device + --application FILE Flash an image + --verify_application, --verify-application + Verify the image after flashing + --reset Reset device after flashing + --skip_reset, --skip-reset + Do not reset device after flashing +""" + +import sys + +import firmware_utils + +# Additional options that can be use to configure an `Flasher` +# object (as dictionary keys) and/or passed as command line options. +BL602_OPTIONS = { + # Configuration options define properties used in flashing operations. + 'configuration': { + # Tool configuration options. + 'commander': { + 'help': 'File name of the commander executable', + 'default': 'commander', + 'argparse': { + 'metavar': 'FILE' + }, + 'verify': ['{commander}', '--version'], + 'error': + """\ + Unable to execute {commander}. + + Please ensure that this tool is installed and + available. See the BL602 example README for + installation instructions. + + """, + }, + 'device': { + 'help': 'Device family or platform to target', + 'default': 'BL602', + 'alias': ['-d'], + 'argparse': { + 'metavar': 'DEVICE' + }, + }, + 'serialno': { + 'help': 'Serial number of device to flash', + 'default': None, + 'alias': ['-s'], + 'argparse': { + 'metavar': 'SERIAL' + }, + }, + }, +} + + +class Flasher(firmware_utils.Flasher): + """Manage bl602 flashing.""" + + def __init__(self, **options): + super().__init__(platform='BL602', module=__name__, **options) + self.define_options(BL602_OPTIONS) + + # Common command line arguments for commander device subcommands. + DEVICE_ARGUMENTS = [{'optional': 'serialno'}, {'optional': 'device'}] + + def erase(self): + """Perform `commander device masserase`.""" + return self.run_tool( + 'commander', ['device', 'masserase', self.DEVICE_ARGUMENTS], + name='Erase device') + + def verify(self, image): + """Verify image.""" + return self.run_tool( + 'commander', + ['verify', self.DEVICE_ARGUMENTS, image], + name='Verify', + pass_message='Verified', + fail_message='Not verified', + fail_level=2) + + def flash(self, image): + """Flash image.""" + return self.run_tool( + 'commander', + ['flash', self.DEVICE_ARGUMENTS, image], + name='Flash') + + def reset(self): + """Reset the device.""" + return self.run_tool( + 'commander', + ['device', 'reset', self.DEVICE_ARGUMENTS], + name='Reset') + + def actions(self): + """Perform actions on the device according to self.option.""" + self.log(3, 'Options:', self.option) + + if self.option.erase: + if self.erase().err: + return self + + application = self.optional_file(self.option.application) + if application: + if self.flash(application).err: + return self + if self.option.verify_application: + if self.verify(application).err: + return self + if self.option.reset is None: + self.option.reset = True + + if self.option.reset: + if self.reset().err: + return self + + return self + + +if __name__ == '__main__': + sys.exit(Flasher().flash_command(sys.argv)) diff --git a/scripts/tools/check_includes_config.py b/scripts/tools/check_includes_config.py index 72e399bd695317..36491a3041a251 100644 --- a/scripts/tools/check_includes_config.py +++ b/scripts/tools/check_includes_config.py @@ -48,6 +48,7 @@ '/platform/nxp/', '/platform/Tizen/', '/platform/P6/', + '/platform/bouffalolab/BL602', r'POSIX\.h$', } diff --git a/src/lib/shell/BUILD.gn b/src/lib/shell/BUILD.gn index 04202cbbf95c52..622645279600dc 100644 --- a/src/lib/shell/BUILD.gn +++ b/src/lib/shell/BUILD.gn @@ -74,6 +74,11 @@ static_library("shell") { "MainLoopDefault.cpp", "streamer_qpg.cpp", ] + } else if (chip_device_platform == "bl602") { + sources += [ + "MainLoopDefault.cpp", + "streamer_bl602.cpp", + ] } else { sources += [ "MainLoopDefault.cpp" ] } diff --git a/src/lwip/BUILD.gn b/src/lwip/BUILD.gn index 930fe804b1534f..3cc14c4ee08e56 100644 --- a/src/lwip/BUILD.gn +++ b/src/lwip/BUILD.gn @@ -32,7 +32,7 @@ assert(lwip_platform == "external" || lwip_platform == "standalone" || lwip_platform == "cc13x2_26x2" || lwip_platform == "efr32" || lwip_platform == "k32w0" || lwip_platform == "qpg" || lwip_platform == "mbed" || lwip_platform == "p6" || - lwip_platform == "cyw30739", + lwip_platform == "cyw30739" || lwip_platform == "bl602", "Unsupported lwIP platform: ${lwip_platform}") if (lwip_platform != "external") { @@ -55,6 +55,8 @@ if (lwip_platform == "cc13x2_26x2") { import("//build_overrides/p6.gni") } else if (lwip_platform == "cyw30739") { import("//build_overrides/cyw30739_sdk.gni") +} else if (lwip_platform == "bl602") { + import("//build_overrides/bl602_sdk.gni") } buildconfig_header("lwip_buildconfig") { @@ -117,6 +119,15 @@ if (current_os == "zephyr" || current_os == "mbed") { "${chip_root}/src:includes", ] } +} else if (lwip_platform == "bl602") { + group("lwip") { + public_deps = [ ":lwip_buildconfig" ] + public_deps += [ "${bl602_sdk_build_root}:bl602_sdk" ] + } + + group("all") { + deps = [ ":lwip" ] + } } else { config("lwip_config") { include_dirs = [ lwip_platform ] @@ -158,6 +169,8 @@ if (current_os == "zephyr" || current_os == "mbed") { public_deps += [ "${k32w0_sdk_build_root}:k32w0_sdk" ] } else if (lwip_platform == "cyw30739") { public_deps += [ "${cyw30739_sdk_build_root}:cyw30739_sdk" ] + } else if (lwip_platform == "bl602") { + public_deps += [ "${bl602_sdk_build_root}:bl602_sdk" ] } public_configs = [ diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index 73d4cabe87c1cf..27bd7dd608ca27 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -209,6 +209,11 @@ if (chip_device_platform != "none" && chip_device_platform != "external") { "CHIP_DEVICE_CONFIG_ENABLE_WIFI=${chip_enable_wifi}", "CHIP_DEVICE_ENABLE_DATA_MODEL=${chip_enable_data_model}", ] + } else if (chip_device_platform == "bl602") { + defines += [ + "CHIP_DEVICE_LAYER_TARGET_BL602=1", + "CHIP_DEVICE_LAYER_TARGET=bouffalolab/BL602", + ] } else if (chip_device_platform == "fake") { defines += [ "CHIP_DEVICE_LAYER_TARGET_FAKE=1", @@ -382,6 +387,8 @@ if (chip_device_platform != "none") { _platform_target = "Ameba" } else if (chip_device_platform == "webos") { _platform_target = "webos" + } else if (chip_device_platform == "bl602") { + _platform_target = "bouffalolab/BL602" } else if (chip_device_platform == "fake") { _platform_target = "fake" } else if (chip_device_platform == "cyw30739") { diff --git a/src/platform/bouffalolab/BL602/BL602Config.cpp b/src/platform/bouffalolab/BL602/BL602Config.cpp new file mode 100644 index 00000000000000..025d48ae18cd16 --- /dev/null +++ b/src/platform/bouffalolab/BL602/BL602Config.cpp @@ -0,0 +1,373 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019-2020 Google LLC. + * Copyright (c) 2019 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Utilities for interacting with the the BL602 Easyflash module. + */ +/* this file behaves like a config.h, comes first */ +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +// 3R: easyflash errno mapping to the CHIP errno + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +const BL602Config::Key BL602Config::kConfigKey_SerialNum = { "serial-num" }; +const BL602Config::Key BL602Config::kConfigKey_MfrDeviceId = { "device-id" }; +const BL602Config::Key BL602Config::kConfigKey_MfrDeviceCert = { "device-cert" }; +const BL602Config::Key BL602Config::kConfigKey_MfrDeviceICACerts = { "device-ca-certs" }; +const BL602Config::Key BL602Config::kConfigKey_MfrDevicePrivateKey = { "device-key" }; +const BL602Config::Key BL602Config::kConfigKey_HardwareVersion = { "hardware-ver" }; +const BL602Config::Key BL602Config::kConfigKey_ManufacturingDate = { "mfg-date" }; +const BL602Config::Key BL602Config::kConfigKey_SetupPinCode = { "pin-code" }; +const BL602Config::Key BL602Config::kConfigKey_SetupDiscriminator = { "discriminator" }; +const BL602Config::Key BL602Config::kConfigKey_Spake2pIterationCount = { "iteration-count" }; +const BL602Config::Key BL602Config::kConfigKey_Spake2pSalt = { "salt" }; +const BL602Config::Key BL602Config::kConfigKey_Spake2pVerifier = { "verifier" }; + +// Keys stored in the chip-config namespace +const BL602Config::Key BL602Config::kConfigKey_FabricId = { "fabric-id" }; +const BL602Config::Key BL602Config::kConfigKey_ServiceConfig = { "service-config" }; +const BL602Config::Key BL602Config::kConfigKey_PairedAccountId = { "account-id" }; +const BL602Config::Key BL602Config::kConfigKey_ServiceId = { "service-id" }; +const BL602Config::Key BL602Config::kConfigKey_GroupKeyIndex = { "group-key-index" }; +const BL602Config::Key BL602Config::kConfigKey_LastUsedEpochKeyId = { "last-ek-id" }; +const BL602Config::Key BL602Config::kConfigKey_FailSafeArmed = { "fail-safe-armed" }; +const BL602Config::Key BL602Config::kConfigKey_WiFiStationSecType = { "sta-sec-type" }; +const BL602Config::Key BL602Config::kConfigKey_OperationalDeviceId = { "op-device-id" }; +const BL602Config::Key BL602Config::kConfigKey_OperationalDeviceCert = { "op-device-cert" }; +const BL602Config::Key BL602Config::kConfigKey_OperationalDeviceICACerts = { "op-device-ca-certs" }; +const BL602Config::Key BL602Config::kConfigKey_OperationalDevicePrivateKey = { "op-device-key" }; +const BL602Config::Key BL602Config::kConfigKey_RegulatoryLocation = { "regulatory-location" }; +const BL602Config::Key BL602Config::kConfigKey_CountryCode = { "country-code" }; +const BL602Config::Key BL602Config::kConfigKey_Breadcrumb = { "breadcrumb" }; +const BL602Config::Key BL602Config::kConfigKey_UniqueId = { "unique-id" }; + +// Prefix used for Easyflash keys that contain Chip group encryption keys. +const char BL602Config::kGroupKeyNamePrefix[] = "gk-"; + +CHIP_ERROR BL602Config::Init() +{ + EfErrCode err = easyflash_init(); + if (EF_NO_ERR == err) + return CHIP_NO_ERROR; + + log_error("easyflash_init() failed. err: %d\r\n", err); + return CHIP_ERROR_NO_MEMORY; +} + +CHIP_ERROR BL602Config::ReadConfigValue(Key key, bool & val) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + bool tmpVal; + size_t ret, valLen; + + ret = ef_get_env_blob(key.name, &tmpVal, sizeof(tmpVal), &valLen); + if (ret <= 0) + { + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + SuccessOrExit(err); + + val = tmpVal; + +exit: + return err; +} + +CHIP_ERROR BL602Config::ReadConfigValue(Key key, uint32_t & val) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + uint32_t tmpVal; + size_t ret, valLen; + + ret = ef_get_env_blob(key.name, &tmpVal, sizeof(tmpVal), &valLen); + if (ret <= 0) + { + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + SuccessOrExit(err); + + val = tmpVal; + +exit: + return err; +} + +CHIP_ERROR BL602Config::ReadConfigValue(Key key, uint64_t & val) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + uint64_t tmpVal; + size_t ret, valLen; + + ret = ef_get_env_blob(key.name, &tmpVal, sizeof(tmpVal), &valLen); + if (ret <= 0) + { + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + SuccessOrExit(err); + + val = tmpVal; +exit: + return err; +} + +CHIP_ERROR BL602Config::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + char tmpVal[bufSize] = { 0 }; + size_t ret; + + ret = ef_get_env_blob(key.name, tmpVal, sizeof(tmpVal) - 1, NULL); + if ('\0' == tmpVal[0]) + { + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + SuccessOrExit(err); + + outLen = ret; + strncpy(buf, tmpVal, outLen); + +exit: + return err; +} + +CHIP_ERROR BL602Config::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + char tmpVal[bufSize] = { 0 }; + size_t ret; + size_t savedLen = 0; + + ret = ef_get_env_blob(key.name, tmpVal, sizeof(tmpVal), &savedLen); + if (0 == savedLen) + { + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + SuccessOrExit(err); + + outLen = ret; + memcpy(buf, tmpVal, outLen); + +exit: + return err; +} + +CHIP_ERROR BL602Config::WriteConfigValue(Key key, bool val) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + EfErrCode ret = ef_set_env_blob(key.name, &val, sizeof(val)); + if (ret != EF_NO_ERR) + { + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + SuccessOrExit(err); + + // ChipLogProgress(DeviceLayer, "Easyflash set: %s = %s", key.name, val ? "true" : "false"); +exit: + return err; +} + +CHIP_ERROR BL602Config::WriteConfigValue(Key key, uint32_t val) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + EfErrCode ret = ef_set_env_blob(key.name, &val, sizeof(val)); + if (ret != EF_NO_ERR) + { + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + SuccessOrExit(err); + + // ChipLogProgress(DeviceLayer, "Easyflash set: %s = %" PRIu32 " (0x%" PRIX32 ")", key.name, val, val); + +exit: + return err; +} + +CHIP_ERROR BL602Config::WriteConfigValue(Key key, uint64_t val) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + EfErrCode ret = ef_set_env_blob(key.name, &val, sizeof(val)); + if (ret != EF_NO_ERR) + { + log_error("WriteConfigValue() failed. key: %s, ret: %d\r\n", key.name, ret); + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + SuccessOrExit(err); + + // ChipLogProgress(DeviceLayer, "Easyflash set: %s = %" PRIu64 " (0x%" PRIX64 ")", key.name, val, val); + +exit: + return err; +} + +CHIP_ERROR BL602Config::WriteConfigValueStr(Key key, const char * str) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + if (str != NULL) + { + EfErrCode ret = ef_set_env(key.name, str); + if (ret != EF_NO_ERR) + { + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + SuccessOrExit(err); + + // ChipLogProgress(DeviceLayer, "Easyflash set: %s = \"%s\"", key.name, str); + } + else + { + err = ClearConfigValue(key); + SuccessOrExit(err); + } + +exit: + return err; +} + +CHIP_ERROR BL602Config::WriteConfigValueStr(Key key, const char * str, size_t strLen) +{ + CHIP_ERROR err; + chip::Platform::ScopedMemoryBuffer strCopy; + + if (str != NULL) + { + strCopy.Calloc(strLen + 1); + VerifyOrExit(strCopy, err = CHIP_ERROR_NO_MEMORY); + strncpy(strCopy.Get(), str, strLen); + } + err = BL602Config::WriteConfigValueStr(key, strCopy.Get()); + +exit: + return err; +} + +CHIP_ERROR BL602Config::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + if (data != NULL) + { + EfErrCode ret = ef_set_env_blob(key.name, data, dataLen); + if (ret != EF_NO_ERR) + { + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + SuccessOrExit(err); + + // ChipLogProgress(DeviceLayer, "Easyflash set: /%s = (blob length %" PRId32 ")", key.name, (unsigned long )dataLen); + } + else + { + err = ClearConfigValue(key); + SuccessOrExit(err); + } + +exit: + return err; +} + +CHIP_ERROR BL602Config::WriteWifiInfo(const char * ssid, const char * passwd) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + +#if 0 + if (ssid != NULL && passwd != NULL) + { + EfErrCode ret = ef_set_env_blob(kBLConfigKey_wifissid, ssid, strlen(ssid)); + if (ret != EF_NO_ERR) + { + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + ef_set_env_blob(kBLConfigKey_wifipassword, passwd, strlen(passwd)); + if (ret != EF_NO_ERR) + { + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + SuccessOrExit(err); + + } + else + { + //err = ClearConfigValue(ssid); + //err = ClearConfigValue(passwd); + SuccessOrExit(err); + } + +exit: +#endif + + return err; +} + +CHIP_ERROR BL602Config::ClearConfigValue(Key key) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EfErrCode ret = ef_del_env(key.name); + if (ret != EF_NO_ERR) + { + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + SuccessOrExit(err); + + ChipLogProgress(DeviceLayer, "Easyflash erase: %s", key.name); + +exit: + return err; +} + +bool BL602Config::ConfigValueExists(Key key) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + env_node_obj node; + bool result = ef_get_env_obj(key.name, &node); + if (!result) + { + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + + return err == CHIP_NO_ERROR; +} + +void BL602Config::RunConfigUnitTest() {} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/BL602Config.h b/src/platform/bouffalolab/BL602/BL602Config.h new file mode 100644 index 00000000000000..4422d6d10014ac --- /dev/null +++ b/src/platform/bouffalolab/BL602/BL602Config.h @@ -0,0 +1,135 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019-2020 Google LLC. + * Copyright (c) 2019 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Utilities for interacting with the the BL602 Easyflash module. + */ + +#pragma once + +#include + +#include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +/** + * Provides functions and definitions for accessing device configuration information on the BL602 platform. + * + * This class is designed to be mixed-in to concrete implementation classes as a means to + * provide access to configuration information to generic base classes. + */ +class BL602Config +{ +public: + static constexpr const char * kBLConfigKey_wifissid = ("bl-wifi-ssid"); + static constexpr const char * kBLConfigKey_wifipassword = ("bl-wifi-psk"); + struct Key; + + // Maximum length of an easyflash key name + static constexpr size_t kMaxConfigKeyNameLength = 15; + + // Easyflash namespaces used to store device configuration information. + static const char kConfigNamespace_ChipFactory[]; + static const char kConfigNamespace_ChipConfig[]; + static const char kConfigNamespace_ChipCounters[]; + + // Key definitions for well-known keys. + static const Key kConfigKey_SerialNum; + static const Key kConfigKey_MfrDeviceId; + static const Key kConfigKey_MfrDeviceCert; + static const Key kConfigKey_MfrDeviceICACerts; + static const Key kConfigKey_MfrDevicePrivateKey; + static const Key kConfigKey_HardwareVersion; + static const Key kConfigKey_ManufacturingDate; + static const Key kConfigKey_SetupPinCode; + static const Key kConfigKey_FabricId; + static const Key kConfigKey_ServiceConfig; + static const Key kConfigKey_PairedAccountId; + static const Key kConfigKey_ServiceId; + static const Key kConfigKey_FabricSecret; + static const Key kConfigKey_GroupKeyIndex; + static const Key kConfigKey_LastUsedEpochKeyId; + static const Key kConfigKey_FailSafeArmed; + static const Key kConfigKey_WiFiStationSecType; + static const Key kConfigKey_OperationalDeviceId; + static const Key kConfigKey_OperationalDeviceCert; + static const Key kConfigKey_OperationalDeviceICACerts; + static const Key kConfigKey_OperationalDevicePrivateKey; + static const Key kConfigKey_SetupDiscriminator; + static const Key kConfigKey_RegulatoryLocation; + static const Key kConfigKey_CountryCode; + static const Key kConfigKey_Breadcrumb; + static const Key kConfigKey_UniqueId; + static const Key kConfigKey_Spake2pIterationCount; + static const Key kConfigKey_Spake2pSalt; + static const Key kConfigKey_Spake2pVerifier; + + static const char kGroupKeyNamePrefix[]; + + static CHIP_ERROR Init(void); + + // Config value accessors. + static CHIP_ERROR ReadConfigValue(Key key, bool & val); + static CHIP_ERROR ReadConfigValue(Key key, uint32_t & val); + static CHIP_ERROR ReadConfigValue(Key key, uint64_t & val); + static CHIP_ERROR ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen); + static CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen); + static CHIP_ERROR ReadConfigValueBin(const char * key, uint8_t * buf, size_t bufSize, size_t & outLen); + + static CHIP_ERROR WriteConfigValue(Key key, bool val); + static CHIP_ERROR WriteConfigValue(Key key, uint32_t val); + static CHIP_ERROR WriteConfigValue(Key key, uint64_t val); + static CHIP_ERROR WriteConfigValueStr(Key key, const char * str); + static CHIP_ERROR WriteConfigValueStr(Key key, const char * str, size_t strLen); + static CHIP_ERROR WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen); + static CHIP_ERROR WriteWifiInfo(const char * ssid, const char * passwd); + static CHIP_ERROR ReadWiFiInfo(const char * ssid, uint32_t ssid_size, const char * passwd, uint32_t passwd_size); + static bool isWiFiInfoSaved(void); + + static CHIP_ERROR ClearConfigValue(Key key); + static bool ConfigValueExists(Key key); + + // // NVS Namespace helper functions. + // static CHIP_ERROR EnsureNamespace(const char * ns); + // static CHIP_ERROR ClearNamespace(const char * ns); + + static void RunConfigUnitTest(void); +}; + +struct BL602Config::Key +{ + // const char * Namespace; + const char * name; + + bool operator==(const Key & other) const; +}; + +inline bool BL602Config::Key::operator==(const Key & other) const +{ + return strcmp(name, other.name) == 0; +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/BLEManagerImpl.cpp b/src/platform/bouffalolab/BL602/BLEManagerImpl.cpp new file mode 100644 index 00000000000000..ff44832de1490d --- /dev/null +++ b/src/platform/bouffalolab/BL602/BLEManagerImpl.cpp @@ -0,0 +1,866 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the BLEManager singleton object + * for the BL602 platform. + */ + +#define __ZEPHYR__ 1 +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +// #include +#include "BLEManagerImpl.h" + +#include +#include +#include +#include + +extern "C" { +// #include +#include + +#if 0 +// BaseType_t xPortIsInsideInterrupt(void) __attribute__((weak, alias("_xPortIsInsideInterrupt"))); +// BaseType_t _xPortIsInsideInterrupt(void) +BaseType_t xPortIsInsideInterrupt(void) +{ + return TrapNetCounter ? 1 : 0; +} +#endif +} + +#include +#include +// #include +// #include +// #include +// #include + +using namespace ::chip; +using namespace ::chip::Ble; +using namespace ::chip::System; + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +namespace { + +const bt_uuid_128 UUID128_CHIPoBLEChar_RX = + BT_UUID_INIT_128(0x11, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18); +const bt_uuid_128 UUID128_CHIPoBLEChar_TX = + BT_UUID_INIT_128(0x12, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18); +bt_uuid_16 UUID16_CHIPoBLEService = BT_UUID_INIT_16(0xFFF6); + +// #define UUID128_CHIPoBLEChar_RX BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x119d9f42, 0x9c4f, 0x9f95, 0x5945, 0x3d26f52eee18)) +// #define UUID128_CHIPoBLEChar_TX BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x129d9f42, 0x9c4f, 0x9f95, 0x5945, 0x3d26f52eee18)) +// #define UUID16_CHIPoBLEService BT_UUID_DECLARE_16(0xFFF6) + +const ChipBleUUID chipUUID_CHIPoBLEChar_RX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, + 0x9D, 0x11 } }; + +const ChipBleUUID chipUUID_CHIPoBLEChar_TX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, + 0x9D, 0x12 } }; + +_bt_gatt_ccc CHIPoBLEChar_TX_CCC = BT_GATT_CCC_INITIALIZER(nullptr, BLEManagerImpl::HandleTXCCCWrite, nullptr); + +// clang-format off + +BT_GATT_SERVICE_DEFINE(_3_CHIPoBLE_Service, + BT_GATT_PRIMARY_SERVICE(&UUID16_CHIPoBLEService.uuid), + BT_GATT_CHARACTERISTIC(&UUID128_CHIPoBLEChar_RX.uuid, + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP, + BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, + nullptr, BLEManagerImpl::HandleRXWrite, nullptr), + BT_GATT_CHARACTERISTIC(&UUID128_CHIPoBLEChar_TX.uuid, + BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_NONE, + nullptr, nullptr, nullptr), + BT_GATT_CCC_MANAGED(&CHIPoBLEChar_TX_CCC, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE) +); + +// static struct bt_gatt_attr attr = BT_GATT_PRIMARY_SERVICE(UUID16_CHIPoBLEService); + +// clang-format on + +// Index of the CCC descriptor in the CHIPoBLE_Service array of attributes. +// This value should be adjusted accordingly if the service declaration changes. +constexpr int kCHIPoBLE_CCC_AttributeIndex = 3; + +void InitRandomStaticAddress() +{ +#if !CONFIG_BT_PRIVACY + // When the BT privacy feature is disabled, generate a random static address once per boot. + // This must be done before bt_enable() has been called. + bt_addr_le_t addr; + + int error = bt_addr_le_create_static(&addr); + VerifyOrReturn(error == 0, ChipLogError(DeviceLayer, "Failed to create BLE address: %d", error)); + + error = bt_id_create(&addr, nullptr); + VerifyOrReturn(error == 0, ChipLogError(DeviceLayer, "Failed to create BLE identity: %d", error)); + + ChipLogProgress(DeviceLayer, "BLE address was set to %02X:%02X:%02X:%02X:%02X:%02X", addr.a.val[5], addr.a.val[4], + addr.a.val[3], addr.a.val[2], addr.a.val[1], addr.a.val[0]); +#endif +} + +} // unnamed namespace + +BLEManagerImpl BLEManagerImpl::sInstance; + +static void bt_enable_cb(int err) +{ + log_info("err: %d\r\n", err); + if (!err) + { + log_info("trace\r\n"); + // ble_cli_register(); + // log_info("trace\r\n"); + } +} + +// static extern "C" void ble_stack_start(void) +static void ble_stack_start(void) +{ + log_info("trace\r\n"); + // Initialize BLE controller + ble_controller_init(configMAX_PRIORITIES - 1); + log_info("trace\r\n"); + // Initialize BLE Host stack + hci_driver_init(); + log_info("trace\r\n"); + bt_enable(bt_enable_cb); + log_info("trace\r\n"); +} + +CHIP_ERROR BLEManagerImpl::_Init() +{ + CHIP_ERROR err; + log_info("trace\r\n"); + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled; + mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART); + mFlags.Set(Flags::kFastAdvertisingEnabled, true); + mGAPConns = 0; + + log_info("trace\r\n"); + memset(mSubscribedConns, 0, sizeof(mSubscribedConns)); + + InitRandomStaticAddress(); + log_info("trace\r\n"); + // err = bt_enable(NULL); + // log_info("err: %d\r\n", err); + // VerifyOrExit(err == CHIP_NO_ERROR, err = MapErrorZephyr(err)); + ble_stack_start(); + + memset(&mConnCallbacks, 0, sizeof(mConnCallbacks)); + mConnCallbacks.connected = HandleConnect; + mConnCallbacks.disconnected = HandleDisconnect; + + log_info("trace\r\n"); + bt_conn_cb_register(&mConnCallbacks); + + log_info("trace\r\n"); + // Initialize the CHIP BleLayer. + err = BleLayer::Init(this, this, &DeviceLayer::SystemLayer()); + log_info("err: %d\r\n", err); + + PlatformMgr().ScheduleWork(DriveBLEState, 0); + + log_info("trace\r\n"); +exit: + return err; +} + +void BLEManagerImpl::DriveBLEState(intptr_t arg) +{ + BLEMgrImpl().DriveBLEState(); +} + +void BLEManagerImpl::DriveBLEState() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + ChipLogDetail(DeviceLayer, "In DriveBLEState"); + + // Perform any initialization actions that must occur after the CHIP task is running. + if (!mFlags.Has(Flags::kAsyncInitCompleted)) + { + mFlags.Set(Flags::kAsyncInitCompleted); + + // If CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED is enabled, + // disable CHIPoBLE advertising if the device is fully provisioned. +#if CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED + if (ConfigurationMgr().IsFullyProvisioned()) + { + mFlags.Clear(Flags::kAdvertisingEnabled); + ChipLogProgress(DeviceLayer, "CHIPoBLE advertising disabled because device is fully provisioned"); + } +#endif // CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED + } + + // If the application has enabled CHIPoBLE and BLE advertising... + if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && + mFlags.Has(Flags::kAdvertisingEnabled) +#if CHIP_DEVICE_CONFIG_CHIPOBLE_SINGLE_CONNECTION + // and no connections are active... + && (NumConnections() == 0) +#endif + ) + { + // Start/re-start advertising if not already advertising, or if the + // advertising state needs to be refreshed. + if (!mFlags.Has(Flags::kAdvertising) || mFlags.Has(Flags::kAdvertisingRefreshNeeded)) + { + mFlags.Clear(Flags::kAdvertisingRefreshNeeded); + err = StartAdvertising(); + SuccessOrExit(err); + } + } + // Otherwise, stop advertising if currently active. + else + { + err = StopAdvertising(); + SuccessOrExit(err); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err)); + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; + } +} + +struct BLEManagerImpl::ServiceData +{ + uint8_t uuid[2]; + ChipBLEDeviceIdentificationInfo deviceIdInfo; +} __attribute__((packed)); + +CHIP_ERROR BLEManagerImpl::StartAdvertising(void) +{ + int err = 0; + const char * deviceName = bt_get_name(); + const uint8_t advFlags = BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR; + const bool isAdvertisingRerun = mFlags.Has(Flags::kAdvertising); + + // At first run always select fast advertising, on the next attempt slow down interval. + const uint16_t intervalMin = mFlags.Has(Flags::kFastAdvertisingEnabled) ? CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MIN + : CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN; + const uint16_t intervalMax = mFlags.Has(Flags::kFastAdvertisingEnabled) ? CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX + : CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX; + + // bt_le_adv_param advParams = + // BT_LE_ADV_PARAM_INIT(BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_ONE_TIME, intervalMin, intervalMax, nullptr); + bt_le_adv_param advParams; + advParams.id = BT_ID_DEFAULT; + advParams.options = BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_ONE_TIME; + advParams.interval_min = intervalMin; + advParams.interval_max = intervalMax; + + // Define advertising data + ServiceData serviceData; + bt_data ad[] = { BT_DATA(BT_DATA_FLAGS, &advFlags, sizeof(advFlags)), + BT_DATA(BT_DATA_SVC_DATA16, &serviceData, sizeof(serviceData)), + BT_DATA(BT_DATA_NAME_COMPLETE, deviceName, static_cast(strlen(deviceName))) }; + + // Initialize service data + static_assert(sizeof(serviceData) == 10, "Size of BLE advertisement data changed! Was that intentional?"); + chip::Encoding::LittleEndian::Put16(serviceData.uuid, UUID16_CHIPoBLEService.val); + ReturnErrorOnFailure(ConfigurationMgr().GetBLEDeviceIdentificationInfo(serviceData.deviceIdInfo)); + + if (!isAdvertisingRerun) + { +#if CONFIG_BT_PRIVACY + static_assert((CHIP_DEVICE_CONFIG_BLE_ADVERTISING_TIMEOUT / 1000) <= CONFIG_BT_RPA_TIMEOUT, + "BLE advertising timeout is too long relative to RPA timeout"); + // Generate new private BLE address + bt_le_oob bleOobInfo; + err = bt_le_oob_get_local(advParams.id, &bleOobInfo); + VerifyOrReturnError(err == 0, MapErrorZephyr(err)); +#endif // CONFIG_BT_PRIVACY + } + + // Restart advertising + err = bt_le_adv_stop(); + VerifyOrReturnError(err == 0, MapErrorZephyr(err)); + + err = bt_le_adv_start(&advParams, ad, ARRAY_SIZE(ad), nullptr, 0u); + VerifyOrReturnError(err == 0, MapErrorZephyr(err)); + + // Transition to the Advertising state... + if (!mFlags.Has(Flags::kAdvertising)) + { + ChipLogProgress(DeviceLayer, "CHIPoBLE advertising started"); + + mFlags.Set(Flags::kAdvertising); + + // Post a CHIPoBLEAdvertisingChange(Started) event. + { + ChipDeviceEvent advChange; + advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; + advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Started; + PlatformMgr().PostEvent(&advChange); + } + + if (mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + // Start timer to change advertising interval. + DeviceLayer::SystemLayer().StartTimer( + System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME), + HandleBLEAdvertisementIntervalChange, this); + } + + // Start timer to disable CHIPoBLE advertisement after timeout expiration only if it isn't advertising rerun (in that case + // timer is already running). + if (!isAdvertisingRerun) + { + DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_TIMEOUT), + HandleBLEAdvertisementTimeout, this); + } + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::StopAdvertising(void) +{ + int err = bt_le_adv_stop(); + VerifyOrReturnError(err == 0, MapErrorZephyr(err)); + + // Transition to the not Advertising state... + if (mFlags.Has(Flags::kAdvertising)) + { + mFlags.Clear(Flags::kAdvertising); + mFlags.Set(Flags::kFastAdvertisingEnabled, true); + + ChipLogProgress(DeviceLayer, "CHIPoBLE advertising stopped"); + + // Post a CHIPoBLEAdvertisingChange(Stopped) event. + { + ChipDeviceEvent advChange; + advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; + advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped; + PlatformMgr().PostEvent(&advChange); + } + + // Cancel timer event disabling CHIPoBLE advertisement after timeout expiration + DeviceLayer::SystemLayer().CancelTimer(HandleBLEAdvertisementTimeout, this); + + // Cancel timer event changing CHIPoBLE advertisement interval + DeviceLayer::SystemLayer().CancelTimer(HandleBLEAdvertisementIntervalChange, this); + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrExit(val != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); + + if (val != mServiceMode) + { + mServiceMode = val; + PlatformMgr().ScheduleWork(DriveBLEState, 0); + } + +exit: + return err; +} + +CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); + + if (mFlags.Has(Flags::kAdvertisingEnabled) != val) + { + ChipLogDetail(DeviceLayer, "SetAdvertisingEnabled(%s)", val ? "true" : "false"); + + mFlags.Set(Flags::kAdvertisingEnabled, val); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + } + +exit: + return err; +} + +CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) +{ + switch (mode) + { + case BLEAdvertisingMode::kFastAdvertising: + mFlags.Set(Flags::kFastAdvertisingEnabled, true); + break; + case BLEAdvertisingMode::kSlowAdvertising: + mFlags.Set(Flags::kFastAdvertisingEnabled, false); + break; + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } + mFlags.Set(Flags::kAdvertisingRefreshNeeded); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::_GetDeviceName(char * buf, size_t bufSize) +{ + size_t len = bufSize - 1; + + strncpy(buf, bt_get_name(), len); + buf[len] = 0; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::_SetDeviceName(const char * deviceName) +{ + if (mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported) + { + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + } + + ChipLogDetail(DeviceLayer, "Device name set to: %s", deviceName); + return MapErrorZephyr(bt_set_name(deviceName)); +} + +CHIP_ERROR BLEManagerImpl::HandleGAPConnect(const ChipDeviceEvent * event) +{ + const BleConnEventType * connEvent = &event->Platform.BleConnEvent; + + if (connEvent->HciResult == BT_HCI_ERR_SUCCESS) + { + ChipLogProgress(DeviceLayer, "BLE connection established (ConnId: 0x%02" PRIx16 ")", bt_conn_index(connEvent->BtConn)); + mGAPConns++; + } + else + { + ChipLogProgress(DeviceLayer, "BLE connection failed (reason: 0x%02" PRIx16 ")", connEvent->HciResult); + } + + ChipLogProgress(DeviceLayer, "Current number of connections: %" PRIu16 "/%" PRIu16, NumConnections(), CONFIG_BT_MAX_CONN); + + mFlags.Set(Flags::kAdvertisingRefreshNeeded); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + + bt_conn_unref(connEvent->BtConn); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::HandleGAPDisconnect(const ChipDeviceEvent * event) +{ + const BleConnEventType * connEvent = &event->Platform.BleConnEvent; + + ChipLogProgress(DeviceLayer, "BLE GAP connection terminated (reason 0x%02" PRIx16 ")", connEvent->HciResult); + + mGAPConns--; + + // If notifications were enabled for this connection, record that they are now disabled and + // notify the BLE Layer of a disconnect. + if (UnsetSubscribed(connEvent->BtConn)) + { + CHIP_ERROR disconReason; + switch (connEvent->HciResult) + { + case BT_HCI_ERR_REMOTE_USER_TERM_CONN: + // Do not treat proper connection termination as an error and exit. + VerifyOrExit(!ConfigurationMgr().IsFullyProvisioned(), ); + disconReason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED; + break; + case BT_HCI_ERR_LOCALHOST_TERM_CONN: + disconReason = BLE_ERROR_APP_CLOSED_CONNECTION; + break; + default: + disconReason = BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT; + break; + } + HandleConnectionError(connEvent->BtConn, disconReason); + } + +exit: + // Unref bt_conn before scheduling DriveBLEState. + bt_conn_unref(connEvent->BtConn); + + ChipLogProgress(DeviceLayer, "Current number of connections: %" PRIu16 "/%" PRIu16, NumConnections(), CONFIG_BT_MAX_CONN); + + // Force a reconfiguration of advertising in case we switched to non-connectable mode when + // the BLE connection was established. + mFlags.Set(Flags::kAdvertisingRefreshNeeded); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::HandleTXCharCCCDWrite(const ChipDeviceEvent * event) +{ + const BleCCCWriteEventType * writeEvent = &event->Platform.BleCCCWriteEvent; + + ChipLogDetail(DeviceLayer, "ConnId: 0x%02" PRIx16 ", New CCCD value: 0x%04" PRIx16, bt_conn_index(writeEvent->BtConn), + writeEvent->Value); + + // If the client has requested to enable notifications and if it is not yet subscribed + if (writeEvent->Value != 0 && SetSubscribed(writeEvent->BtConn)) + { + // Alert the BLE layer that CHIPoBLE "subscribe" has been received and increment the bt_conn reference counter. + HandleSubscribeReceived(writeEvent->BtConn, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); + + ChipLogProgress(DeviceLayer, "CHIPoBLE connection established (ConnId: 0x%02" PRIx16 ", GATT MTU: %" PRIu16 ")", + bt_conn_index(writeEvent->BtConn), GetMTU(writeEvent->BtConn)); + + // Post a CHIPoBLEConnectionEstablished event to the DeviceLayer and the application. + { + ChipDeviceEvent conEstEvent; + conEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; + PlatformMgr().PostEvent(&conEstEvent); + } + } + else + { + if (UnsetSubscribed(writeEvent->BtConn)) + { + HandleUnsubscribeReceived(writeEvent->BtConn, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); + } + } + + bt_conn_unref(writeEvent->BtConn); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::HandleRXCharWrite(const ChipDeviceEvent * event) +{ + const BleRXWriteEventType * writeEvent = &event->Platform.BleRXWriteEvent; + + ChipLogDetail(DeviceLayer, "Write request received for CHIPoBLE RX (ConnId 0x%02" PRIx16 ")", + bt_conn_index(writeEvent->BtConn)); + + HandleWriteReceived(writeEvent->BtConn, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_RX, + PacketBufferHandle::Adopt(writeEvent->Data)); + bt_conn_unref(writeEvent->BtConn); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::HandleTXCharComplete(const ChipDeviceEvent * event) +{ + const BleTXCompleteEventType * completeEvent = &event->Platform.BleTXCompleteEvent; + + ChipLogDetail(DeviceLayer, "Notification for CHIPoBLE TX done (ConnId 0x%02" PRIx16 ")", bt_conn_index(completeEvent->BtConn)); + + // Signal the BLE Layer that the outstanding notification is complete. + HandleIndicationConfirmation(completeEvent->BtConn, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); + bt_conn_unref(completeEvent->BtConn); + + return CHIP_NO_ERROR; +} + +void BLEManagerImpl::HandleBLEAdvertisementTimeout(System::Layer * layer, void * param) +{ + BLEMgr().SetAdvertisingEnabled(false); + ChipLogProgress(DeviceLayer, "CHIPoBLE advertising disabled because of timeout expired"); +} + +void BLEManagerImpl::HandleBLEAdvertisementIntervalChange(System::Layer * layer, void * param) +{ + BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising); + ChipLogProgress(DeviceLayer, "CHIPoBLE advertising mode changed to slow"); +} + +void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + switch (event->Type) + { + case DeviceEventType::kPlatformZephyrBleConnected: + err = HandleGAPConnect(event); + break; + + case DeviceEventType::kPlatformZephyrBleDisconnected: + err = HandleGAPDisconnect(event); + break; + + case DeviceEventType::kPlatformZephyrBleCCCWrite: + err = HandleTXCharCCCDWrite(event); + break; + + case DeviceEventType::kPlatformZephyrBleRXWrite: + err = HandleRXCharWrite(event); + break; + + case DeviceEventType::kPlatformZephyrBleTXComplete: + err = HandleTXCharComplete(event); + break; + + case DeviceEventType::kFabricMembershipChange: + case DeviceEventType::kServiceProvisioningChange: + case DeviceEventType::kAccountPairingChange: + + // If CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED is enabled, and there is a change to the + // device's provisioning state, then automatically disable CHIPoBLE advertising if the device + // is now fully provisioned. +#if CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED + if (ConfigurationMgr().IsFullyProvisioned()) + { + mFlags.Clear(Flags::kAdvertisingEnabled); + ChipLogProgress(DeviceLayer, "CHIPoBLE advertising disabled because device is fully provisioned"); + } +#endif // CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED + + // Force the advertising state to be refreshed to reflect new provisioning state. + mFlags.Set(Flags::kAdvertisingRefreshNeeded); + + DriveBLEState(); + + break; + + default: + break; + } + + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err)); + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; + PlatformMgr().ScheduleWork(DriveBLEState, 0); + } +} + +uint16_t BLEManagerImpl::_NumConnections(void) +{ + return mGAPConns; +} + +bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId) +{ + ChipLogProgress(DeviceLayer, "Closing BLE GATT connection (ConnId %02" PRIx16 ")", bt_conn_index((bt_conn *) conId)); + return bt_conn_disconnect(conId, BT_HCI_ERR_REMOTE_USER_TERM_CONN) == 0; +} + +uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const +{ + return bt_gatt_get_mtu((bt_conn *) conId); +} + +bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogError(DeviceLayer, "%s: NOT IMPLEMENTED", __PRETTY_FUNCTION__); + return true; +} + +bool BLEManagerImpl::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogError(DeviceLayer, "%s: NOT IMPLEMENTED", __PRETTY_FUNCTION__); + return true; +} + +bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + log_info("\r\n"); + CHIP_ERROR err = CHIP_NO_ERROR; + int status = 0; + uint8_t index = bt_conn_index((bt_conn *) conId); + bt_gatt_notify_params * params = &mNotifyParams[index]; + + VerifyOrExit(IsSubscribed((bt_conn *) conId) == true, err = CHIP_ERROR_INVALID_ARGUMENT); + + ChipLogDetail(DeviceLayer, "Sending notification for CHIPoBLE TX (ConnId %02" PRIx16 ", len %u)", index, pBuf->DataLength()); + + params->uuid = nullptr; + params->attr = &_3_CHIPoBLE_Service.attrs[kCHIPoBLE_CCC_AttributeIndex]; + params->data = pBuf->Start(); + params->len = pBuf->DataLength(); + params->func = HandleTXCompleted; + params->user_data = nullptr; + + status = bt_gatt_notify_cb(conId, params); + VerifyOrExit(status == 0, err = MapErrorZephyr(status)); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Sending notification for CHIPoBLE TX failed: %s", ErrorStr(err)); + } + + return err == CHIP_NO_ERROR; +} + +bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + ChipLogError(DeviceLayer, "%s: NOT IMPLEMENTED", __PRETTY_FUNCTION__); + return true; +} + +bool BLEManagerImpl::SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + ChipLogError(DeviceLayer, "%s: NOT IMPLEMENTED", __PRETTY_FUNCTION__); + return true; +} + +bool BLEManagerImpl::SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, + const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogError(DeviceLayer, "%s: NOT IMPLEMENTED", __PRETTY_FUNCTION__); + return true; +} + +void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) +{ + // Intentionally empty. +} + +bool BLEManagerImpl::IsSubscribed(bt_conn * conn) +{ + return mSubscribedConns[bt_conn_index(conn)]; +} + +bool BLEManagerImpl::SetSubscribed(bt_conn * conn) +{ + uint8_t index = bt_conn_index(conn); + bool isSubscribed = mSubscribedConns[index]; + mSubscribedConns[index] = true; + + // If we were not subscribed previously, increment the reference counter of the connection. + if (!isSubscribed) + { + bt_conn_ref(conn); + } + + return !isSubscribed; +} + +bool BLEManagerImpl::UnsetSubscribed(bt_conn * conn) +{ + uint8_t index = bt_conn_index(conn); + bool isSubscribed = mSubscribedConns[index]; + mSubscribedConns[index] = false; + + // If we were subscribed previously, decrement the reference counter of the connection. + if (isSubscribed) + { + bt_conn_unref(conn); + } + + return isSubscribed; +} + +ssize_t BLEManagerImpl::HandleRXWrite(struct bt_conn * conId, const struct bt_gatt_attr * attr, const void * buf, uint16_t len, + uint16_t offset, uint8_t flags) +{ + ChipDeviceEvent event; + PacketBufferHandle packetBuf = PacketBufferHandle::NewWithData(buf, len); + + // Unfortunately the Zephyr logging macros end up assigning uint16_t + // variables to uint16_t:10 fields, which triggers integer conversion + // warnings. And treating the Zephyr headers as system headers does not + // help, apparently. Just turn off that warning around this log call. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" + // LOG_HEXDUMP_DBG(buf, len, "Rx char write"); + blog_debug_hexdump("Rx char write", buf, len); +#pragma GCC diagnostic pop + + // If successful... + if (!packetBuf.IsNull()) + { + // Arrange to post a CHIPoBLERXWriteEvent event to the CHIP queue. + event.Type = DeviceEventType::kPlatformZephyrBleRXWrite; + event.Platform.BleRXWriteEvent.BtConn = bt_conn_ref(conId); + event.Platform.BleRXWriteEvent.Data = std::move(packetBuf).UnsafeRelease(); + } + + // If we failed to allocate a buffer, post a kPlatformZephyrBleOutOfBuffersEvent event. + else + { + event.Type = DeviceEventType::kPlatformZephyrBleOutOfBuffersEvent; + } + + PlatformMgr().PostEvent(&event); + + return len; +} + +bool BLEManagerImpl::HandleTXCCCWrite(struct bt_conn * conId, const struct bt_gatt_attr * attr, uint16_t value) +{ + ChipDeviceEvent event; + + if (value != BT_GATT_CCC_NOTIFY && value != 0) + { + // return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED); + return false; + } + + event.Type = DeviceEventType::kPlatformZephyrBleCCCWrite; + event.Platform.BleCCCWriteEvent.BtConn = bt_conn_ref(conId); + event.Platform.BleCCCWriteEvent.Value = value; + + PlatformMgr().PostEvent(&event); + + return true; +} + +void BLEManagerImpl::HandleTXCompleted(struct bt_conn * conId, void * /* param */) +{ + ChipDeviceEvent event; + + event.Type = DeviceEventType::kPlatformZephyrBleTXComplete; + event.Platform.BleTXCompleteEvent.BtConn = bt_conn_ref(conId); + + PlatformMgr().PostEvent(&event); +} + +void BLEManagerImpl::HandleConnect(struct bt_conn * conId, uint8_t err) +{ + ChipDeviceEvent event; + + event.Type = DeviceEventType::kPlatformZephyrBleConnected; + event.Platform.BleConnEvent.BtConn = bt_conn_ref(conId); + event.Platform.BleConnEvent.HciResult = err; + + PlatformMgr().PostEvent(&event); +} + +void BLEManagerImpl::HandleDisconnect(struct bt_conn * conId, uint8_t reason) +{ + ChipDeviceEvent event; + + event.Type = DeviceEventType::kPlatformZephyrBleDisconnected; + event.Platform.BleConnEvent.BtConn = bt_conn_ref(conId); + event.Platform.BleConnEvent.HciResult = reason; + + PlatformMgr().PostEvent(&event); +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/src/platform/bouffalolab/BL602/BLEManagerImpl.h b/src/platform/bouffalolab/BL602/BLEManagerImpl.h new file mode 100644 index 00000000000000..44d65d503a78b4 --- /dev/null +++ b/src/platform/bouffalolab/BL602/BLEManagerImpl.h @@ -0,0 +1,189 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the BLEManager singleton object + * for the BL602 platform. + */ + +#pragma once + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +#include +#include +#include + +#include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +using namespace chip::Ble; + +/** + * Concrete implementation of the BLEManager singleton object for the BL602 platform. + */ +class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePlatformDelegate, private BleApplicationDelegate +{ + // Allow the BLEManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend BLEManager; + +private: + // ===== Members that implement the BLEManager internal interface. + + CHIP_ERROR _Init(void); + CHIP_ERROR _Shutdown() { return CHIP_NO_ERROR; } + CHIPoBLEServiceMode _GetCHIPoBLEServiceMode(void); + CHIP_ERROR _SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val); + bool _IsAdvertisingEnabled(void); + CHIP_ERROR _SetAdvertisingEnabled(bool val); + bool _IsAdvertising(void); + CHIP_ERROR _SetAdvertisingMode(BLEAdvertisingMode mode); + CHIP_ERROR _GetDeviceName(char * buf, size_t bufSize); + CHIP_ERROR _SetDeviceName(const char * deviceName); + uint16_t _NumConnections(void); + void _OnPlatformEvent(const ChipDeviceEvent * event); + BleLayer * _GetBleLayer(void); + + // ===== Members that implement virtual methods on BlePlatformDelegate. + + bool SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId); + bool UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId); + bool CloseConnection(BLE_CONNECTION_OBJECT conId); + uint16_t GetMTU(BLE_CONNECTION_OBJECT conId) const; + bool SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf); + bool SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf); + bool SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf); + bool SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, const ChipBleUUID * svcId, + const ChipBleUUID * charId); + + // ===== Members that implement virtual methods on BleApplicationDelegate. + + void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId); + + // ===== Private members reserved for use by this class only. + + enum class Flags : uint8_t + { + kAsyncInitCompleted = 0x0001, /**< One-time asynchronous initialization actions have been performed. */ + kAdvertisingEnabled = 0x0002, /**< The application has enabled CHIPoBLE advertising. */ + kFastAdvertisingEnabled = 0x0004, /**< The application has enabled fast advertising. */ + kAdvertising = 0x0008, /**< The system is currently CHIPoBLE advertising. */ + kAdvertisingRefreshNeeded = + 0x0010, /**< The advertising state/configuration has changed, but the SoftDevice has yet to be updated. */ + }; + + struct ServiceData; + + BitFlags mFlags; + uint16_t mGAPConns; + CHIPoBLEServiceMode mServiceMode; + bool mSubscribedConns[CONFIG_BT_MAX_CONN]; + bt_gatt_notify_params mNotifyParams[CONFIG_BT_MAX_CONN]; + bt_conn_cb mConnCallbacks; + + void DriveBLEState(void); + CHIP_ERROR ConfigureAdvertising(void); + CHIP_ERROR StartAdvertising(void); + CHIP_ERROR StopAdvertising(void); + CHIP_ERROR HandleGAPConnect(const ChipDeviceEvent * event); + CHIP_ERROR HandleGAPDisconnect(const ChipDeviceEvent * event); + CHIP_ERROR HandleRXCharWrite(const ChipDeviceEvent * event); + CHIP_ERROR HandleTXCharCCCDWrite(const ChipDeviceEvent * event); + CHIP_ERROR HandleTXCharComplete(const ChipDeviceEvent * event); + bool IsSubscribed(bt_conn * conn); + bool SetSubscribed(bt_conn * conn); + bool UnsetSubscribed(bt_conn * conn); + uint32_t GetAdvertisingInterval(); + + static void DriveBLEState(intptr_t arg); + + // Below callbacks run from the system workqueue context and have a limited stack capacity. + static void HandleTXCompleted(bt_conn * conn, void * param); + static void HandleConnect(bt_conn * conn, uint8_t err); + static void HandleDisconnect(bt_conn * conn, uint8_t reason); + static void HandleBLEAdvertisementTimeout(System::Layer * layer, void * param); + static void HandleBLEAdvertisementIntervalChange(System::Layer * layer, void * param); + + // ===== Members for internal use by the following friends. + + friend BLEManager & BLEMgr(void); + friend BLEManagerImpl & BLEMgrImpl(void); + + static BLEManagerImpl sInstance; + +public: + // Below callbacks are public in order to be visible from the global scope. + static ssize_t HandleRXWrite(bt_conn * conn, const bt_gatt_attr * attr, const void * buf, uint16_t len, uint16_t offset, + uint8_t flags); + static bool HandleTXCCCWrite(bt_conn * conn, const bt_gatt_attr * attr, uint16_t value); +}; + +/** + * Returns a reference to the public interface of the BLEManager singleton object. + * + * Internal components should use this to access features of the BLEManager object + * that are common to all platforms. + */ +inline BLEManager & BLEMgr(void) +{ + return BLEManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the BLEManager singleton object. + * + * Internal components can use this to gain access to features of the BLEManager + * that are specific to the BL602 platform. + */ +inline BLEManagerImpl & BLEMgrImpl(void) +{ + return BLEManagerImpl::sInstance; +} + +inline BleLayer * BLEManagerImpl::_GetBleLayer() +{ + return this; +} + +inline BLEManager::CHIPoBLEServiceMode BLEManagerImpl::_GetCHIPoBLEServiceMode(void) +{ + return mServiceMode; +} + +inline bool BLEManagerImpl::_IsAdvertisingEnabled(void) +{ + return mFlags.Has(Flags::kAdvertisingEnabled); +} + +inline bool BLEManagerImpl::_IsAdvertising(void) +{ + return mFlags.Has(Flags::kAdvertising); +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/src/platform/bouffalolab/BL602/BUILD.gn b/src/platform/bouffalolab/BL602/BUILD.gn new file mode 100644 index 00000000000000..8d7114a0c60975 --- /dev/null +++ b/src/platform/bouffalolab/BL602/BUILD.gn @@ -0,0 +1,74 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") + +import("${chip_root}/src/platform/device.gni") + +assert(chip_device_platform == "bl602") + +static_library("BL602") { + sources = [ + "../../FreeRTOS/SystemTimeSupport.cpp", + "../../SingletonConfigurationManager.cpp", + "BL602Config.cpp", + "BL602Config.h", + "BLEManagerImpl.cpp", + "BLEManagerImpl.h", + "BlePlatformConfig.h", + "CHIPDevicePlatformConfig.h", + "CHIPDevicePlatformEvent.h", + "CHIPMem-Platform.cpp", + "CHIPPlatformConfig.h", + "ConfigurationManagerImpl.cpp", + "ConfigurationManagerImpl.h", + "ConnectivityManagerImpl.cpp", + "ConnectivityManagerImpl.h", + "DeviceNetworkProvisioningDelegateImpl.cpp", + "DeviceNetworkProvisioningDelegateImpl.h", + "DiagnosticDataProviderImpl.cpp", + "DiagnosticDataProviderImpl.h", + "DnssdImpl.cpp", + "InetPlatformConfig.h", + "Logging.cpp", + "NetworkCommissioningDriver.cpp", + "PlatformManagerImpl.cpp", + "PlatformManagerImpl.h", + "SystemPlatformConfig.h", + ] + + deps = [ "${chip_root}/src/lib/dnssd:platform_header" ] + + public_deps = [ "${chip_root}/src/platform:platform_base" ] + + # defines = [ + # "CHIP_KVS_SECTOR_COUNT=1", + # "CHIP_KVS_BASE_SECTOR_INDEX=0" + # ] + + # Add pigweed KVS + deps += [ + "$dir_pw_kvs:crc16", + "$dir_pw_log", + ] + public_deps += [ + "$dir_pw_checksum", + "$dir_pw_kvs", + ] + sources += [ + "KeyValueStoreManagerImpl.cpp", + "KeyValueStoreManagerImpl.h", + ] +} diff --git a/src/platform/bouffalolab/BL602/BlePlatformConfig.h b/src/platform/bouffalolab/BL602/BlePlatformConfig.h new file mode 100644 index 00000000000000..f445cabca58a59 --- /dev/null +++ b/src/platform/bouffalolab/BL602/BlePlatformConfig.h @@ -0,0 +1,36 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the CHIP BLE + * Layer on the BL602 platform. + * + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +struct bt_conn; +#define BLE_CONNECTION_OBJECT bt_conn * +#define BLE_CONNECTION_UNINITIALIZED nullptr +#define BLE_MAX_RECEIVE_WINDOW_SIZE 5 + +// ========== Platform-specific Configuration Overrides ========= + +/* none so far */ diff --git a/src/platform/bouffalolab/BL602/CHIPDevicePlatformConfig.h b/src/platform/bouffalolab/BL602/CHIPDevicePlatformConfig.h new file mode 100644 index 00000000000000..878ef7f8f3be84 --- /dev/null +++ b/src/platform/bouffalolab/BL602/CHIPDevicePlatformConfig.h @@ -0,0 +1,133 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the Chip Device Layer + * on BL602 platforms using the BouffaloLab SDK. + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +#define CHIP_DEVICE_CONFIG_BL602_EASYFLASH_ERROR_MIN 22000000 +#define CHIP_DEVICE_CONFIG_BL602_BLE_ERROR_MIN 23000000 + +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION 0 +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP 0 + +#if CHIP_ENABLE_OPENTHREAD +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD 1 +#define CHIP_DEVICE_CONFIG_ENABLE_MDNS 1 +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT 1 +#endif + +//#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 + +#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0 + +#define CHIP_DEVICE_CONFIG_PERSISTED_STORAGE_CRIT_EIDC_KEY 2 +#define CHIP_DEVICE_CONFIG_PERSISTED_STORAGE_PROD_EIDC_KEY 3 +#define CHIP_DEVICE_CONFIG_PERSISTED_STORAGE_INFO_EIDC_KEY 4 +#define CHIP_DEVICE_CONFIG_PERSISTED_STORAGE_DEBUG_EIDC_KEY 5 + +// ========== Platform-specific Configuration ========= + +// These are configuration options that are unique to the BL602 platform. +// These can be overridden by the application as needed. + +// -------------- BL602 EasyFlash Storage Configuration ------------- + +/** + * @def CHIP_DEVICE_CONFIG_EASYFLASH_MAX_NUM_OBJECTS + * + * @brief + * Configures the size of the easyflash cache and should be set >= the + * maximum number of Chip Config objects, e.g... + * Factory configs[5], System configs[23], Counter configs[32] + margin[4] = 64. + * + */ +#ifndef CHIP_DEVICE_CONFIG_EASYFLASH_MAX_NUM_OBJECTS +#define CHIP_DEVICE_CONFIG_EASYFLASH_MAX_NUM_OBJECTS 64 +#endif // CHIP_DEVICE_CONFIG_EASYFLASH_MAX_NUM_OBJECTS + +/** + * @def CHIP_DEVICE_CONFIG_EASYFLASH_MAX_OBJECT_SIZE + * + * @brief + * This determines the max size for any Chip easyflash object + * (e.g. for Config 'string' or 'binary' types). + */ +#ifndef CHIP_DEVICE_CONFIG_EASYFLASH_MAX_OBJECT_SIZE +#define CHIP_DEVICE_CONFIG_EASYFLASH_MAX_OBJECT_SIZE 1000 +#endif // CHIP_DEVICE_CONFIG_EASYFLASH_MAX_OBJECT_SIZE + +/** + * @def CHIP_DEVICE_CONFIG_EASYFLASH_NUM_FLASH_PAGES_FOR_STORAGE + * + * @brief + * This determines the Flash size used for easyflash data storage:- + * (assuming 2k Flash page size) => Total Flash size for easyflash: 8 * 2k = 16k + * The total size should allow sufficient margin for wear-levelling and + * repacking. + */ +#ifndef CHIP_DEVICE_CONFIG_EASYFLASH_NUM_FLASH_PAGES_FOR_STORAGE +#define CHIP_DEVICE_CONFIG_EASYFLASH_NUM_FLASH_PAGES_FOR_STORAGE 8 +#endif // CHIP_DEVICE_CONFIG_EASYFLASH_NUM_FLASH_PAGES_FOR_STORAGE + +// ========== Platform-specific Configuration Overrides ========= + +#ifndef CHIP_DEVICE_CONFIG_BLE_LL_TASK_PRIORITY +#define CHIP_DEVICE_CONFIG_BLE_LL_TASK_PRIORITY (configTIMER_TASK_PRIORITY - 1) +#endif // CHIP_DEVICE_CONFIG_BLE_LL_TASK_PRIORITY + +#ifndef CHIP_DEVICE_CONFIG_BLE_STACK_TASK_PRIORITY +#define CHIP_DEVICE_CONFIG_BLE_STACK_TASK_PRIORITY (CHIP_DEVICE_CONFIG_BLE_LL_TASK_PRIORITY - 1) +#endif // CHIP_DEVICE_CONFIG_BLE_STACK_TASK_PRIORITY + +#ifndef CHIP_DEVICE_CONFIG_BLE_APP_TASK_PRIORITY +#define CHIP_DEVICE_CONFIG_BLE_APP_TASK_PRIORITY (CHIP_DEVICE_CONFIG_BLE_STACK_TASK_PRIORITY - 1) +#endif // CHIP_DEVICE_CONFIG_BLE_STACK_TASK_PRIORITY + +#ifndef CHIP_DEVICE_CONFIG_BLE_APP_TASK_STACK_SIZE +#define CHIP_DEVICE_CONFIG_BLE_APP_TASK_STACK_SIZE 1536 +#endif // CHIP_DEVICE_CONFIG_BLE_APP_TASK_STACK_SIZE + +#ifndef CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE +#define CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE (6 * 1024) +#endif // CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE + +#ifndef CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE +#if defined(BL602MG21) +#define CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE (2 * 1024) +#else +#define CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE (3 * 1024) +#endif +#endif // CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE + +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_TELEMETRY 0 +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_TELEMETRY 0 +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_TELEMETRY_FULL 0 + +#ifndef CHIP_DEVICE_CONFIG_BLE_APP_TASK_NAME +#define CHIP_DEVICE_CONFIG_BLE_APP_TASK_NAME "BLE_EVENT" +#endif // CHIP_DEVICE_CONFIG_BLE_APP_TASK_NAME +#define CHIP_DEVICE_CONFIG_LOG_PROVISIONING_HASH 0 + +#define CHIP_DEVICE_CONFIG_MAX_EVENT_QUEUE_SIZE 25 diff --git a/src/platform/bouffalolab/BL602/CHIPDevicePlatformEvent.h b/src/platform/bouffalolab/BL602/CHIPDevicePlatformEvent.h new file mode 100644 index 00000000000000..76bd2bcdc0476c --- /dev/null +++ b/src/platform/bouffalolab/BL602/CHIPDevicePlatformEvent.h @@ -0,0 +1,98 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Defines platform-specific event types and data for the chip + * Device Layer on the BL602 platform. + */ + +#pragma once + +#include + +#include +#include + +namespace chip { +namespace DeviceLayer { + +namespace DeviceEventType { + +/** + * Enumerates BL602 platform-specific event types that are visible to the application. + */ +enum PublicPlatformSpecificEventTypes +{ + /* None currently defined */ +}; + +/** + * Enumerates BL602 platform-specific event types that are internal to the chip Device Layer. + */ +enum InternalPlatformSpecificEventTypes +{ + kPlatformZephyrEvent = kRange_InternalPlatformSpecific, + kPlatformZephyrBleConnected, + kPlatformZephyrBleDisconnected, + kPlatformZephyrBleCCCWrite, + kPlatformZephyrBleRXWrite, + kPlatformZephyrBleTXComplete, + kPlatformZephyrBleOutOfBuffersEvent, +}; + +} // namespace DeviceEventType + +struct BleConnEventType +{ + bt_conn * BtConn; + uint8_t HciResult; +}; + +struct BleCCCWriteEventType +{ + bt_conn * BtConn; + uint16_t Value; +}; + +struct BleRXWriteEventType +{ + bt_conn * BtConn; + ::chip::System::PacketBuffer * Data; +}; + +struct BleTXCompleteEventType +{ + bt_conn * BtConn; +}; + +/** + * Represents platform-specific event information for the BL602 platform. + */ +struct ChipDevicePlatformEvent final +{ + union + { + BleConnEventType BleConnEvent; + BleCCCWriteEventType BleCCCWriteEvent; + BleRXWriteEventType BleRXWriteEvent; + BleTXCompleteEventType BleTXCompleteEvent; + }; +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/CHIPMem-Platform.cpp b/src/platform/bouffalolab/BL602/CHIPMem-Platform.cpp new file mode 100644 index 00000000000000..5f1f07f97a6a77 --- /dev/null +++ b/src/platform/bouffalolab/BL602/CHIPMem-Platform.cpp @@ -0,0 +1,164 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file implements heap memory allocation APIs for CHIP. These functions are platform + * specific and might be C Standard Library heap functions re-direction in most of cases. + * + */ + +//#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +extern "C" { +#include +#include +}; + +#if CHIP_CONFIG_MEMORY_MGMT_PLATFORM + +extern "C" void memMonitoringTrackAlloc(void * ptr, size_t size); +extern "C" void memMonitoringTrackFree(void * ptr, size_t size); + +#ifndef trackAlloc +#define trackAlloc(pvAddress, uiSize) memMonitoringTrackAlloc(pvAddress, uiSize) +#endif +#ifndef trackFree +#define trackFree(pvAddress, uiSize) memMonitoringTrackFree(pvAddress, uiSize) +#endif + +namespace chip { +namespace Platform { + +#define VERIFY_INITIALIZED() VerifyInitialized(__func__) + +static std::atomic_int memoryInitialized{ 0 }; + +static void VerifyInitialized(const char * func) +{ + if (!memoryInitialized) + { + log_error("ABORT: chip::Platform::%s() called before chip::Platform::MemoryInit()\r\n", func); + abort(); + } +} + +CHIP_ERROR MemoryAllocatorInit(void * buf, size_t bufSize) +{ +#ifndef NDEBUG + if (memoryInitialized++ > 0) + { + log_error("ABORT: chip::Platform::MemoryInit() called twice.\r\n"); + abort(); + } +#endif + return CHIP_NO_ERROR; +} + +void MemoryAllocatorShutdown() +{ +#ifndef NDEBUG + if (--memoryInitialized < 0) + { + log_error("ABORT: chip::Platform::MemoryShutdown() called twice.\r\n"); + abort(); + } +#endif +} + +void * MemoryAlloc(size_t size) +{ + void * ptr; + VERIFY_INITIALIZED(); + ptr = pvPortMalloc(size); + trackAlloc(ptr, size); + return ptr; +} + +void * MemoryAlloc(size_t size, bool isLongTermAlloc) +{ + void * ptr; + VERIFY_INITIALIZED(); + ptr = pvPortMalloc(size); + trackAlloc(ptr, size); + return ptr; +} + +void * MemoryCalloc(size_t num, size_t size) +{ + void * ptr; + VERIFY_INITIALIZED(); + ptr = pvPortCalloc(num, size); + trackAlloc(ptr, size * num); + return ptr; +} + +void * MemoryRealloc(void * p, size_t size) +{ + VERIFY_INITIALIZED(); + return pvPortRealloc(p, size); +} + +void MemoryFree(void * p) +{ + VERIFY_INITIALIZED(); + trackFree(p, 0); + vPortFree(p); +} + +bool MemoryInternalCheckPointer(const void * p, size_t min_size) +{ + return (p != nullptr); +} + +} // namespace Platform +} // namespace chip + +extern "C" void memMonitoringTrackAlloc(void * ptr, size_t size) {} + +extern "C" void memMonitoringTrackFree(void * ptr, size_t size) {} + +#endif // CHIP_CONFIG_MEMORY_MGMT_PLATFORM diff --git a/src/platform/bouffalolab/BL602/CHIPPlatformConfig.h b/src/platform/bouffalolab/BL602/CHIPPlatformConfig.h new file mode 100644 index 00000000000000..7e427d48ad3cfa --- /dev/null +++ b/src/platform/bouffalolab/BL602/CHIPPlatformConfig.h @@ -0,0 +1,149 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for CHIP on + * Bouffalolab BL602 platforms. + */ + +#pragma once + +#include + +// ==================== General Platform Adaptations ==================== + +#define CHIP_CONFIG_ERROR_TYPE int32_t +#define CHIP_CONFIG_NO_ERROR 0 +#define CHIP_CONFIG_ERROR_MIN 4000000 +#define CHIP_CONFIG_ERROR_MAX 4000999 + +#define ASN1_CONFIG_ERROR_TYPE int32_t +#define ASN1_CONFIG_NO_ERROR 0 +#define ASN1_CONFIG_ERROR_MIN 5000000 +#define ASN1_CONFIG_ERROR_MAX 5000999 + +#define ChipDie() abort() + +#define CHIP_CONFIG_PERSISTED_STORAGE_KEY_TYPE const char * +#define CHIP_CONFIG_PERSISTED_STORAGE_ENC_MSG_CNTR_ID 1 +#define CHIP_CONFIG_PERSISTED_STORAGE_MAX_KEY_LENGTH 2 + +#define CHIP_CONFIG_LIFETIIME_PERSISTED_COUNTER_KEY 0x01 +//#define CHIP_CONFIG_PERSISTED_STORAGE_KEY_GLOBAL_MESSAGE_COUNTER 0x2 + +#define CHIP_CONFIG_TIME_ENABLE_CLIENT 1 +#define CHIP_CONFIG_TIME_ENABLE_SERVER 0 + +// ==================== Security Adaptations ==================== + +#define CHIP_CONFIG_USE_OPENSSL_ECC 0 +#define CHIP_CONFIG_USE_MICRO_ECC 0 + +#define CHIP_CONFIG_HASH_IMPLEMENTATION_OPENSSL 0 +#define CHIP_CONFIG_HASH_IMPLEMENTATION_MINCRYPT 1 +#define CHIP_CONFIG_HASH_IMPLEMENTATION_MBEDTLS 0 +#define CHIP_CONFIG_HASH_IMPLEMENTATION_PLATFORM 0 + +// FIXME: BL602 set to MBED-TLS (But this is third-party repo in CHIP, not SDK) + +#define CHIP_CONFIG_AES_IMPLEMENTATION_OPENSSL 0 +#define CHIP_CONFIG_AES_IMPLEMENTATION_AESNI 0 +#define CHIP_CONFIG_AES_IMPLEMENTATION_MBEDTLS 1 +#define CHIP_CONFIG_AES_IMPLEMENTATION_PLATFORM 0 + +// FIXME: BL602 currently set to CHIP (Does this use Entropy.cpp ?) + +#define CHIP_CONFIG_RNG_IMPLEMENTATION_OPENSSL 0 +#define CHIP_CONFIG_RNG_IMPLEMENTATION_CHIPDRBG 1 +#define CHIP_CONFIG_RNG_IMPLEMENTATION_PLATFORM 0 + +#define CHIP_CONFIG_ENABLE_PASE_INITIATOR 0 +#define CHIP_CONFIG_ENABLE_PASE_RESPONDER 1 +#define CHIP_CONFIG_ENABLE_CASE_INITIATOR 1 + +#define CHIP_CONFIG_SUPPORT_PASE_CONFIG0 0 +#define CHIP_CONFIG_SUPPORT_PASE_CONFIG1 0 +#define CHIP_CONFIG_SUPPORT_PASE_CONFIG2 0 +#define CHIP_CONFIG_SUPPORT_PASE_CONFIG3 0 +#define CHIP_CONFIG_SUPPORT_PASE_CONFIG4 1 + +#define CHIP_CONFIG_ENABLE_KEY_EXPORT_INITIATOR 0 + +#define CHIP_CONFIG_ENABLE_PROVISIONING_BUNDLE_SUPPORT 0 + +// ==================== General Configuration Overrides ==================== + +#ifndef CHIP_CONFIG_MAX_PEER_NODES +#define CHIP_CONFIG_MAX_PEER_NODES 16 +#endif // CHIP_CONFIG_MAX_PEER_NODES + +#ifndef CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS +#define CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS 8 +#endif // CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS + +#ifndef CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS +#define CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS 8 +#endif // CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS + +#ifndef CHIP_CONFIG_MAX_ACTIVE_CHANNELS +#define CHIP_CONFIG_MAX_ACTIVE_CHANNELS 8 +#endif // CHIP_CONFIG_MAX_ACTIVE_CHANNELS + +#ifndef CHIP_CONFIG_MAX_CHANNEL_HANDLES +#define CHIP_CONFIG_MAX_CHANNEL_HANDLES 16 +#endif // CHIP_CONFIG_MAX_CHANNEL_HANDLES + +#ifndef CHIP_CONFIG_RMP_TIMER_DEFAULT_PERIOD_SHIFT +#define CHIP_CONFIG_RMP_TIMER_DEFAULT_PERIOD_SHIFT 6 +#endif // CHIP_CONFIG_RMP_TIMER_DEFAULT_PERIOD_SHIFT + +#ifndef CHIP_LOG_FILTERING +#define CHIP_LOG_FILTERING 0 +#endif // CHIP_LOG_FILTERING + +#ifndef CHIP_CONFIG_MAX_INTERFACES +#define CHIP_CONFIG_MAX_INTERFACES 4 +#endif // CHIP_CONFIG_MAX_INTERFACES + +#ifndef CHIP_CONFIG_MAX_LOCAL_ADDR_UDP_ENDPOINTS +#define CHIP_CONFIG_MAX_LOCAL_ADDR_UDP_ENDPOINTS 4 +#endif // CHIP_CONFIG_MAX_LOCAL_ADDR_UDP_ENDPOINTS + +// ==================== Security Configuration Overrides ==================== + +#ifndef CHIP_CONFIG_MAX_APPLICATION_GROUPS +#define CHIP_CONFIG_MAX_APPLICATION_GROUPS 4 +#endif // CHIP_CONFIG_MAX_APPLICATION_GROUPS + +#ifndef CHIP_CONFIG_DEBUG_CERT_VALIDATION +#define CHIP_CONFIG_DEBUG_CERT_VALIDATION 0 +#endif // CHIP_CONFIG_DEBUG_CERT_VALIDATION + +#ifndef CHIP_CONFIG_ENABLE_CASE_RESPONDER +#define CHIP_CONFIG_ENABLE_CASE_RESPONDER 1 +#endif // CHIP_CONFIG_ENABLE_CASE_RESPONDER + +// ==================== FreeRTOS Configuration Overrides ==================== +#ifndef CHIP_CONFIG_FREERTOS_USE_STATIC_TASK +#define CHIP_CONFIG_FREERTOS_USE_STATIC_TASK 1 +#endif + +#ifndef CHIP_CONFIG_FREERTOS_USE_STATIC_QUEUE +#define CHIP_CONFIG_FREERTOS_USE_STATIC_QUEUE 1 +#endif diff --git a/src/platform/bouffalolab/BL602/ConfigurationManagerImpl.cpp b/src/platform/bouffalolab/BL602/ConfigurationManagerImpl.cpp new file mode 100644 index 00000000000000..a9149928901d4b --- /dev/null +++ b/src/platform/bouffalolab/BL602/ConfigurationManagerImpl.cpp @@ -0,0 +1,218 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides the implementation of the Device Layer ConfigurationManager object + * for the BL602 platform. + */ +/* this file behaves like a config.h, comes first */ +#include + +#include +#include +#include +#include +#include + +//#include "esp_wifi.h" +//#include "nvs.h" +//#include "nvs_flash.h" +extern "C" { +#include +} + +namespace chip { +namespace DeviceLayer { + +using namespace ::chip::DeviceLayer::Internal; + +namespace { + +enum +{ + kChipProduct_Connect = 0x0016 +}; + +} // unnamed namespace + +/** Singleton instance of the ConfigurationManager implementation object for the BL602 platform. + */ +ConfigurationManagerImpl ConfigurationManagerImpl::sInstance; + +ConfigurationManagerImpl & ConfigurationManagerImpl::GetDefaultInstance() +{ + static ConfigurationManagerImpl sInstance; + return sInstance; +} + +CHIP_ERROR ConfigurationManagerImpl::Init() +{ + CHIP_ERROR err; + bool failSafeArmed; + + // Initialize the generic implementation base class. + err = Internal::GenericConfigurationManagerImpl::Init(); + SuccessOrExit(err); + +#if CHIP_DEVICE_CONFIG_ENABLE_FACTORY_PROVISIONING + + { + FactoryProvisioning factoryProv; + uint8_t * const kInternalSRAM12Start = (uint8_t *) 0x3FFAE000; + uint8_t * const kInternalSRAM12End = kInternalSRAM12Start + (328 * 1024) - 1; + + // Scan ESP32 Internal SRAM regions 1 and 2 for injected provisioning data and save + // to persistent storage if found. + err = factoryProv.ProvisionDeviceFromRAM(kInternalSRAM12Start, kInternalSRAM12End); + SuccessOrExit(err); + } + +#endif // CHIP_DEVICE_CONFIG_ENABLE_FACTORY_PROVISIONING + + // If the fail-safe was armed when the device last shutdown, initiate a factory reset. + if (GetFailSafeArmed(failSafeArmed) == CHIP_NO_ERROR && failSafeArmed) + { + ChipLogProgress(DeviceLayer, "Detected fail-safe armed on reboot; initiating factory reset"); + InitiateFactoryReset(); + } + err = CHIP_NO_ERROR; + +exit: + return err; +} + +bool ConfigurationManagerImpl::CanFactoryReset() +{ + // TODO: query the application to determine if factory reset is allowed. + return true; +} + +void ConfigurationManagerImpl::InitiateFactoryReset() +{ + PlatformMgr().ScheduleWork(DoFactoryReset); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value) +{ + BL602Config::Key configKey{ key }; + + CHIP_ERROR err = ReadConfigValue(configKey, value); + if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) + { + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + return err; +} + +CHIP_ERROR ConfigurationManagerImpl::WritePersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t value) +{ + BL602Config::Key configKey{ key }; + return WriteConfigValue(configKey, value); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, bool & val) +{ + return BL602Config::ReadConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, uint32_t & val) +{ + return BL602Config::ReadConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, uint64_t & val) +{ + return BL602Config::ReadConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +{ + return BL602Config::ReadConfigValueStr(key, buf, bufSize, outLen); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) +{ + return BL602Config::ReadConfigValueBin(key, buf, bufSize, outLen); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, bool val) +{ + return BL602Config::WriteConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, uint32_t val) +{ + return BL602Config::WriteConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, uint64_t val) +{ + return BL602Config::WriteConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueStr(Key key, const char * str) +{ + return BL602Config::WriteConfigValueStr(key, str); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueStr(Key key, const char * str, size_t strLen) +{ + return BL602Config::WriteConfigValueStr(key, str, strLen); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) +{ + return BL602Config::WriteConfigValueBin(key, data, dataLen); +} + +void ConfigurationManagerImpl::RunConfigUnitTest(void) +{ + BL602Config::RunConfigUnitTest(); +} + +void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) +{ + CHIP_ERROR err; + + ChipLogProgress(DeviceLayer, "Performing factory reset"); + + // 3R: TODO + + // // Erase all values in the chip-config NVS namespace. + // err = ClearNamespace(kConfigNamespace_ChipConfig); + // if (err != CHIP_NO_ERROR) + // { + // ChipLogError(DeviceLayer, "ClearNamespace(ChipConfig) failed: %s", chip::ErrorStr(err)); + // } + + // // Restore WiFi persistent settings to default values. + // err = esp_wifi_restore(); + // if (err != ESP_OK) + // { + // ChipLogError(DeviceLayer, "esp_wifi_restore() failed: %s", chip::ErrorStr(err)); + // } + + // Restart the system. + ChipLogProgress(DeviceLayer, "System restarting"); + hal_reboot(); +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/ConfigurationManagerImpl.h b/src/platform/bouffalolab/BL602/ConfigurationManagerImpl.h new file mode 100644 index 00000000000000..0239f9a8dee22e --- /dev/null +++ b/src/platform/bouffalolab/BL602/ConfigurationManagerImpl.h @@ -0,0 +1,133 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the ConfigurationManager object + * for the BL602 platform. + */ + +#pragma once + +#include +#include +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#include +#else +#include +#endif + +#include +#include + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the ConfigurationManager singleton object for the BL602 platform. + */ +class ConfigurationManagerImpl final : public Internal::GenericConfigurationManagerImpl, +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + public Internal::GenericConnectivityManagerImpl_BLE +#else + public Internal::GenericConnectivityManagerImpl_NoBLE +#endif +{ +public: + static ConfigurationManagerImpl & GetDefaultInstance(); + // Allow the ConfigurationManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend class ConfigurationManager; + +private: + // ===== Members that implement the ConfigurationManager public interface. + + CHIP_ERROR Init(void) override; + CHIP_ERROR GetPrimaryWiFiMACAddress(uint8_t * buf) override; + bool CanFactoryReset(void) override; + void InitiateFactoryReset(void) override; + CHIP_ERROR ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value) override; + CHIP_ERROR WritePersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t value) override; + +#if 0 + CHIP_ERROR GetRebootCount(uint32_t & rebootCount) override; + CHIP_ERROR StoreRebootCount(uint32_t rebootCount) override; + CHIP_ERROR GetTotalOperationalHours(uint32_t & totalOperationalHours) override; + CHIP_ERROR StoreTotalOperationalHours(uint32_t totalOperationalHours) override; + CHIP_ERROR GetBootReason(uint32_t & bootReasons) override; + CHIP_ERROR StoreBootReason(uint32_t bootReasons) override; +#endif + + // NOTE: Other public interface methods are implemented by GenericConfigurationManagerImpl<>. + + // ===== Members for internal use by the following friends. + + CHIP_ERROR ReadConfigValue(Key key, bool & val) override; + CHIP_ERROR ReadConfigValue(Key key, uint32_t & val) override; + CHIP_ERROR ReadConfigValue(Key key, uint64_t & val) override; + CHIP_ERROR ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) override; + CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) override; + CHIP_ERROR WriteConfigValue(Key key, bool val) override; + CHIP_ERROR WriteConfigValue(Key key, uint32_t val) override; + CHIP_ERROR WriteConfigValue(Key key, uint64_t val) override; + CHIP_ERROR WriteConfigValueStr(Key key, const char * str) override; + CHIP_ERROR WriteConfigValueStr(Key key, const char * str, size_t strLen) override; + CHIP_ERROR WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) override; + void RunConfigUnitTest(void) override; + + friend ConfigurationManager & ConfigurationMgr(void); + friend ConfigurationManagerImpl & ConfigurationMgrImpl(void); + + static ConfigurationManagerImpl sInstance; + + // ===== Private members reserved for use by this class only. + + static void DoFactoryReset(intptr_t arg); +}; + +/** + * Returns the public interface of the ConfigurationManager singleton object. + * + * Chip applications should use this to access features of the ConfigurationManager object + * that are common to all platforms. + */ +inline ConfigurationManager & ConfigurationMgr(void) +{ + return ConfigurationManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the ConfigurationManager singleton object. + * + * Chip applications can use this to gain access to features of the ConfigurationManager + * that are specific to the BL602 platform. + */ +inline ConfigurationManagerImpl & ConfigurationMgrImpl(void) +{ + return ConfigurationManagerImpl::sInstance; +} + +inline CHIP_ERROR ConfigurationManagerImpl::GetPrimaryWiFiMACAddress(uint8_t * buf) +{ + log_error("ConfigurationManagerImpl::_GetPrimaryWiFiMACAddress() is not supported now.\r\n"); + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/ConnectivityManagerImpl.cpp b/src/platform/bouffalolab/BL602/ConnectivityManagerImpl.cpp new file mode 100644 index 00000000000000..f1424c5aca8e8a --- /dev/null +++ b/src/platform/bouffalolab/BL602/ConnectivityManagerImpl.cpp @@ -0,0 +1,153 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* this file behaves like a config.h, comes first */ +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#include +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#include +#endif + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#define zero(S) memset(&S, 0, sizeof(S)) + +using namespace ::chip; +using namespace ::chip::Dnssd; +using namespace ::chip::Inet; +using namespace ::chip::System; +using namespace ::chip::TLV; +using namespace ::chip::DeviceLayer::Internal; + +namespace chip { +namespace DeviceLayer { + +ConnectivityManagerImpl ConnectivityManagerImpl::sInstance; +static ConnectivityManager::WiFiStationState ConnectivityManagerImpl::mWiFiStationState = + ConnectivityManager::kWiFiStationState_NotConnected; + +void ConnectivityManagerImpl::WifiStationStateChange(void) +{ + ChipDeviceEvent event; + + if (ConnectivityManagerImpl::mWiFiStationState == ConnectivityManager::kWiFiStationState_Connected) + { + event.Type = DeviceEventType::kWiFiConnectivityChange; + event.WiFiConnectivityChange.Result = kConnectivity_Established; + PlatformMgr().PostEventOrDie(&event); + } +} + +void ConnectivityManagerImpl::DriveStationState() +{ + +exit: + return; +} + +void ConnectivityManagerImpl::DriveStationState(::chip::System::Layer * aLayer, void * aAppState) +{ + sInstance.DriveStationState(); +} + +CHIP_ERROR ConnectivityManagerImpl::_SetWiFiStationMode(WiFiStationMode val) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + DeviceLayer::SystemLayer().ScheduleWork(DriveStationState, NULL); +exit: + return err; +} + +CHIP_ERROR ConnectivityManagerImpl::_Init() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + // Initialize the generic base classes that require it. +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + GenericConnectivityManagerImpl_Thread::_Init(); +#endif + + SuccessOrExit(err); + + err = SetWiFiStationMode(kWiFiStationMode_Enabled); + NetworkCommissioning::BLWiFiDriver::GetInstance().ReConnectWiFiNetwork(); + + SuccessOrExit(err); + +exit: + return err; +} + +void ConnectivityManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) +{ + // Forward the event to the generic base classes as needed. +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + GenericConnectivityManagerImpl_Thread::_OnPlatformEvent(event); +#endif +} + +bool ConnectivityManagerImpl::_IsWiFiStationEnabled(void) +{ + return GetWiFiStationMode() == kWiFiStationMode_Enabled; +} + +void ConnectivityManagerImpl::OnStationConnected() +{ + NetworkCommissioning::BLWiFiDriver::GetInstance().OnConnectWiFiNetwork(); + // TODO Invoke WARM to perform actions that occur when the WiFi station interface comes up. + +#if 0 + // Alert other components of the new state. + ChipDeviceEvent event; + event.Type = DeviceEventType::kWiFiConnectivityChange; + event.WiFiConnectivityChange.Result = kConnectivity_Established; + PlatformMgr().PostEventOrDie(&event); + + UpdateInternetConnectivityState(); +#endif +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/ConnectivityManagerImpl.h b/src/platform/bouffalolab/BL602/ConnectivityManagerImpl.h new file mode 100644 index 00000000000000..e74d536d2ed339 --- /dev/null +++ b/src/platform/bouffalolab/BL602/ConnectivityManagerImpl.h @@ -0,0 +1,124 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#include +#else +#include +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#include +#else +#include +#endif + +namespace Inet { +class IPAddress; +} // namespace Inet + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the ConnectivityManager singleton object for Bouffalolab BL602 platforms. + */ +class ConnectivityManagerImpl final : public ConnectivityManager, + public Internal::GenericConnectivityManagerImpl, + public Internal::GenericConnectivityManagerImpl_WiFi, +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + public Internal::GenericConnectivityManagerImpl_BLE, +#else + public Internal::GenericConnectivityManagerImpl_NoBLE, +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + public Internal::GenericConnectivityManagerImpl_Thread +#else + public Internal::GenericConnectivityManagerImpl_NoThread +#endif +{ + // Allow the ConnectivityManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend class ConnectivityManager; + +public: + static WiFiStationState mWiFiStationState; + + bool _IsWiFiStationConnected(void); + void WifiStationStateChange(void); + void OnStationConnected(void); + +private: + // ===== Members that implement the ConnectivityManager abstract interface. + + bool _IsWiFiStationEnabled(void); + bool _IsWiFiStationProvisioned(void); + CHIP_ERROR _SetWiFiStationMode(WiFiStationMode val); + void DriveStationState(void); + static void DriveStationState(::chip::System::Layer * aLayer, void * aAppState); + CHIP_ERROR _Init(void); + void _OnPlatformEvent(const ChipDeviceEvent * event); + void GetWifiState(void); + WiFiStationState GetWiFiStationState(void); + + // ===== Members for internal use by the following friends. + + friend ConnectivityManager & ConnectivityMgr(void); + friend ConnectivityManagerImpl & ConnectivityMgrImpl(void); + + static ConnectivityManagerImpl sInstance; +}; + +inline ConnectivityManager::WiFiStationState ConnectivityManagerImpl::GetWiFiStationState(void) +{ + return mWiFiStationState; +} + +inline bool ConnectivityManagerImpl::_IsWiFiStationConnected(void) +{ + return mWiFiStationState == kWiFiStationState_Connected; +} + +/** + * Returns the public interface of the ConnectivityManager singleton object. + * + * Chip applications should use this to access features of the ConnectivityManager object + * that are common to all platforms. + */ +inline ConnectivityManager & ConnectivityMgr(void) +{ + return ConnectivityManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the ConnectivityManager singleton object. + * + * Chip applications can use this to gain access to features of the ConnectivityManager + * that are specific to the ESP32 platform. + */ +inline ConnectivityManagerImpl & ConnectivityMgrImpl(void) +{ + return ConnectivityManagerImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/DeviceNetworkProvisioningDelegateImpl.cpp b/src/platform/bouffalolab/BL602/DeviceNetworkProvisioningDelegateImpl.cpp new file mode 100644 index 00000000000000..6a8474c9e59f69 --- /dev/null +++ b/src/platform/bouffalolab/BL602/DeviceNetworkProvisioningDelegateImpl.cpp @@ -0,0 +1,48 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "DeviceNetworkProvisioningDelegateImpl.h" +#include "NetworkCommissioningDriver.h" + +#include + +#if CHIP_ENABLE_OPENTHREAD +#include +#endif + +using namespace ::chip::DeviceLayer::Internal; + +namespace chip { +namespace DeviceLayer { + +CHIP_ERROR DeviceNetworkProvisioningDelegateImpl::_ProvisionWiFiNetwork(const char * ssid, const char * key) +{ + // BL602Config::WriteWifiInfo(ssid, passwd); + + CHIP_ERROR err = CHIP_NO_ERROR; + ChipLogProgress(NetworkProvisioning, "BL602NetworkProvisioningDelegate: SSID: %s", ssid); + err = NetworkCommissioning::BLWiFiDriver::GetInstance().ConnectWiFiNetwork(ssid, strlen(ssid), key, strlen(key)); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NetworkProvisioning, "Failed to connect to WiFi network: %s", chip::ErrorStr(err)); + } + + return err; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/DeviceNetworkProvisioningDelegateImpl.h b/src/platform/bouffalolab/BL602/DeviceNetworkProvisioningDelegateImpl.h new file mode 100644 index 00000000000000..47c9f0f6e8262c --- /dev/null +++ b/src/platform/bouffalolab/BL602/DeviceNetworkProvisioningDelegateImpl.h @@ -0,0 +1,43 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { + +namespace Internal { + +template +class GenericDeviceNetworkProvisioningDelegateImpl; + +} // namespace Internal + +class DeviceNetworkProvisioningDelegateImpl final + : public Internal::GenericDeviceNetworkProvisioningDelegateImpl +{ + friend class GenericDeviceNetworkProvisioningDelegateImpl; + +private: + CHIP_ERROR _ProvisionWiFiNetwork(const char * ssid, const char * passwd); + CHIP_ERROR _ProvisionThreadNetwork(ByteSpan threadData) { return CHIP_ERROR_NOT_IMPLEMENTED; } +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/DiagnosticDataProviderImpl.cpp b/src/platform/bouffalolab/BL602/DiagnosticDataProviderImpl.cpp new file mode 100644 index 00000000000000..3dcb1098fcd41e --- /dev/null +++ b/src/platform/bouffalolab/BL602/DiagnosticDataProviderImpl.cpp @@ -0,0 +1,138 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the DiagnosticDataProvider object + * for k32w0 platform. + */ + +#include + +#include +#include +#include + +#include + +namespace chip { +namespace DeviceLayer { + +#define HEAP_SIZE 14100 + +DiagnosticDataProviderImpl & DiagnosticDataProviderImpl::GetDefaultInstance() +{ + static DiagnosticDataProviderImpl sInstance; + return sInstance; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapFree(uint64_t & currentHeapFree) +{ + size_t freeHeapSize; + + freeHeapSize = xPortGetFreeHeapSize(); + currentHeapFree = static_cast(freeHeapSize); + return CHIP_NO_ERROR; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapUsed(uint64_t & currentHeapUsed) +{ + size_t freeHeapSize; + size_t usedHeapSize; + + freeHeapSize = xPortGetFreeHeapSize(); + usedHeapSize = HEAP_SIZE - freeHeapSize; + + currentHeapUsed = static_cast(usedHeapSize); + return CHIP_NO_ERROR; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark) +{ + size_t highWatermarkHeapSize; + + highWatermarkHeapSize = HEAP_SIZE - xPortGetMinimumEverFreeHeapSize(); + currentHeapHighWatermark = static_cast(highWatermarkHeapSize); + return CHIP_NO_ERROR; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetRebootCount(uint16_t & rebootCount) +{ + uint32_t count = 0; + + CHIP_ERROR err = ConfigurationMgr().GetRebootCount(count); + + if (err == CHIP_NO_ERROR) + { + VerifyOrReturnError(count <= UINT16_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE); + rebootCount = static_cast(count); + } + + return err; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetUpTime(uint64_t & upTime) +{ +#if 0 + System::Clock::Timestamp currentTime = System::SystemClock().GetMonotonicTimestamp(); + System::Clock::Timestamp startTime = PlatformMgrImpl().GetStartTime(); + + if (currentTime >= startTime) + { + upTime = std::chrono::duration_cast(currentTime - startTime).count(); + return CHIP_NO_ERROR; + } +#endif + + return CHIP_ERROR_INVALID_TIME; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetTotalOperationalHours(uint32_t & totalOperationalHours) +{ + uint64_t upTime = 0; + + if (GetUpTime(upTime) == CHIP_NO_ERROR) + { + uint32_t totalHours = 0; + if (ConfigurationMgr().GetTotalOperationalHours(totalHours) == CHIP_NO_ERROR) + { + VerifyOrReturnError(upTime / 3600 <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE); + totalOperationalHours = totalHours + static_cast(upTime / 3600); + return CHIP_NO_ERROR; + } + } + + return CHIP_ERROR_INVALID_TIME; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetBootReason(BootReasonType & bootReason) +{ + uint32_t reason = 0; + + CHIP_ERROR err = ConfigurationMgr().GetBootReason(reason); + + if (err == CHIP_NO_ERROR) + { + VerifyOrReturnError(reason <= UINT8_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE); + bootReason = static_cast(reason); + } + + return err; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/DiagnosticDataProviderImpl.h b/src/platform/bouffalolab/BL602/DiagnosticDataProviderImpl.h new file mode 100644 index 00000000000000..dadada68c197a5 --- /dev/null +++ b/src/platform/bouffalolab/BL602/DiagnosticDataProviderImpl.h @@ -0,0 +1,53 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the DiagnosticDataProvider object. + */ + +#pragma once + +#include + +#include + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the PlatformManager singleton object for Linux platforms. + */ +class DiagnosticDataProviderImpl : public DiagnosticDataProvider +{ +public: + static DiagnosticDataProviderImpl & GetDefaultInstance(); + + // ===== Methods that implement the PlatformManager abstract interface. + + CHIP_ERROR GetCurrentHeapFree(uint64_t & currentHeapFree) override; + CHIP_ERROR GetCurrentHeapUsed(uint64_t & currentHeapUsed) override; + CHIP_ERROR GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark) override; + + CHIP_ERROR GetRebootCount(uint16_t & rebootCount) override; + CHIP_ERROR GetUpTime(uint64_t & upTime) override; + CHIP_ERROR GetTotalOperationalHours(uint32_t & totalOperationalHours) override; + CHIP_ERROR GetBootReason(BootReasonType & bootReason) override; +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/DnssdImpl.cpp b/src/platform/bouffalolab/BL602/DnssdImpl.cpp new file mode 100644 index 00000000000000..9f0f3a1a02f2a7 --- /dev/null +++ b/src/platform/bouffalolab/BL602/DnssdImpl.cpp @@ -0,0 +1,299 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lib/dnssd/platform/Dnssd.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace chip::Dnssd; + +using namespace ::chip::DeviceLayer::Internal; +namespace { + +static constexpr uint32_t kTimeoutMilli = 3000; +static constexpr size_t kMaxResults = 20; +} // namespace + +namespace chip { +namespace Dnssd { + +#define MDNS_MAX_PACKET_SIZE 64 + +static const DnssdService * glservice; + +CHIP_ERROR ChipDnssdInit(DnssdAsyncReturnCallback initCallback, DnssdAsyncReturnCallback errorCallback, void * context) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + + mdns_resp_init(); + initCallback(context, error); + + glservice = static_cast(chip::Platform::MemoryCalloc(1, sizeof(DnssdService))); + + return error; +} + +CHIP_ERROR ChipDnssdShutdown() +{ + return CHIP_NO_ERROR; +} + +static const char * GetProtocolString(DnssdServiceProtocol protocol) +{ + return protocol == DnssdServiceProtocol::kDnssdProtocolTcp ? "_tcp" : "_udp"; +} + +typedef struct +{ + const char * key; /*!< item key name */ + const char * value; /*!< item value string */ + size_t value_len; +} mdns_txt_item_t; + +typedef struct mdns +{ + struct netif * netif; + int slot; +} mdns_t; + +#define MDNS_TXT_MAX_LEN 128 +static mdns_t mdns = { NULL, -1 }; +mdns_txt_item_t * items = nullptr; +uint8_t packet[MDNS_TXT_MAX_LEN]; + +static inline uint8_t _mdns_append_u8(uint8_t * packet, uint16_t * index, uint8_t value) +{ + if (*index >= MDNS_MAX_PACKET_SIZE) + { + return 0; + } + + packet[*index] = value; + *index += 1; + return 1; +} + +static inline int append_one_txt_record_entry(uint8_t * packet, uint16_t * index, mdns_txt_item_t * txt) +{ + if (txt == NULL || txt->key == NULL || packet == NULL) + { + return -1; + } + + size_t key_len = strlen(txt->key); + size_t len = key_len + txt->value_len + (txt->value ? 1 : 0); + if ((*index + len + 1) >= MDNS_MAX_PACKET_SIZE) + { + return 0; + } + + _mdns_append_u8(packet, index, len); + memcpy(packet + *index, txt->key, key_len); + if (txt->value) + { + packet[*index + key_len] = '='; + memcpy(packet + *index + key_len + 1, txt->value, txt->value_len); + } + + *index += len; + + return len + 1; +} + +static void dnssd_txt_resolve(uint8_t * packet, mdns_txt_item_t * txt, int count) +{ + uint16_t index = 0; + + for (int i = 0; i < count; i++) + { + append_one_txt_record_entry(packet, &index, &(txt[i])); + } +} + +static void srv_txt(struct mdns_service * service, void * txt_userdata) +{ + int i, ret; + int index = 0; + + for (i = 0; i < 3; i++) + { + ret = mdns_resp_add_service_txtitem(service, &(packet[index + 1]), packet[index]); + if (ret) + { + log_info("send txt failed.\r\n"); + + return; + } + + index = index + packet[index] + 1; + } +} + +static void ota_txt(struct mdns_service * service, void * txt_userdata) +{ + int ret = mdns_resp_add_service_txtitem(service, "version=12345678", 16); + if (ret) + { + log_info("send ota txt failed.\r\n"); + } +} + +static err_t mdns_responder_stop_netifapi_errt_fn(struct netif * netif) +{ + return mdns_responder_stop(netif); +} + +int mdns_responder_ops(struct netif * netif) +{ + int ret, slot = -1; + int protocol = 0; + uint16_t packet_len = 0; + + if (netif == NULL) + { + log_info("netif is NULL\r\n"); + return -1; + } + + mdns.netif = netif; + + ret = mdns_resp_add_netif(netif, glservice->mHostName, 10); + if (ret != 0) + { + mdns_resp_deinit(); + log_info("add netif failed:%d\r\n", ret); + return -1; + } + + items = static_cast(chip::Platform::MemoryCalloc(glservice->mTextEntrySize, sizeof(mdns_txt_item_t))); + + for (size_t i = 0; i < glservice->mTextEntrySize; i++) + { + items[i].key = glservice->mTextEntries[i].mKey; + items[i].value = reinterpret_cast(glservice->mTextEntries[i].mData); + items[i].value_len = glservice->mTextEntries[i].mDataSize; + packet_len = packet_len + strlen(items[i].key) + items[i].value_len + 1; + } + + // todo:use malloc? + // packet = static_cast(chip::Platform::MemoryCalloc(packet_len, sizeof(uint8_t))); + if (MDNS_TXT_MAX_LEN < packet_len) + { + return -1; + } + + dnssd_txt_resolve(packet, items, glservice->mTextEntrySize); + chip::Platform::MemoryFree(items); + + log_info("name = %s nType = %s protocol = %d port = %d \r\n", glservice->mName, glservice->mType, protocol, glservice->mPort); + slot = mdns_resp_add_service(netif, glservice->mName, glservice->mType, static_cast(glservice->mProtocol), + glservice->mPort, 60, srv_txt, NULL); + if (slot < 0) + { + mdns_resp_remove_netif(netif); + mdns_resp_deinit(); + log_info("add server failed:%d\r\n", slot); + return -1; + } + + // for ota + slot = + mdns_resp_add_service(netif, "MATTER OTA", "_ota", static_cast(glservice->mProtocol), 3333, 1000, ota_txt, NULL); + if (slot < 0) + { + mdns_resp_remove_netif(netif); + mdns_resp_deinit(); + log_info("ota mdns fail.\r\n"); + } + + return slot; +} + +static err_t mdns_responder_start_netifapi_errt_fn(struct netif * netif) +{ + return mdns_responder_ops(netif); +} + +CHIP_ERROR ChipDnssdPublishService(const DnssdService * service, DnssdPublishCallback callback, void * context) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + struct netif * netif; + int slot; + bool mdns_flag; + + if (!(chip::DeviceLayer::ConnectivityMgrImpl()._IsWiFiStationConnected())) + { + return CHIP_ERROR_NOT_IMPLEMENTED; + } + + if (service) + { + memcpy(glservice, service, sizeof(DnssdService)); + } + + netif = wifi_mgmr_sta_netif_get(); + if (netif == NULL) + { + log_info("find failed\r\n"); + return CHIP_ERROR_INTERNAL; + } + + slot = netifapi_netif_common(netif, NULL, mdns_responder_start_netifapi_errt_fn); + if (slot < 0) + { + log_info("start mdns failed\r\n"); + return CHIP_ERROR_INTERNAL; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR ChipDnssdRemoveServices() +{ + // netifapi_netif_common(mdns.netif, NULL, mdns_responder_stop_netifapi_errt_fn); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ChipDnssdFinalizeServiceUpdate() +{ + return CHIP_NO_ERROR; +} + +CHIP_ERROR ChipDnssdBrowse(const char * /*type*/, DnssdServiceProtocol /*protocol*/, chip::Inet::IPAddressType addressType, + chip::Inet::InterfaceId /*interface*/, DnssdBrowseCallback /*callback*/, void * /*context*/) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR ChipDnssdResolve(DnssdService * /*service*/, chip::Inet::InterfaceId /*interface*/, DnssdResolveCallback /*callback*/, + void * /*context*/) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +} // namespace Dnssd +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/GroupKeyStoreImpl.cpp b/src/platform/bouffalolab/BL602/GroupKeyStoreImpl.cpp new file mode 100644 index 00000000000000..295e30f68dd3bf --- /dev/null +++ b/src/platform/bouffalolab/BL602/GroupKeyStoreImpl.cpp @@ -0,0 +1,377 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the CHIP GroupKeyStore interface + * for platforms based on the Bouffalolab SDK. + */ +/* this file behaves like a config.h, comes first */ +#include + +#include + +using namespace ::chip; +using namespace ::chip::Profiles::Security::AppKeys; + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +CHIP_ERROR GroupKeyStoreImpl::RetrieveGroupKey(uint32_t keyId, ChipGroupKey & key) +{ + CHIP_ERROR err; + + // Iterate over all the GroupKey easyflash records looking for a matching key... + err = ForEachRecord(kConfigKey_GroupKeyBase, kConfigKey_GroupKeyMax, false, + [keyId, &key](const Key & efKey, const size_t & length) -> CHIP_ERROR { + CHIP_ERROR err2; + size_t keyLen; + uint8_t buf[kMaxEncodedKeySize]; // (buf length == 45 bytes) + uint32_t curKeyId; + + // Read the easyflash obj binary data data into the buffer. + err2 = ReadConfigValueBin(efKey, buf, sizeof(buf), keyLen); + + // Decode the CHIP key id for the current key. + err2 = DecodeGroupKeyId(buf, keyLen, curKeyId); + SuccessOrExit(err2); + + // If it matches the key we're looking for... + if (curKeyId == keyId) + { + // Decode the associated key data. + err2 = DecodeGroupKey(buf, keyLen, key); + SuccessOrExit(err2); + + // End the iteration by returning a CHIP_END_OF_INPUT result. + ExitNow(err2 = CHIP_END_OF_INPUT); + } + + exit: + return err2; + }); + + // Modify error code for return. + switch (err) + { + case CHIP_END_OF_INPUT: + err = CHIP_NO_ERROR; // Match found. + break; + case CHIP_NO_ERROR: + err = CHIP_ERROR_KEY_NOT_FOUND; // Match not found. + break; + default: + break; + } + + return err; +} + +CHIP_ERROR GroupKeyStoreImpl::StoreGroupKey(const ChipGroupKey & key) +{ + CHIP_ERROR err; + + // Delete any existing group key with the same id (this may or may not exit). + DeleteGroupKey(key.KeyId); // no error checking here. + + // Iterate over all the GroupKey easyflash records looking for the first + // empty easyflash key where we can store the data. (Note- use arg addNewrecord=true) + err = ForEachRecord(kConfigKey_GroupKeyBase, kConfigKey_GroupKeyMax, true, + [&key](const Key & efKey, const size_t & length) -> CHIP_ERROR { + CHIP_ERROR err2; + size_t keyLen; + uint8_t buf[kMaxEncodedKeySize]; // (buf length == 45 bytes) + + // Encode the key for storage in an easyflash record. + err2 = EncodeGroupKey(key, buf, sizeof(buf), keyLen); + SuccessOrExit(err2); + + // Write the encoded binary data into the easyflash object. + err2 = WriteConfigValueBin(efKey, buf, keyLen); + SuccessOrExit(err2); + + // End the iteration by returning a CHIP_END_OF_INPUT result. + ExitNow(err2 = CHIP_END_OF_INPUT); + + exit: + return err2; + }); + + // Modify error code for return. + switch (err) + { + case CHIP_END_OF_INPUT: + err = CHIP_NO_ERROR; // Key entry was stored. + break; + case CHIP_NO_ERROR: + err = CHIP_ERROR_KEY_NOT_FOUND; // Key entry was not stored. + break; + default: + break; + } + + if (err == CHIP_NO_ERROR) + { +#if CHIP_PROGRESS_LOGGING + { + char extraKeyInfo[32]; + if (ChipKeyId::IsAppEpochKey(key.KeyId)) + { + snprintf(extraKeyInfo, sizeof(extraKeyInfo), ", start time %" PRId32, key.StartTime); + } + else if (ChipKeyId::IsAppGroupMasterKey(key.KeyId)) + { + snprintf(extraKeyInfo, sizeof(extraKeyInfo), ", global id 0x%08" PRIX32, key.GlobalId); + } + else + { + extraKeyInfo[0] = 0; + } + } + +#endif // CHIP_PROGRESS_LOGGING + } + + return err; +} + +CHIP_ERROR GroupKeyStoreImpl::DeleteGroupKey(uint32_t keyId) +{ + CHIP_ERROR err; + + // Iterate over all the GroupKey easyflash records looking for a matching key... + err = ForEachRecord(kConfigKey_GroupKeyBase, kConfigKey_GroupKeyMax, false, + [keyId](const Key & efKey, const size_t & length) -> CHIP_ERROR { + CHIP_ERROR err2; + size_t keyLen; + uint8_t buf[kMaxEncodedKeySize]; // (buf length == 45 bytes) + uint32_t curKeyId; + + // Read the easyflash obj binary data data into the buffer. + err2 = ReadConfigValueBin(efKey, buf, sizeof(buf), keyLen); + SuccessOrExit(err2); + + // Decode the CHIP key id for the current group key. + err2 = DecodeGroupKeyId(buf, keyLen, curKeyId); + SuccessOrExit(err2); + + // If it matches the key we are looking for, delete the easyflash record. + if (curKeyId == keyId) + { + err2 = ClearConfigValue(efKey); + ChipLogProgress(DeviceLayer, "GroupKeyStore: deleting key 0x%08" PRIX32, curKeyId); + + // End the iteration by returning a CHIP_END_OF_INPUT result. + ExitNow(err2 = CHIP_END_OF_INPUT); + } + + exit: + return err2; + }); + + // Modify error code for return. + switch (err) + { + case CHIP_END_OF_INPUT: + err = CHIP_NO_ERROR; // Key entry was deleted. + break; + case CHIP_NO_ERROR: + err = CHIP_ERROR_KEY_NOT_FOUND; // Key entry was not deleted. + break; + default: + break; + } + + return err; +} + +CHIP_ERROR GroupKeyStoreImpl::DeleteGroupKeysOfAType(uint32_t keyType) +{ + CHIP_ERROR err; + + // Iterate over all the GroupKey easyflash records looking for a matching key... + err = ForEachRecord(kConfigKey_GroupKeyBase, kConfigKey_GroupKeyMax, false, + [keyType](const Key & efKey, const size_t & length) -> CHIP_ERROR { + CHIP_ERROR err2; + size_t keyLen; + uint8_t buf[kMaxEncodedKeySize]; // (buf length == 45 bytes) + uint32_t curKeyId; + + // Read the easyflash obj binary data data into the buffer. + err2 = ReadConfigValueBin(efKey, buf, sizeof(buf), keyLen); + SuccessOrExit(err2); + + // Decode the CHIP key id for the current group key. + err2 = DecodeGroupKeyId(buf, keyLen, curKeyId); + SuccessOrExit(err2); + + // If the current key matches the type we are looking for, delete the easyflash record. + if (ChipKeyId::GetType(curKeyId) == keyType) + { + err2 = ClearConfigValue(efKey); + ChipLogProgress(DeviceLayer, "GroupKeyStore: deleting key 0x%08" PRIX32, curKeyId); + } + + exit: + return err2; + }); + + return err; +} + +CHIP_ERROR GroupKeyStoreImpl::EnumerateGroupKeys(uint32_t keyType, uint32_t * keyIds, uint8_t keyIdsArraySize, uint8_t & keyCount) +{ + CHIP_ERROR err; + + keyCount = 0; + + // Iterate over all the GroupKey records looking for keys of the specified type... + err = ForEachRecord(kConfigKey_GroupKeyBase, kConfigKey_GroupKeyMax, false, + [keyType, keyIds, keyIdsArraySize, &keyCount](const Key & efKey, const size_t & length) -> CHIP_ERROR { + CHIP_ERROR err2; + size_t keyLen; + uint8_t buf[kMaxEncodedKeySize]; // (buf length == 45 bytes) + uint32_t curKeyId; + + // Read the easyflash obj binary data data into the buffer. + err2 = ReadConfigValueBin(efKey, buf, sizeof(buf), keyLen); + SuccessOrExit(err2); + + // Decode the CHIP key id for the current group key. + err2 = DecodeGroupKeyId(buf, keyLen, curKeyId); + SuccessOrExit(err2); + + // If the current key matches the type we're looking for, add it to the keyIds array. + if ((keyType == ChipKeyId::kType_None) || (ChipKeyId::GetType(curKeyId) == keyType)) + { + keyIds[keyCount++] = curKeyId; + + // Stop iterating if there's no more room in the keyIds array. + VerifyOrExit(keyCount < keyIdsArraySize, err2 = CHIP_ERROR_BUFFER_TOO_SMALL); + } + + exit: + return err2; + }); + + // Simply return a truncated list if there are more matching keys than will fit in the array. + if (err == CHIP_ERROR_BUFFER_TOO_SMALL) + { + err = CHIP_NO_ERROR; + } + + return err; +} + +CHIP_ERROR GroupKeyStoreImpl::Clear(void) +{ + CHIP_ERROR err; + + // Iterate over all the GroupKey easyflash records deleting each one... + err = ForEachRecord(kConfigKey_GroupKeyBase, kConfigKey_GroupKeyMax, false, + [](const Key & efKey, const size_t & length) -> CHIP_ERROR { + CHIP_ERROR err2; + + err2 = ClearConfigValue(efKey); + SuccessOrExit(err2); + + exit: + return err2; + }); + + return err; +} + +CHIP_ERROR GroupKeyStoreImpl::RetrieveLastUsedEpochKeyId(void) +{ + CHIP_ERROR err; + + err = ReadConfigValue(kConfigKey_LastUsedEpochKeyId, LastUsedEpochKeyId); + if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) + { + LastUsedEpochKeyId = ChipKeyId::kNone; + err = CHIP_NO_ERROR; + } + return err; +} + +CHIP_ERROR GroupKeyStoreImpl::StoreLastUsedEpochKeyId(void) +{ + return WriteConfigValue(kConfigKey_LastUsedEpochKeyId, LastUsedEpochKeyId); +} + +CHIP_ERROR GroupKeyStoreImpl::Init() +{ + // Nothing to do + return CHIP_NO_ERROR; +} + +CHIP_ERROR GroupKeyStoreImpl::EncodeGroupKey(const ChipGroupKey & key, uint8_t * buf, size_t bufSize, size_t & encodedKeyLen) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + uint8_t * p = buf; + + VerifyOrExit(bufSize >= kFixedEncodedKeySize + key.KeyLen, err = CHIP_ERROR_BUFFER_TOO_SMALL); + + Encoding::LittleEndian::Write32(p, key.KeyId); + Encoding::LittleEndian::Write32(p, key.StartTime); + Encoding::Write8(p, key.KeyLen); + memcpy(p, key.Key, key.KeyLen); + p += key.KeyLen; + + encodedKeyLen = p - buf; + +exit: + return err; +} + +CHIP_ERROR GroupKeyStoreImpl::DecodeGroupKeyId(const uint8_t * encodedKey, size_t encodedKeyLen, uint32_t & keyId) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrExit(encodedKeyLen >= kFixedEncodedKeySize, err = CHIP_ERROR_INVALID_ARGUMENT); + + keyId = Encoding::LittleEndian::Get32(encodedKey); + +exit: + return err; +} + +CHIP_ERROR GroupKeyStoreImpl::DecodeGroupKey(const uint8_t * encodedKey, size_t encodedKeyLen, ChipGroupKey & key) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t * p = encodedKey; + + VerifyOrExit(encodedKeyLen >= kFixedEncodedKeySize, err = CHIP_ERROR_INVALID_ARGUMENT); + + key.KeyId = Encoding::LittleEndian::Read32(p); + key.StartTime = Encoding::LittleEndian::Read32(p); + key.KeyLen = Encoding::Read8(p); + + VerifyOrExit(encodedKeyLen >= kFixedEncodedKeySize + key.KeyLen, err = CHIP_ERROR_INVALID_ARGUMENT); + + memcpy(key.Key, p, key.KeyLen); + +exit: + return err; +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/GroupKeyStoreImpl.h b/src/platform/bouffalolab/BL602/GroupKeyStoreImpl.h new file mode 100644 index 00000000000000..5831594dc907b5 --- /dev/null +++ b/src/platform/bouffalolab/BL602/GroupKeyStoreImpl.h @@ -0,0 +1,73 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the Chip Group Key Store interface + * for platforms based on the Bouffalolab SDK. + */ + +#include +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +/** + * An implementation of the Chip GroupKeyStoreBase API for platforms based + * on the Bouffalolab SDK. + */ +class GroupKeyStoreImpl final : public ::chip::Profiles::Security::AppKeys::GroupKeyStoreBase, private BL602Config +{ + using ChipGroupKey = ::chip::Profiles::Security::AppKeys::ChipGroupKey; + +public: + CHIP_ERROR Init(); + + CHIP_ERROR RetrieveGroupKey(uint32_t keyId, ChipGroupKey & key) override; + CHIP_ERROR StoreGroupKey(const ChipGroupKey & key) override; + CHIP_ERROR DeleteGroupKey(uint32_t keyId) override; + CHIP_ERROR DeleteGroupKeysOfAType(uint32_t keyType) override; + CHIP_ERROR EnumerateGroupKeys(uint32_t keyType, uint32_t * keyIds, uint8_t keyIdsArraySize, uint8_t & keyCount) override; + CHIP_ERROR Clear(void) override; + CHIP_ERROR RetrieveLastUsedEpochKeyId(void) override; + CHIP_ERROR StoreLastUsedEpochKeyId(void) override; + +private: + static constexpr size_t kFixedEncodedKeySize = 4U + // key id + 4U + // start time / global id + 1U; // key data length + + static constexpr size_t kMaxEncodedKeySize = kFixedEncodedKeySize + ChipGroupKey::MaxKeySize; + + /* Not used + static constexpr uint16_t kGroupKeyFileId = GetFileId(kConfigKey_GroupKey); + static constexpr uint16_t kGroupKeyRecordKey = GetRecordKey(kConfigKey_GroupKey); + */ + + static CHIP_ERROR EncodeGroupKey(const ChipGroupKey & key, uint8_t * buf, size_t bufSize, size_t & encodedKeyLen); + static CHIP_ERROR DecodeGroupKey(const uint8_t * encodedKey, size_t encodedKeyLen, ChipGroupKey & key); + static CHIP_ERROR DecodeGroupKeyId(const uint8_t * encodedKey, size_t encodedKeyLen, uint32_t & keyId); +}; + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/InetPlatformConfig.h b/src/platform/bouffalolab/BL602/InetPlatformConfig.h new file mode 100644 index 00000000000000..c79c5fc061e0a5 --- /dev/null +++ b/src/platform/bouffalolab/BL602/InetPlatformConfig.h @@ -0,0 +1,51 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the CHIP Inet + * Layer on BL602 platforms using the Bouffalolab SDK. + * + */ + +#pragma once + +#include + +// ==================== Platform Adaptations ==================== + +#define INET_CONFIG_ERROR_TYPE int32_t +#define INET_CONFIG_NO_ERROR 0 +#define INET_CONFIG_ERROR_MIN 1000000 +#define INET_CONFIG_ERROR_MAX 1000999 + +#if LWIP_CONFIG_ENABLE_IPV4 +#define INET_CONFIG_ENABLE_IPV4 1 +#else +#define INET_CONFIG_ENABLE_IPV4 0 +#endif + +// ========== Platform-specific Configuration Overrides ========= + +#ifndef INET_CONFIG_NUM_TCP_ENDPOINTS +#define INET_CONFIG_NUM_TCP_ENDPOINTS 4 +#endif // INET_CONFIG_NUM_TCP_ENDPOINTS + +#ifndef INET_CONFIG_NUM_UDP_ENDPOINTS +#define INET_CONFIG_NUM_UDP_ENDPOINTS 4 +#endif // INET_CONFIG_NUM_UDP_ENDPOINTS diff --git a/src/platform/bouffalolab/BL602/KeyValueStoreManagerImpl.cpp b/src/platform/bouffalolab/BL602/KeyValueStoreManagerImpl.cpp new file mode 100644 index 00000000000000..d313f426df9948 --- /dev/null +++ b/src/platform/bouffalolab/BL602/KeyValueStoreManagerImpl.cpp @@ -0,0 +1,210 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific key value storage implementation for BL602 + */ +/* this file behaves like a config.h, comes first */ +#include + +#include + +#include + +#include +#include + +/* ignore GCC Wconversion warnings for pigweed */ +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + +#include + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +namespace chip { +namespace DeviceLayer { +namespace PersistedStorage { + +using namespace ::chip::DeviceLayer::Internal; + +KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance; + +CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size, + size_t offset_bytes) const +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + // todo: need get value at offset for return + size_t outlen = 0; + BL602Config::Key ckey = { key }; + + err = BL602Config::ReadConfigValueBin(ckey, value, value_size, outlen); + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + SuccessOrExit(err); + + if (read_bytes_size) + { + *read_bytes_size = outlen; + } + +exit: + return err; +} + +CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, size_t value_size) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + BL602Config::Key ckey = { key }; + + err = BL602Config::WriteConfigValueBin(ckey, value, value_size); + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return err; +} + +CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + BL602Config::Key ckey = { key }; + + err = BL602Config::ClearConfigValue(ckey); + + if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) + { + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + return err; +} + +// #if defined(CHIP_KVS_AVAILABLE) && CHIP_KVS_AVAILABLE + +// CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size, +// size_t offset_bytes) const +// { +// assert(CHIP_KVS_AVAILABLE); +// auto status_and_size = mKvs.Get(key, std::span(reinterpret_cast(value), value_size), offset_bytes); +// if (read_bytes_size) +// { +// *read_bytes_size = status_and_size.size(); +// } +// switch (status_and_size.status().code()) +// { +// case pw::OkStatus().code(): +// return CHIP_NO_ERROR; +// case pw::Status::NotFound().code(): +// return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; +// case pw::Status::DataLoss().code(): +// return CHIP_ERROR_INTEGRITY_CHECK_FAILED; +// case pw::Status::ResourceExhausted().code(): +// return CHIP_ERROR_BUFFER_TOO_SMALL; +// case pw::Status::FailedPrecondition().code(): +// return CHIP_ERROR_WELL_UNINITIALIZED; +// case pw::Status::InvalidArgument().code(): +// return CHIP_ERROR_INVALID_ARGUMENT; +// default: +// break; +// } +// return CHIP_ERROR_INTERNAL; // Unexpected KVS status. +// } + +// CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, size_t value_size) +// { +// assert(CHIP_KVS_AVAILABLE); +// auto status = mKvs.Put(key, std::span(reinterpret_cast(value), value_size)); +// switch (status.code()) +// { +// case pw::OkStatus().code(): +// return CHIP_NO_ERROR; +// case pw::Status::DataLoss().code(): +// return CHIP_ERROR_INTEGRITY_CHECK_FAILED; +// case pw::Status::ResourceExhausted().code(): +// case pw::Status::AlreadyExists().code(): +// return CHIP_ERROR_PERSISTED_STORAGE_FAILED; +// case pw::Status::FailedPrecondition().code(): +// return CHIP_ERROR_WELL_UNINITIALIZED; +// case pw::Status::InvalidArgument().code(): +// return CHIP_ERROR_INVALID_ARGUMENT; +// default: +// break; +// } +// return CHIP_ERROR_INTERNAL; // Unexpected KVS status. +// } + +// CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) +// { +// printf("KeyValueStoreManagerImpl::_Delete, key = %s\r\n", key); +// assert(CHIP_KVS_AVAILABLE); +// printf("KeyValueStoreManagerImpl::_Delete, key = %s\r\n", key); + +// auto status = mKvs.Delete(key); +// switch (status.code()) +// { +// case pw::OkStatus().code(): +// return CHIP_NO_ERROR; +// case pw::Status::NotFound().code(): +// return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; +// case pw::Status::DataLoss().code(): +// return CHIP_ERROR_INTEGRITY_CHECK_FAILED; +// case pw::Status::ResourceExhausted().code(): +// return CHIP_ERROR_PERSISTED_STORAGE_FAILED; +// case pw::Status::FailedPrecondition().code(): +// return CHIP_ERROR_WELL_UNINITIALIZED; +// case pw::Status::InvalidArgument().code(): +// return CHIP_ERROR_INVALID_ARGUMENT; +// default: +// break; +// } +// return CHIP_ERROR_INTERNAL; // Unexpected KVS status. +// } + +// CHIP_ERROR KeyValueStoreManagerImpl::ErasePartition() +// { +// assert(CHIP_KVS_AVAILABLE); +// auto status = mKvsPartition.Erase(); +// switch (status.code()) +// { +// case pw::OkStatus().code(): +// return CHIP_NO_ERROR; +// case pw::Status::DeadlineExceeded().code(): +// return CHIP_ERROR_TIMEOUT; +// case pw::Status::PermissionDenied().code(): +// return CHIP_ERROR_ACCESS_DENIED; +// default: +// break; +// } +// return CHIP_ERROR_INTERNAL; // Unexpected KVS status. +// } +// #endif // defined(CHIP_KVS_AVAILABLE) && CHIP_KVS_AVAILABLE + +} // namespace PersistedStorage +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/KeyValueStoreManagerImpl.h b/src/platform/bouffalolab/BL602/KeyValueStoreManagerImpl.h new file mode 100644 index 00000000000000..31180fb838b98b --- /dev/null +++ b/src/platform/bouffalolab/BL602/KeyValueStoreManagerImpl.h @@ -0,0 +1,92 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific key value storage implementation for BL602. + * + */ + +#pragma once + +/* ignore GCC Wconversion warnings for pigweed */ +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + +#include +#include +#include + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +#pragma once + +namespace chip { +namespace DeviceLayer { +namespace PersistedStorage { + +class KeyValueStoreManagerImpl final : public KeyValueStoreManager +{ + // Allow the KeyValueStoreManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend class KeyValueStoreManager; + +public: + CHIP_ERROR _Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size = nullptr, size_t offset = 0) const; + + CHIP_ERROR _Delete(const char * key); + + CHIP_ERROR _Put(const char * key, const void * value, size_t value_size); + +private: + // ===== Members for internal use by the following friends. + friend KeyValueStoreManager & KeyValueStoreMgr(); + friend KeyValueStoreManagerImpl & KeyValueStoreMgrImpl(); + + static KeyValueStoreManagerImpl sInstance; +}; + +/** + * Returns the public interface of the KeyValueStoreManager singleton object. + * + * Chip applications should use this to access features of the KeyValueStoreManager object + * that are common to all platforms. + */ +inline KeyValueStoreManager & KeyValueStoreMgr(void) +{ + return KeyValueStoreManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the KeyValueStoreManager singleton object. + * + * Chip applications can use this to gain access to features of the KeyValueStoreManager + * that are specific to the ESP32 platform. + */ +inline KeyValueStoreManagerImpl & KeyValueStoreMgrImpl(void) +{ + return KeyValueStoreManagerImpl::sInstance; +} + +} // namespace PersistedStorage +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/Logging.cpp b/src/platform/bouffalolab/BL602/Logging.cpp new file mode 100644 index 00000000000000..6ed1005826d9d2 --- /dev/null +++ b/src/platform/bouffalolab/BL602/Logging.cpp @@ -0,0 +1,45 @@ +/* See Project CHIP LICENSE file for licensing information. */ + +#include + +#include +#include + +#include + +// #ifdef LOG_LOCAL_LEVEL +// #undef LOG_LOCAL_LEVEL +// #endif +// #define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE + +extern "C" { +#include +} + +namespace chip { +namespace Logging { +namespace Platform { + +void LogV(const char * module, uint8_t category, const char * msg, va_list v) +{ + char formattedMsg[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE]; + vsnprintf(formattedMsg, sizeof(formattedMsg), msg, v); + + switch (category) + { + case kLogCategory_Error: + log_error("[%s] %s\r\n", module, formattedMsg); + break; + case kLogCategory_Progress: + default: + log_info("[%s] %s\r\n", module, formattedMsg); + break; + case kLogCategory_Detail: + log_trace("[%s] %s\r\n", module, formattedMsg); + break; + } +} + +} // namespace Platform +} // namespace Logging +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/NetworkCommissioningDriver.cpp b/src/platform/bouffalolab/BL602/NetworkCommissioningDriver.cpp new file mode 100644 index 00000000000000..8d4b3fcf6a52ec --- /dev/null +++ b/src/platform/bouffalolab/BL602/NetworkCommissioningDriver.cpp @@ -0,0 +1,375 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace ::chip; +//#if CHIP_DEVICE_CONFIG_ENABLE_WIFI +namespace chip { +namespace DeviceLayer { +namespace NetworkCommissioning { + +namespace { +constexpr char kWiFiSSIDKeyName[] = "wifi-ssid"; +constexpr char kWiFiCredentialsKeyName[] = "wifi-pass"; + +constexpr char blWiFiSSIDKeyName[] = "bl-wifi-ssid"; +constexpr char blWiFiCredentialsKeyName[] = "bl-wifi-pass"; + +static uint8_t WiFiSSIDStr[DeviceLayer::Internal::kMaxWiFiSSIDLength]; +} // namespace + +CHIP_ERROR BLWiFiDriver::Init(NetworkStatusChangeCallback * networkStatusChangeCallback) +{ + CHIP_ERROR err; + size_t ssidLen = 0; + size_t credentialsLen = 0; + + err = PersistedStorage::KeyValueStoreMgr().Get(kWiFiCredentialsKeyName, mSavedNetwork.credentials, + sizeof(mSavedNetwork.credentials), &credentialsLen); + if (err == CHIP_ERROR_NOT_FOUND) + { + return CHIP_NO_ERROR; + } + + err = PersistedStorage::KeyValueStoreMgr().Get(kWiFiSSIDKeyName, mSavedNetwork.ssid, sizeof(mSavedNetwork.ssid), &ssidLen); + if (err == CHIP_ERROR_NOT_FOUND) + { + return CHIP_NO_ERROR; + } + mSavedNetwork.credentialsLen = credentialsLen; + mSavedNetwork.ssidLen = ssidLen; + + mStagingNetwork = mSavedNetwork; + mpScanCallback = nullptr; + mpConnectCallback = nullptr; + mpStatusChangeCallback = networkStatusChangeCallback; + + return err; +} + +CHIP_ERROR BLWiFiDriver::Shutdown() +{ + mpStatusChangeCallback = nullptr; + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLWiFiDriver::CommitConfiguration() +{ + ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(kWiFiSSIDKeyName, mStagingNetwork.ssid, mStagingNetwork.ssidLen)); + ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(kWiFiCredentialsKeyName, mStagingNetwork.credentials, + mStagingNetwork.credentialsLen)); + mSavedNetwork = mStagingNetwork; + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLWiFiDriver::SaveConfiguration() +{ + if (NULL == mStagingNetwork.ssid || 0 == mStagingNetwork.ssidLen || NULL == mStagingNetwork.credentials || + 0 == mStagingNetwork.credentialsLen) + { + return CHIP_ERROR_KEY_NOT_FOUND; + } + + ReturnErrorOnFailure( + PersistedStorage::KeyValueStoreMgr().Put(blWiFiSSIDKeyName, mStagingNetwork.ssid, mStagingNetwork.ssidLen)); + ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(blWiFiCredentialsKeyName, mStagingNetwork.credentials, + mStagingNetwork.credentialsLen)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLWiFiDriver::RevertConfiguration() +{ + mStagingNetwork = mSavedNetwork; + return CHIP_NO_ERROR; +} + +bool BLWiFiDriver::NetworkMatch(const WiFiNetwork & network, ByteSpan networkId) +{ + return networkId.size() == network.ssidLen && memcmp(networkId.data(), network.ssid, network.ssidLen) == 0; +} + +Status BLWiFiDriver::AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials, MutableCharSpan & outDebugText, + uint8_t & outNetworkIndex) +{ + VerifyOrReturnError(mStagingNetwork.ssidLen == 0 || NetworkMatch(mStagingNetwork, ssid), Status::kBoundsExceeded); + VerifyOrReturnError(credentials.size() <= sizeof(mStagingNetwork.credentials), Status::kOutOfRange); + VerifyOrReturnError(ssid.size() <= sizeof(mStagingNetwork.ssid), Status::kOutOfRange); + + memcpy(mStagingNetwork.credentials, credentials.data(), credentials.size()); + mStagingNetwork.credentialsLen = static_cast(credentials.size()); + + memcpy(mStagingNetwork.ssid, ssid.data(), ssid.size()); + mStagingNetwork.ssidLen = static_cast(ssid.size()); + + return Status::kSuccess; +} + +Status BLWiFiDriver::RemoveNetwork(ByteSpan networkId, MutableCharSpan & outDebugText, uint8_t & outNetworkIndex) +{ + VerifyOrReturnError(NetworkMatch(mStagingNetwork, networkId), Status::kNetworkIDNotFound); + + // Use empty ssid for representing invalid network + mStagingNetwork.ssidLen = 0; + return Status::kSuccess; +} + +Status BLWiFiDriver::ReorderNetwork(ByteSpan networkId, uint8_t index, MutableCharSpan & outDebugText) +{ + // Only one network is supported now + VerifyOrReturnError(index == 0, Status::kOutOfRange); + VerifyOrReturnError(NetworkMatch(mStagingNetwork, networkId), Status::kNetworkIDNotFound); + return Status::kSuccess; +} + +CHIP_ERROR BLWiFiDriver::ConnectWiFiNetwork(const char * ssid, uint8_t ssidLen, const char * key, uint8_t keyLen) +{ + // ReturnErrorOnFailure(ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Disabled)); + + char wifi_ssid[64] = { 0 }; + char passwd[64] = { 0 }; + // Set the wifi configuration + memcpy(wifi_ssid, ssid, ssidLen); + memcpy(passwd, key, keyLen); + wifi_interface_t wifi_interface; + wifi_interface = wifi_mgmr_sta_enable(); + wifi_mgmr_sta_connect(wifi_interface, ssid, passwd, NULL, NULL, 0, 0); + + // Configure the WiFi interface. + ReturnErrorOnFailure(ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Disabled)); + + return ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Enabled); +} + +CHIP_ERROR BLWiFiDriver::ReConnectWiFiNetwork(void) +{ + char ssid[64] = { 0 }; + char psk[64] = { 0 }; + size_t ssidLen = 0; + size_t pskLen = 0; + + ReturnErrorOnFailure( + PersistedStorage::KeyValueStoreMgr().Get((const char *) blWiFiSSIDKeyName, (void *) ssid, 64, &ssidLen, 0)); + ReturnErrorOnFailure( + PersistedStorage::KeyValueStoreMgr().Get((const char *) blWiFiCredentialsKeyName, (void *) psk, 64, &pskLen, 0)); + + ConnectWiFiNetwork(ssid, ssidLen, psk, pskLen); + + return CHIP_NO_ERROR; +} + +void BLWiFiDriver::OnConnectWiFiNetwork() +{ + if (mpConnectCallback) + { + mpConnectCallback->OnResult(Status::kSuccess, CharSpan(), 0); + mpConnectCallback = nullptr; + } +} + +void BLWiFiDriver::ConnectNetwork(ByteSpan networkId, ConnectCallback * callback) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + Status networkingStatus = Status::kSuccess; + static int save = 0; + + // VerifyOrExit(NetworkMatch(mStagingNetwork, networkId), networkingStatus = Status::kNetworkIDNotFound); + // VerifyOrExit(mpConnectCallback == nullptr, networkingStatus = Status::kUnknownError); + ChipLogProgress(NetworkProvisioning, "BL NetworkCommissioningDelegate: SSID: %.*s", static_cast(networkId.size()), + networkId.data()); + + err = ConnectWiFiNetwork(reinterpret_cast(mStagingNetwork.ssid), mStagingNetwork.ssidLen, + reinterpret_cast(mStagingNetwork.credentials), mStagingNetwork.credentialsLen); + mpConnectCallback = callback; + +exit: + if (err != CHIP_NO_ERROR) + { + networkingStatus = Status::kUnknownError; + } + if (networkingStatus != Status::kSuccess) + { + ChipLogError(NetworkProvisioning, "Failed to connect to WiFi network:%s", chip::ErrorStr(err)); + mpConnectCallback = nullptr; + callback->OnResult(networkingStatus, CharSpan(), 0); + } +} + +#if 0 +CHIP_ERROR ESPWiFiDriver::StartScanWiFiNetworks(ByteSpan ssid) +{ + esp_err_t err = ESP_OK; + if (ssid.data()) + { + wifi_scan_config_t scan_config = { 0 }; + memset(WiFiSSIDStr, 0, sizeof(WiFiSSIDStr)); + memcpy(WiFiSSIDStr, ssid.data(), ssid.size()); + scan_config.ssid = WiFiSSIDStr; + err = esp_wifi_scan_start(&scan_config, false); + } + else + { + err = esp_wifi_scan_start(NULL, false); + } + if (err != ESP_OK) + { + return chip::DeviceLayer::Internal::ESP32Utils::MapError(err); + } + return CHIP_NO_ERROR; +} +#endif + +#if 0 +void ESPWiFiDriver::OnScanWiFiNetworkDone() +{ + uint16_t ap_number; + esp_wifi_scan_get_ap_num(&ap_number); + if (!ap_number) + { + ChipLogProgress(DeviceLayer, "No AP found"); + if (mpScanCallback != nullptr) + { + mpScanCallback->OnFinished(Status::kSuccess, CharSpan(), nullptr); + mpScanCallback = nullptr; + } + return; + } + std::unique_ptr ap_buffer_ptr(new wifi_ap_record_t[ap_number]); + if (ap_buffer_ptr == NULL) + { + ChipLogError(DeviceLayer, "can't malloc memory for ap_list_buffer"); + if (mpScanCallback) + { + mpScanCallback->OnFinished(Status::kUnknownError, CharSpan(), nullptr); + mpScanCallback = nullptr; + } + return; + } + wifi_ap_record_t * ap_list_buffer = ap_buffer_ptr.get(); + if (esp_wifi_scan_get_ap_records(&ap_number, ap_list_buffer) == ESP_OK) + { + if (CHIP_NO_ERROR == DeviceLayer::SystemLayer().ScheduleLambda([ap_number, ap_list_buffer]() { + std::unique_ptr auto_free(ap_list_buffer); + ESPScanResponseIterator iter(ap_number, ap_list_buffer); + if (GetInstance().mpScanCallback) + { + GetInstance().mpScanCallback->OnFinished(Status::kSuccess, CharSpan(), &iter); + GetInstance().mpScanCallback = nullptr; + } + else + { + ChipLogError(DeviceLayer, "can't find the ScanCallback function"); + } + })) + { + ap_buffer_ptr.release(); + } + } + else + { + ChipLogError(DeviceLayer, "can't get ap_records "); + if (mpScanCallback) + { + mpScanCallback->OnFinished(Status::kUnknownError, CharSpan(), nullptr); + mpScanCallback = nullptr; + } + } +} +#endif + +void BLWiFiDriver::ScanNetworks(ByteSpan ssid, WiFiDriver::ScanCallback * callback) +{ +#if 0 + if (callback != nullptr) + { + mpScanCallback = callback; + if (StartScanWiFiNetworks(ssid) != CHIP_NO_ERROR) + { + mpScanCallback = nullptr; + callback->OnFinished(Status::kUnknownError, CharSpan(), nullptr); + } + } +#endif +} + +#if 0 +CHIP_ERROR GetConnectedNetwork(Network & network) +{ + wifi_ap_record_t ap_info; + esp_err_t err; + err = esp_wifi_sta_get_ap_info(&ap_info); + if (err != ESP_OK) + { + return chip::DeviceLayer::Internal::ESP32Utils::MapError(err); + } + uint8_t length = strnlen(reinterpret_cast(ap_info.ssid), DeviceLayer::Internal::kMaxWiFiSSIDLength); + if (length > sizeof(network.networkID)) + { + return CHIP_ERROR_INTERNAL; + } + memcpy(network.networkID, ap_info.ssid, length); + network.networkIDLen = length; + return CHIP_NO_ERROR; +} +#endif + +size_t BLWiFiDriver::WiFiNetworkIterator::Count() +{ + return mDriver->mStagingNetwork.ssidLen == 0 ? 0 : 1; +} + +bool BLWiFiDriver::WiFiNetworkIterator::Next(Network & item) +{ +#if 0 + if (mExhausted || mDriver->mStagingNetwork.ssidLen == 0) + { + return false; + } + memcpy(item.networkID, mDriver->mStagingNetwork.ssid, mDriver->mStagingNetwork.ssidLen); + item.networkIDLen = mDriver->mStagingNetwork.ssidLen; + item.connected = false; + mExhausted = true; + + Network connectedNetwork; + CHIP_ERROR err = GetConnectedNetwork(connectedNetwork); + if (err == CHIP_NO_ERROR) + { + if (connectedNetwork.networkIDLen == item.networkIDLen && + memcmp(connectedNetwork.networkID, item.networkID, item.networkIDLen) == 0) + { + item.connected = true; + } + } +#endif + return true; +} + +} // namespace NetworkCommissioning +} // namespace DeviceLayer +} // namespace chip +//#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI diff --git a/src/platform/bouffalolab/BL602/NetworkCommissioningDriver.h b/src/platform/bouffalolab/BL602/NetworkCommissioningDriver.h new file mode 100644 index 00000000000000..5ce9ecc82c4862 --- /dev/null +++ b/src/platform/bouffalolab/BL602/NetworkCommissioningDriver.h @@ -0,0 +1,138 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once +#include + +namespace chip { +namespace DeviceLayer { +namespace NetworkCommissioning { +//#if CHIP_DEVICE_CONFIG_ENABLE_WIFI +namespace { +constexpr uint8_t kMaxWiFiNetworks = 1; +constexpr uint8_t kWiFiScanNetworksTimeOutSeconds = 10; +constexpr uint8_t kWiFiConnectNetworkTimeoutSeconds = 20; +} // namespace + +class BLScanResponseIterator : public Iterator +{ +public: + // BLScanResponseIterator(const size_t size, const wifi_ap_record_t * scanResults) : mSize(size), mpScanResults(scanResults) {} + size_t Count() override { return mSize; } + bool Next(WiFiScanResponse & item) override + { + if (mIternum >= mSize) + { + return false; + } + +#if 0 + item.security = mpScanResults[mIternum].authmode; + item.ssidLen = + strnlen(reinterpret_cast(mpScanResults[mIternum].ssid), chip::DeviceLayer::Internal::kMaxWiFiSSIDLength); + item.channel = mpScanResults[mIternum].primary; + item.wiFiBand = chip::DeviceLayer::NetworkCommissioning::WiFiBand::k2g4; + item.rssi = mpScanResults[mIternum].rssi; + memcpy(item.ssid, mpScanResults[mIternum].ssid, item.ssidLen); + memcpy(item.bssid, mpScanResults[mIternum].bssid, 6); +#endif + + mIternum++; + return true; + } + void Release() override {} + +private: + const size_t mSize; + // const wifi_ap_record_t * mpScanResults; + size_t mIternum = 0; +}; + +class BLWiFiDriver final : public WiFiDriver +{ +public: + class WiFiNetworkIterator final : public NetworkIterator + { + public: + WiFiNetworkIterator(BLWiFiDriver * aDriver) : mDriver(aDriver) {} + size_t Count() override; + bool Next(Network & item) override; + void Release() override { delete this; } + ~WiFiNetworkIterator() = default; + + private: + BLWiFiDriver * mDriver; + bool mExhausted = false; + }; + + struct WiFiNetwork + { + char ssid[DeviceLayer::Internal::kMaxWiFiSSIDLength]; + uint8_t ssidLen = 0; + char credentials[DeviceLayer::Internal::kMaxWiFiKeyLength]; + uint8_t credentialsLen = 0; + }; + + // BaseDriver + NetworkIterator * GetNetworks() override { return new WiFiNetworkIterator(this); } + CHIP_ERROR Init(NetworkStatusChangeCallback * networkStatusChangeCallback) override; + CHIP_ERROR Shutdown(); + + // WirelessDriver + uint8_t GetMaxNetworks() override { return kMaxWiFiNetworks; } + uint8_t GetScanNetworkTimeoutSeconds() override { return kWiFiScanNetworksTimeOutSeconds; } + uint8_t GetConnectNetworkTimeoutSeconds() override { return kWiFiConnectNetworkTimeoutSeconds; } + + CHIP_ERROR CommitConfiguration() override; + CHIP_ERROR SaveConfiguration(); + CHIP_ERROR RevertConfiguration() override; + + Status RemoveNetwork(ByteSpan networkId, MutableCharSpan & outDebugText, uint8_t & outNetworkIndex) override; + Status ReorderNetwork(ByteSpan networkId, uint8_t index, MutableCharSpan & outDebugText) override; + void ConnectNetwork(ByteSpan networkId, ConnectCallback * callback) override; + + // WiFiDriver + Status AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials, MutableCharSpan & outDebugText, + uint8_t & outNetworkIndex) override; + void ScanNetworks(ByteSpan ssid, ScanCallback * callback) override; + + CHIP_ERROR ConnectWiFiNetwork(const char * ssid, uint8_t ssidLen, const char * key, uint8_t keyLen); + CHIP_ERROR ReConnectWiFiNetwork(void); + void OnConnectWiFiNetwork(); + void OnScanWiFiNetworkDone(); + static BLWiFiDriver & GetInstance() + { + static BLWiFiDriver instance; + return instance; + } + +private: + bool NetworkMatch(const WiFiNetwork & network, ByteSpan networkId); + CHIP_ERROR StartScanWiFiNetworks(ByteSpan ssid); + + WiFiNetworkIterator mWiFiIterator = WiFiNetworkIterator(this); + WiFiNetwork mSavedNetwork; + WiFiNetwork mStagingNetwork; + ScanCallback * mpScanCallback; + ConnectCallback * mpConnectCallback; + NetworkStatusChangeCallback * mpStatusChangeCallback = nullptr; +}; +//#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI + +} // namespace NetworkCommissioning +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/NetworkCommissioningWiFiDriver.cpp b/src/platform/bouffalolab/BL602/NetworkCommissioningWiFiDriver.cpp new file mode 100644 index 00000000000000..3a9d341a5443a2 --- /dev/null +++ b/src/platform/bouffalolab/BL602/NetworkCommissioningWiFiDriver.cpp @@ -0,0 +1,371 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace ::chip; +//#if CHIP_DEVICE_CONFIG_ENABLE_WIFI +namespace chip { +namespace DeviceLayer { +namespace NetworkCommissioning { + +namespace { +constexpr char kWiFiSSIDKeyName[] = "wifi-ssid"; +constexpr char kWiFiCredentialsKeyName[] = "wifi-pass"; + +constexpr char blWiFiSSIDKeyName[] = "bl-wifi-ssid"; +constexpr char blWiFiCredentialsKeyName[] = "bl-wifi-pass"; + +static uint8_t WiFiSSIDStr[DeviceLayer::Internal::kMaxWiFiSSIDLength]; +} // namespace + +CHIP_ERROR BLWiFiDriver::Init() +{ + CHIP_ERROR err; + size_t ssidLen = 0; + size_t credentialsLen = 0; + + err = PersistedStorage::KeyValueStoreMgr().Get(kWiFiCredentialsKeyName, mSavedNetwork.credentials, + sizeof(mSavedNetwork.credentials), &credentialsLen); + if (err == CHIP_ERROR_NOT_FOUND) + { + return CHIP_NO_ERROR; + } + + err = PersistedStorage::KeyValueStoreMgr().Get(kWiFiSSIDKeyName, mSavedNetwork.ssid, sizeof(mSavedNetwork.ssid), &ssidLen); + if (err == CHIP_ERROR_NOT_FOUND) + { + return CHIP_NO_ERROR; + } + mSavedNetwork.credentialsLen = credentialsLen; + mSavedNetwork.ssidLen = ssidLen; + + mStagingNetwork = mSavedNetwork; + mpScanCallback = nullptr; + mpConnectCallback = nullptr; + + return err; +} + +CHIP_ERROR BLWiFiDriver::Shutdown() +{ + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLWiFiDriver::CommitConfiguration() +{ + ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(kWiFiSSIDKeyName, mStagingNetwork.ssid, mStagingNetwork.ssidLen)); + ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(kWiFiCredentialsKeyName, mStagingNetwork.credentials, + mStagingNetwork.credentialsLen)); + mSavedNetwork = mStagingNetwork; + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLWiFiDriver::SaveConfiguration() +{ + if (NULL == mStagingNetwork.ssid || 0 == mStagingNetwork.ssidLen || NULL == mStagingNetwork.credentials || + 0 == mStagingNetwork.credentialsLen) + { + return CHIP_ERROR_KEY_NOT_FOUND; + } + + ReturnErrorOnFailure( + PersistedStorage::KeyValueStoreMgr().Put(blWiFiSSIDKeyName, mStagingNetwork.ssid, mStagingNetwork.ssidLen)); + ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(blWiFiCredentialsKeyName, mStagingNetwork.credentials, + mStagingNetwork.credentialsLen)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLWiFiDriver::RevertConfiguration() +{ + mStagingNetwork = mSavedNetwork; + return CHIP_NO_ERROR; +} + +bool BLWiFiDriver::NetworkMatch(const WiFiNetwork & network, ByteSpan networkId) +{ + return networkId.size() == network.ssidLen && memcmp(networkId.data(), network.ssid, network.ssidLen) == 0; +} + +Status BLWiFiDriver::AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials) +{ + VerifyOrReturnError(mStagingNetwork.ssidLen == 0 || NetworkMatch(mStagingNetwork, ssid), Status::kBoundsExceeded); + VerifyOrReturnError(credentials.size() <= sizeof(mStagingNetwork.credentials), Status::kOutOfRange); + VerifyOrReturnError(ssid.size() <= sizeof(mStagingNetwork.ssid), Status::kOutOfRange); + + memcpy(mStagingNetwork.credentials, credentials.data(), credentials.size()); + mStagingNetwork.credentialsLen = static_cast(credentials.size()); + + memcpy(mStagingNetwork.ssid, ssid.data(), ssid.size()); + mStagingNetwork.ssidLen = static_cast(ssid.size()); + + return Status::kSuccess; +} + +Status BLWiFiDriver::RemoveNetwork(ByteSpan networkId) +{ + VerifyOrReturnError(NetworkMatch(mStagingNetwork, networkId), Status::kNetworkIDNotFound); + + // Use empty ssid for representing invalid network + mStagingNetwork.ssidLen = 0; + return Status::kSuccess; +} + +Status BLWiFiDriver::ReorderNetwork(ByteSpan networkId, uint8_t index) +{ + // Only one network is supported now + VerifyOrReturnError(index == 0, Status::kOutOfRange); + VerifyOrReturnError(NetworkMatch(mStagingNetwork, networkId), Status::kNetworkIDNotFound); + return Status::kSuccess; +} + +CHIP_ERROR BLWiFiDriver::ConnectWiFiNetwork(const char * ssid, uint8_t ssidLen, const char * key, uint8_t keyLen) +{ + // ReturnErrorOnFailure(ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Disabled)); + + char wifi_ssid[64] = { 0 }; + char passwd[64] = { 0 }; + // Set the wifi configuration + memcpy(wifi_ssid, ssid, ssidLen); + memcpy(passwd, key, keyLen); + wifi_interface_t wifi_interface; + wifi_interface = wifi_mgmr_sta_enable(); + wifi_mgmr_sta_connect(wifi_interface, ssid, passwd, NULL, NULL, 0, 0); + + // Configure the WiFi interface. + ReturnErrorOnFailure(ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Disabled)); + + return ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Enabled); +} + +CHIP_ERROR BLWiFiDriver::ReConnectWiFiNetwork(void) +{ + char ssid[64] = { 0 }; + char psk[64] = { 0 }; + size_t ssidLen = 0; + size_t pskLen = 0; + + ReturnErrorOnFailure( + PersistedStorage::KeyValueStoreMgr().Get((const char *) blWiFiSSIDKeyName, (void *) ssid, 64, &ssidLen, 0)); + ReturnErrorOnFailure( + PersistedStorage::KeyValueStoreMgr().Get((const char *) blWiFiCredentialsKeyName, (void *) psk, 64, &pskLen, 0)); + + ConnectWiFiNetwork(ssid, ssidLen, psk, pskLen); + + return CHIP_NO_ERROR; +} + +void BLWiFiDriver::OnConnectWiFiNetwork() +{ + if (mpConnectCallback) + { + mpConnectCallback->OnResult(Status::kSuccess, CharSpan(), 0); + mpConnectCallback = nullptr; + } +} + +void BLWiFiDriver::ConnectNetwork(ByteSpan networkId, ConnectCallback * callback) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + Status networkingStatus = Status::kSuccess; + static int save = 0; + + // VerifyOrExit(NetworkMatch(mStagingNetwork, networkId), networkingStatus = Status::kNetworkIDNotFound); + // VerifyOrExit(mpConnectCallback == nullptr, networkingStatus = Status::kUnknownError); + ChipLogProgress(NetworkProvisioning, "BL NetworkCommissioningDelegate: SSID: %.*s", static_cast(networkId.size()), + networkId.data()); + + err = ConnectWiFiNetwork(reinterpret_cast(mStagingNetwork.ssid), mStagingNetwork.ssidLen, + reinterpret_cast(mStagingNetwork.credentials), mStagingNetwork.credentialsLen); + mpConnectCallback = callback; + +exit: + if (err != CHIP_NO_ERROR) + { + networkingStatus = Status::kUnknownError; + } + if (networkingStatus != Status::kSuccess) + { + ChipLogError(NetworkProvisioning, "Failed to connect to WiFi network:%s", chip::ErrorStr(err)); + mpConnectCallback = nullptr; + callback->OnResult(networkingStatus, CharSpan(), 0); + } +} + +#if 0 +CHIP_ERROR ESPWiFiDriver::StartScanWiFiNetworks(ByteSpan ssid) +{ + esp_err_t err = ESP_OK; + if (ssid.data()) + { + wifi_scan_config_t scan_config = { 0 }; + memset(WiFiSSIDStr, 0, sizeof(WiFiSSIDStr)); + memcpy(WiFiSSIDStr, ssid.data(), ssid.size()); + scan_config.ssid = WiFiSSIDStr; + err = esp_wifi_scan_start(&scan_config, false); + } + else + { + err = esp_wifi_scan_start(NULL, false); + } + if (err != ESP_OK) + { + return chip::DeviceLayer::Internal::ESP32Utils::MapError(err); + } + return CHIP_NO_ERROR; +} +#endif + +#if 0 +void ESPWiFiDriver::OnScanWiFiNetworkDone() +{ + uint16_t ap_number; + esp_wifi_scan_get_ap_num(&ap_number); + if (!ap_number) + { + ChipLogProgress(DeviceLayer, "No AP found"); + if (mpScanCallback != nullptr) + { + mpScanCallback->OnFinished(Status::kSuccess, CharSpan(), nullptr); + mpScanCallback = nullptr; + } + return; + } + std::unique_ptr ap_buffer_ptr(new wifi_ap_record_t[ap_number]); + if (ap_buffer_ptr == NULL) + { + ChipLogError(DeviceLayer, "can't malloc memory for ap_list_buffer"); + if (mpScanCallback) + { + mpScanCallback->OnFinished(Status::kUnknownError, CharSpan(), nullptr); + mpScanCallback = nullptr; + } + return; + } + wifi_ap_record_t * ap_list_buffer = ap_buffer_ptr.get(); + if (esp_wifi_scan_get_ap_records(&ap_number, ap_list_buffer) == ESP_OK) + { + if (CHIP_NO_ERROR == DeviceLayer::SystemLayer().ScheduleLambda([ap_number, ap_list_buffer]() { + std::unique_ptr auto_free(ap_list_buffer); + ESPScanResponseIterator iter(ap_number, ap_list_buffer); + if (GetInstance().mpScanCallback) + { + GetInstance().mpScanCallback->OnFinished(Status::kSuccess, CharSpan(), &iter); + GetInstance().mpScanCallback = nullptr; + } + else + { + ChipLogError(DeviceLayer, "can't find the ScanCallback function"); + } + })) + { + ap_buffer_ptr.release(); + } + } + else + { + ChipLogError(DeviceLayer, "can't get ap_records "); + if (mpScanCallback) + { + mpScanCallback->OnFinished(Status::kUnknownError, CharSpan(), nullptr); + mpScanCallback = nullptr; + } + } +} +#endif + +void BLWiFiDriver::ScanNetworks(ByteSpan ssid, WiFiDriver::ScanCallback * callback) +{ +#if 0 + if (callback != nullptr) + { + mpScanCallback = callback; + if (StartScanWiFiNetworks(ssid) != CHIP_NO_ERROR) + { + mpScanCallback = nullptr; + callback->OnFinished(Status::kUnknownError, CharSpan(), nullptr); + } + } +#endif +} + +#if 0 +CHIP_ERROR GetConnectedNetwork(Network & network) +{ + wifi_ap_record_t ap_info; + esp_err_t err; + err = esp_wifi_sta_get_ap_info(&ap_info); + if (err != ESP_OK) + { + return chip::DeviceLayer::Internal::ESP32Utils::MapError(err); + } + uint8_t length = strnlen(reinterpret_cast(ap_info.ssid), DeviceLayer::Internal::kMaxWiFiSSIDLength); + if (length > sizeof(network.networkID)) + { + return CHIP_ERROR_INTERNAL; + } + memcpy(network.networkID, ap_info.ssid, length); + network.networkIDLen = length; + return CHIP_NO_ERROR; +} +#endif + +size_t BLWiFiDriver::WiFiNetworkIterator::Count() +{ + return mDriver->mStagingNetwork.ssidLen == 0 ? 0 : 1; +} + +bool BLWiFiDriver::WiFiNetworkIterator::Next(Network & item) +{ +#if 0 + if (mExhausted || mDriver->mStagingNetwork.ssidLen == 0) + { + return false; + } + memcpy(item.networkID, mDriver->mStagingNetwork.ssid, mDriver->mStagingNetwork.ssidLen); + item.networkIDLen = mDriver->mStagingNetwork.ssidLen; + item.connected = false; + mExhausted = true; + + Network connectedNetwork; + CHIP_ERROR err = GetConnectedNetwork(connectedNetwork); + if (err == CHIP_NO_ERROR) + { + if (connectedNetwork.networkIDLen == item.networkIDLen && + memcmp(connectedNetwork.networkID, item.networkID, item.networkIDLen) == 0) + { + item.connected = true; + } + } +#endif + return true; +} + +} // namespace NetworkCommissioning +} // namespace DeviceLayer +} // namespace chip +//#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI diff --git a/src/platform/bouffalolab/BL602/PlatformManagerImpl.cpp b/src/platform/bouffalolab/BL602/PlatformManagerImpl.cpp new file mode 100644 index 00000000000000..647f1aa87e0b43 --- /dev/null +++ b/src/platform/bouffalolab/BL602/PlatformManagerImpl.cpp @@ -0,0 +1,221 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the PlatformManager object + * for BL602 platforms using the Bouffalolab BL602 SDK. + */ +/* this file behaves like a config.h, comes first */ +#include +#include + +#include +#include +#include + +#include + +#include "AppConfig.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace DeviceLayer { + +PlatformManagerImpl PlatformManagerImpl::sInstance; + +static wifi_conf_t conf = { + .country_code = "CN", +}; + +static int app_entropy_source(void * data, unsigned char * output, size_t len, size_t * olen) +{ + + bl_rand_stream(reinterpret_cast(output), static_cast(len)); + *olen = len; + + return 0; +} + +void event_cb_wifi_event(input_event_t * event, void * private_data) +{ + static char * ssid; + static char * password; + + switch (event->code) + { + case CODE_WIFI_ON_INIT_DONE: { + wifi_mgmr_start_background(&conf); + log_info("CODE_WIFI_ON_INIT_DONE DONE.\r\n"); + } + break; + case CODE_WIFI_ON_MGMR_DONE: { + log_info("[APP] [EVT] MGMR DONE %lld\r\n", aos_now_ms()); + } + break; + case CODE_WIFI_ON_SCAN_DONE: { + log_info("[APP] [EVT] SCAN Done %lld, SCAN Result: %s\r\n", aos_now_ms(), + WIFI_SCAN_DONE_EVENT_OK == event->value ? "OK" : "Busy now"); + } + break; + case CODE_WIFI_ON_CONNECTING: { + log_info("[APP] [EVT] Connecting %lld\r\n", aos_now_ms()); + ConnectivityManagerImpl::mWiFiStationState = ConnectivityManager::kWiFiStationState_Connecting; + } + break; + case CODE_WIFI_CMD_RECONNECT: { + log_info("[APP] [EVT] Reconnect %lld\r\n", aos_now_ms()); + } + break; + case CODE_WIFI_ON_CONNECTED: { + log_info("[APP] [EVT] connected %lld\r\n", aos_now_ms()); + ConnectivityManagerImpl::mWiFiStationState = ConnectivityManager::kWiFiStationState_Connecting_Succeeded; + } + break; + case CODE_WIFI_ON_PRE_GOT_IP: { + log_info("[APP] [EVT] connected %lld\r\n", aos_now_ms()); + } + break; + case CODE_WIFI_ON_GOT_IP: { + log_info("[APP] [EVT] GOT IP %lld\r\n", aos_now_ms()); + log_info("[SYS] Memory left is %d Bytes\r\n", xPortGetFreeHeapSize()); + + ConnectivityManagerImpl::mWiFiStationState = ConnectivityManager::kWiFiStationState_Connected; + ConnectivityMgrImpl().WifiStationStateChange(); + ConnectivityMgrImpl().OnStationConnected(); + } + break; + case CODE_WIFI_ON_PROV_SSID: { + log_info("[APP] [EVT] [PROV] [SSID] %lld: %s\r\n", aos_now_ms(), event->value ? (const char *) event->value : "UNKNOWN"); + if (ssid) + { + vPortFree(ssid); + ssid = NULL; + } + ssid = (char *) event->value; + } + break; + case CODE_WIFI_ON_PROV_BSSID: { + log_info("[APP] [EVT] [PROV] [BSSID] %lld: %s\r\n", aos_now_ms(), event->value ? (const char *) event->value : "UNKNOWN"); + if (event->value) + { + vPortFree((void *) event->value); + } + } + break; + case CODE_WIFI_ON_PROV_PASSWD: { + log_info("[APP] [EVT] [PROV] [PASSWD] %lld: %s\r\n", aos_now_ms(), event->value ? (const char *) event->value : "UNKNOWN"); + if (password) + { + vPortFree(password); + password = NULL; + } + password = (char *) event->value; + } + break; + case CODE_WIFI_ON_PROV_CONNECT: { + log_info("[APP] [EVT] [PROV] [CONNECT] %lld\r\n", aos_now_ms()); +#if defined(CONFIG_BT_MESH_SYNC) + if (event->value) + { + struct _wifi_conn * conn_info = (struct _wifi_conn *) event->value; + break; + } +#endif + log_info("connecting to %s:%s...\r\n", ssid, password); + } + break; + case CODE_WIFI_ON_PROV_DISCONNECT: { + log_info("[APP] [EVT] [PROV] [DISCONNECT] %lld\r\n", aos_now_ms()); +#if defined(CONFIG_BT_MESH_SYNC) + // wifi_mgmr_sta_disconnect(); + vTaskDelay(1000); +// wifi_mgmr_sta_disable(NULL); +#endif + ConnectivityManagerImpl::mWiFiStationState = ConnectivityManager::kWiFiStationState_NotConnected; + } + break; +#if defined(CONFIG_BT_MESH_SYNC) + case CODE_WIFI_ON_PROV_SCAN_START: { + log_info("[APP] [EVT] [PROV] [SCAN] %lld\r\n", aos_now_ms()); + // wifiprov_scan((void *)event->value); + } + break; + case CODE_WIFI_ON_PROV_STATE_GET: { + log_info("[APP] [EVT] [PROV] [STATE] %lld\r\n", aos_now_ms()); + // wifiprov_wifi_state_get((void *)event->value); + } + break; +#endif /*CONFIG_BT_MESH_SYNC*/ + default: { + log_info("[APP] [EVT] Unknown code %u, %lld\r\n", event->code, aos_now_ms()); + /*nothing*/ + } + } +} + +CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) +{ + CHIP_ERROR err; + + SetConfigurationMgr(&ConfigurationManagerImpl::GetDefaultInstance()); + SetDiagnosticDataProvider(&DiagnosticDataProviderImpl::GetDefaultInstance()); + + // Initialize the configuration system. + err = Internal::BL602Config::Init(); + log_error("err: %d\r\n", err); + SuccessOrExit(err); + + // Initialize LwIP. + tcpip_init(NULL, NULL); + aos_register_event_filter(EV_WIFI, event_cb_wifi_event, NULL); + + /*wifi fw stack and thread stuff*/ + static uint8_t stack_wifi_init = 0; + + if (1 == stack_wifi_init) + { + log_error("Wi-Fi already initialized!\r\n"); + return; + } + + hal_wifi_start_firmware_task(); + stack_wifi_init = 1; + aos_post_event(EV_WIFI, CODE_WIFI_ON_INIT_DONE, 0); + + err = chip::Crypto::add_entropy_source(app_entropy_source, NULL, 16); + SuccessOrExit(err); + + // Call _InitChipStack() on the generic implementation base class + // to finish the initialization process. + err = Internal::GenericPlatformManagerImpl_FreeRTOS::_InitChipStack(); + SuccessOrExit(err); + +exit: + return err; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/PlatformManagerImpl.h b/src/platform/bouffalolab/BL602/PlatformManagerImpl.h new file mode 100644 index 00000000000000..7938c4ed4275b8 --- /dev/null +++ b/src/platform/bouffalolab/BL602/PlatformManagerImpl.h @@ -0,0 +1,101 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the PlatformManager object + * for BL602 platforms using the Bouffalolab SDK. + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { + +typedef struct +{ + uint32_t time; + uint16_t type; + uint16_t code; + unsigned long value; + unsigned long extra; +} input_event_t; + +/** + * Concrete implementation of the PlatformManager singleton object for the BL602 platform. + */ +class PlatformManagerImpl final : public PlatformManager, public Internal::GenericPlatformManagerImpl_FreeRTOS +{ + // Allow the PlatformManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend PlatformManager; + + // Allow the generic implementation base class to call helper methods on + // this class. +#ifndef DOXYGEN_SHOULD_SKIP_THIS + friend Internal::GenericPlatformManagerImpl_FreeRTOS; +#endif + +public: + // ===== Platform-specific members that may be accessed directly by the application. + + /* none so far */ + +private: + // ===== Methods that implement the PlatformManager abstract interface. + + CHIP_ERROR _InitChipStack(void); + + // ===== Members for internal use by the following friends. + + friend PlatformManager & PlatformMgr(void); + friend PlatformManagerImpl & PlatformMgrImpl(void); + friend class Internal::BLEManagerImpl; + friend void event_cb_wifi_event(input_event_t * event, void * private_data); + + static PlatformManagerImpl sInstance; + + using Internal::GenericPlatformManagerImpl_FreeRTOS::PostEventFromISR; +}; + +/** + * Returns the public interface of the PlatformManager singleton object. + * + * Chip applications should use this to access features of the PlatformManager object + * that are common to all platforms. + */ +inline PlatformManager & PlatformMgr(void) +{ + return PlatformManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the PlatformManager singleton object. + * + * Chip applications can use this to gain access to features of the PlatformManager + * that are specific to the ESP32 platform. + */ +inline PlatformManagerImpl & PlatformMgrImpl(void) +{ + return PlatformManagerImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/SoftwareUpdateManagerImpl.cpp b/src/platform/bouffalolab/BL602/SoftwareUpdateManagerImpl.cpp new file mode 100644 index 00000000000000..993a009ea7b890 --- /dev/null +++ b/src/platform/bouffalolab/BL602/SoftwareUpdateManagerImpl.cpp @@ -0,0 +1,45 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* this file behaves like a config.h, comes first */ +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_SOFTWARE_UPDATE_MANAGER + +#include +#include + +#include +#include + +namespace chip { +namespace DeviceLayer { + +SoftwareUpdateManagerImpl SoftwareUpdateManagerImpl::sInstance; + +CHIP_ERROR SoftwareUpdateManagerImpl::_Init(void) +{ + Internal::GenericSoftwareUpdateManagerImpl_BDX::DoInit(); + Internal::GenericSoftwareUpdateManagerImpl::DoInit(); + + return CHIP_NO_ERROR; +} + +} // namespace DeviceLayer +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_ENABLE_SOFTWARE_UPDATE_MANAGER diff --git a/src/platform/bouffalolab/BL602/SoftwareUpdateManagerImpl.h b/src/platform/bouffalolab/BL602/SoftwareUpdateManagerImpl.h new file mode 100644 index 00000000000000..1d2d366611f8c7 --- /dev/null +++ b/src/platform/bouffalolab/BL602/SoftwareUpdateManagerImpl.h @@ -0,0 +1,88 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#if CHIP_DEVICE_CONFIG_ENABLE_SOFTWARE_UPDATE_MANAGER + +#include +#include + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the SoftwareUpdateManager singleton object for the + * Bouffalolab BL602 platforms. + */ +class SoftwareUpdateManagerImpl final : public SoftwareUpdateManager, + public Internal::GenericSoftwareUpdateManagerImpl, + public Internal::GenericSoftwareUpdateManagerImpl_BDX +{ + // Allow the SoftwareUpdateManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend class SoftwareUpdateManager; + + // Allow the GenericSoftwareUpdateManagerImpl base class to access helper methods + // and types defined on this class. + friend class Internal::GenericSoftwareUpdateManagerImpl; + + // Allow the GenericSoftwareUpdateManagerImpl_BDX base class to access helper methods + // and types defined on this class. + friend class Internal::GenericSoftwareUpdateManagerImpl_BDX; + +public: + // ===== Members for internal use by the following friends. + + friend ::chip::DeviceLayer::SoftwareUpdateManager & SoftwareUpdateMgr(void); + friend SoftwareUpdateManagerImpl & SoftwareUpdateMgrImpl(void); + + static SoftwareUpdateManagerImpl sInstance; + +private: + // ===== Members that implement the SoftwareUpdateManager abstract interface. + + CHIP_ERROR _Init(void); +}; + +/** + * Returns a reference to the public interface of the SoftwareUpdateManager singleton object. + * + * Internal components should use this to access features of the SoftwareUpdateManager object + * that are common to all platforms. + */ +inline SoftwareUpdateManager & SoftwareUpdateMgr(void) +{ + return SoftwareUpdateManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the SoftwareUpdateManager singleton object. + * + * Internal components can use this to gain access to features of the SoftwareUpdateManager + * that are specific to the BL602 platform. + */ +inline SoftwareUpdateManagerImpl & SoftwareUpdateMgrImpl(void) +{ + return SoftwareUpdateManagerImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_ENABLE_SOFTWARE_UPDATE_MANAGER diff --git a/src/platform/bouffalolab/BL602/SystemPlatformConfig.h b/src/platform/bouffalolab/BL602/SystemPlatformConfig.h new file mode 100644 index 00000000000000..976231c4b15831 --- /dev/null +++ b/src/platform/bouffalolab/BL602/SystemPlatformConfig.h @@ -0,0 +1,54 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the CHIP System + * Layer on Bouffalolab BL602 Platforms. + * + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { +struct ChipDeviceEvent; +} // namespace DeviceLayer +} // namespace chip + +// ==================== Platform Adaptations ==================== +#define CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS 1 +#define CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME 1 +#define CHIP_SYSTEM_CONFIG_LWIP_EVENT_TYPE int +#define CHIP_SYSTEM_CONFIG_EVENT_OBJECT_TYPE const struct ::chip::DeviceLayer::ChipDeviceEvent * + +#define CHIP_SYSTEM_CONFIG_ERROR_TYPE int32_t +#define CHIP_SYSTEM_CONFIG_NO_ERROR 0 +#define CHIP_SYSTEM_CONFIG_ERROR_MIN 7000000 +#define CHIP_SYSTEM_CONFIG_ERROR_MAX 7000999 +#define _CHIP_SYSTEM_CONFIG_ERROR(e) (CHIP_SYSTEM_CONFIG_ERROR_MIN + (e)) +#define CHIP_SYSTEM_LWIP_ERROR_MIN 3000000 +#define CHIP_SYSTEM_LWIP_ERROR_MAX 3000128 + +// ========== Platform-specific Configuration Overrides ========= + +#ifndef CHIP_SYSTEM_CONFIG_NUM_TIMERS +#define CHIP_SYSTEM_CONFIG_NUM_TIMERS 16 +#endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS diff --git a/src/platform/bouffalolab/BL602/ThreadStackManagerImpl.cpp b/src/platform/bouffalolab/BL602/ThreadStackManagerImpl.cpp new file mode 100644 index 00000000000000..9466bbb420e825 --- /dev/null +++ b/src/platform/bouffalolab/BL602/ThreadStackManagerImpl.cpp @@ -0,0 +1,160 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the ThreadStackManager object for + * BL602 platforms using the Bouffalolab SDK. + * + */ +/* this file behaves like a config.h, comes first */ +#include + +#include +#include + +#include +#include + +#include + +#include + +namespace chip { +namespace DeviceLayer { + +using namespace ::chip::DeviceLayer::Internal; + +ThreadStackManagerImpl ThreadStackManagerImpl::sInstance; + +CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack(void) +{ + return InitThreadStack(NULL); +} + +CHIP_ERROR ThreadStackManagerImpl::InitThreadStack(otInstance * otInst) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + // Initialize the generic implementation base classes. + err = GenericThreadStackManagerImpl_FreeRTOS::DoInit(); + SuccessOrExit(err); + err = GenericThreadStackManagerImpl_OpenThread_LwIP::DoInit(otInst); + SuccessOrExit(err); + +exit: + return err; +} + +bool ThreadStackManagerImpl::IsInitialized() +{ + return sInstance.mThreadStackLock != NULL; +} + +} // namespace DeviceLayer +} // namespace chip + +using namespace ::chip::DeviceLayer; + +/** + * Glue function called directly by the OpenThread stack when tasklet processing work + * is pending. + */ +extern "C" void otTaskletsSignalPending(otInstance * p_instance) +{ + ThreadStackMgrImpl().SignalThreadActivityPending(); +} + +/** + * Glue function called directly by the OpenThread stack when system event processing work + * is pending. + */ +extern "C" void otSysEventSignalPending(void) +{ + BaseType_t yieldRequired = ThreadStackMgrImpl().SignalThreadActivityPendingFromISR(); + portYIELD_FROM_ISR(yieldRequired); +} + +extern "C" void * otPlatCAlloc(size_t aNum, size_t aSize) +{ + return CHIPPlatformMemoryCalloc(aNum, aSize); +} + +extern "C" void otPlatFree(void * aPtr) +{ + CHIPPlatformMemoryFree(aPtr); +} + +/** + * @brief Openthread UART implementation for the CLI is conflicting + * with the UART implemented for Pigweed RPC as they use the same UART port + * + * For now OT CLI isn't usable when the examples are built with pw_rpc + */ + +#ifndef PW_RPC_ENABLED +#include "uart.h" +#endif + +extern "C" __WEAK otError otPlatUartEnable(void) +{ +#ifdef PW_RPC_ENABLED + return OT_ERROR_NOT_IMPLEMENTED; +#else + uartConsoleInit(); + return OT_ERROR_NONE; +#endif +} + +extern "C" __WEAK otError otPlatUartSend(const uint8_t * aBuf, uint16_t aBufLength) +{ +#ifdef PW_RPC_ENABLED + return OT_ERROR_NOT_IMPLEMENTED; +#else + if (uartConsoleWrite((const char *) aBuf, aBufLength) > 0) + { + otPlatUartSendDone(); + return OT_ERROR_NONE; + } + return OT_ERROR_FAILED; +#endif +} + +extern "C" __WEAK void efr32UartProcess(void) +{ +#if !defined(PW_RPC_ENABLED) && !defined(ENABLE_CHIP_SHELL) + uint8_t tempBuf[128] = { 0 }; + // will read the data available up to 128bytes + uint16_t count = uartConsoleRead((char *) tempBuf, 128); + if (count > 0) + { + // ot process Received data for CLI cmds + otPlatUartReceived(tempBuf, count); + } +#endif +} + +extern "C" __WEAK otError otPlatUartFlush(void) +{ + return OT_ERROR_NOT_IMPLEMENTED; +} + +extern "C" __WEAK otError otPlatUartDisable(void) +{ + return OT_ERROR_NOT_IMPLEMENTED; +} diff --git a/src/platform/bouffalolab/BL602/ThreadStackManagerImpl.h b/src/platform/bouffalolab/BL602/ThreadStackManagerImpl.h new file mode 100644 index 00000000000000..0e8d7a95146f47 --- /dev/null +++ b/src/platform/bouffalolab/BL602/ThreadStackManagerImpl.h @@ -0,0 +1,118 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the ThreadStackManager object + * for BL602 platforms using the Bouffalolab SDK. + */ + +#pragma once + +#include +#include + +#include +#include + +extern "C" void otSysEventSignalPending(void); + +namespace chip { +namespace DeviceLayer { + +class ThreadStackManager; +class ThreadStackManagerImpl; +namespace Internal { +extern int GetEntropy_BL602(uint8_t * buf, size_t bufSize); +} + +/** + * Concrete implementation of the ThreadStackManager singleton object for BL602 platforms + * using the Bouffalolab SDK. + */ +class ThreadStackManagerImpl final : public ThreadStackManager, + public Internal::GenericThreadStackManagerImpl_OpenThread_LwIP, + public Internal::GenericThreadStackManagerImpl_FreeRTOS +{ + // Allow the ThreadStackManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend class ThreadStackManager; + + // Allow the generic implementation base classes to call helper methods on + // this class. +#ifndef DOXYGEN_SHOULD_SKIP_THIS + friend Internal::GenericThreadStackManagerImpl_OpenThread; + friend Internal::GenericThreadStackManagerImpl_OpenThread_LwIP; + friend Internal::GenericThreadStackManagerImpl_FreeRTOS; +#endif + + // Allow glue functions called by OpenThread to call helper methods on this + // class. + friend void ::otTaskletsSignalPending(otInstance * otInst); + friend void ::otSysEventSignalPending(void); + +public: + // ===== Platform-specific members that may be accessed directly by the application. + + using ThreadStackManager::InitThreadStack; + CHIP_ERROR InitThreadStack(otInstance * otInst); + +private: + // ===== Methods that implement the ThreadStackManager abstract interface. + + CHIP_ERROR _InitThreadStack(void); + + // ===== Members for internal use by the following friends. + + friend ThreadStackManager & ::chip::DeviceLayer::ThreadStackMgr(void); + friend ThreadStackManagerImpl & ::chip::DeviceLayer::ThreadStackMgrImpl(void); + friend int Internal::GetEntropy_BL602(uint8_t * buf, size_t bufSize); + + static ThreadStackManagerImpl sInstance; + + static bool IsInitialized(); + + // ===== Private members for use by this class only. + + ThreadStackManagerImpl() = default; +}; + +/** + * Returns the public interface of the ThreadStackManager singleton object. + * + * Chip applications should use this to access features of the ThreadStackManager object + * that are common to all platforms. + */ +inline ThreadStackManager & ThreadStackMgr(void) +{ + return ThreadStackManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the ThreadStackManager singleton object. + * + * Chip applications can use this to gain access to features of the ThreadStackManager + * that are specific to BL602 platforms. + */ +inline ThreadStackManagerImpl & ThreadStackMgrImpl(void) +{ + return ThreadStackManagerImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/bouffalolab/BL602/WarmPlatformConfig.h b/src/platform/bouffalolab/BL602/WarmPlatformConfig.h new file mode 100644 index 00000000000000..05665b04a0229b --- /dev/null +++ b/src/platform/bouffalolab/BL602/WarmPlatformConfig.h @@ -0,0 +1,39 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the Chip + * Addressing and Routing Module (WARM) on BL602 platforms + * using the Bouffalolab SDK. + * + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +#define WARM_CONFIG_SUPPORT_THREAD 1 +#define WARM_CONFIG_SUPPORT_THREAD_ROUTING 0 +#define WARM_CONFIG_SUPPORT_LEGACY6LOWPAN_NETWORK 0 +#define WARM_CONFIG_SUPPORT_WIFI 0 +#define WARM_CONFIG_SUPPORT_CELLULAR 0 + +// ========== Platform-specific Configuration Overrides ========= + +/* none so far */ diff --git a/src/platform/bouffalolab/BL602/args.gni b/src/platform/bouffalolab/BL602/args.gni new file mode 100644 index 00000000000000..f7a568013a4795 --- /dev/null +++ b/src/platform/bouffalolab/BL602/args.gni @@ -0,0 +1,45 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/bl602_sdk.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") + +import("${chip_root}/examples/platform/bouffalolab/bl602/args.gni") + +riscv_platform_config = "${bl602_sdk_build_root}/bl602_riscv.gni" + +mbedtls_target = "${bl602_sdk_build_root}:bl602_sdk" + +chip_device_platform = "bl602" +chip_mdns = "platform" + +lwip_platform = "bl602" + +chip_inet_config_enable_ipv4 = true + +chip_enable_rotating_device_id = false + +chip_config_memory_management = "platform" + +chip_build_tests = false +chip_inet_config_enable_dns_resolver = false +chip_inet_config_enable_tun_endpoint = false +chip_inet_config_enable_tcp_endpoint = true +chip_inet_config_enable_udp_endpoint = true + +pw_build_LINK_DEPS = [ + "$dir_pw_assert:impl", + "$dir_pw_log:impl", +] diff --git a/src/platform/bouffalolab/BL602/bl602-chip-mbedtls-config.h b/src/platform/bouffalolab/BL602/bl602-chip-mbedtls-config.h new file mode 100644 index 00000000000000..21e4446a466503 --- /dev/null +++ b/src/platform/bouffalolab/BL602/bl602-chip-mbedtls-config.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2021, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include +#include +#include + +/** + * Enable FreeRTOS threading support + */ +#define MBEDTLS_FREERTOS +//#define MBEDTLS_THREADING_C + +#define SL_CATALOG_FREERTOS_KERNEL_PRESENT + +/** + * Enable H Crypto and Entropy modules + */ +#define MBEDTLS_AES_C +#define MBEDTLS_ECP_C +#define MBEDTLS_ECDH_C +#define MBEDTLS_ENTROPY_C +#define MBEDTLS_SHA256_C +#define MBEDTLS_CIPHER_MODE_CTR +#define MBEDTLS_TRNG_C + +#if defined(MBEDTLS_ECP_ALT) && !defined(MBEDTLS_ECP_RESTARTABLE) +typedef void mbedtls_ecp_restart_ctx; +#endif + +#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf + +#define MBEDTLS_AES_ROM_TABLES +#define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_ASN1_WRITE_C +#define MBEDTLS_BASE64_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_CCM_C +#define MBEDTLS_CIPHER_C +#define MBEDTLS_CIPHER_MODE_CBC +#define MBEDTLS_CIPHER_MODE_CFB +#define MBEDTLS_CMAC_C +#define MBEDTLS_CTR_DRBG_C +#define MBEDTLS_ECDH_LEGACY_CONTEXT +#define MBEDTLS_ECDSA_C +#define MBEDTLS_ECDSA_DETERMINISTIC +#define MBEDTLS_ECJPAKE_C +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_NIST_OPTIM +#define MBEDTLS_ENTROPY_FORCE_SHA256 + +// TODO: 3R +// #define MBEDTLS_ENTROPY_HARDWARE_ALT + +#define MBEDTLS_ERROR_STRERROR_DUMMY +#define MBEDTLS_HAVE_ASM +#define MBEDTLS_HKDF_C +#define MBEDTLS_HMAC_DRBG_C +#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED +#define MBEDTLS_MD_C +#define MBEDTLS_NO_PLATFORM_ENTROPY +#define MBEDTLS_OID_C +#define MBEDTLS_PEM_PARSE_C +#define MBEDTLS_PEM_WRITE_C +#define MBEDTLS_PK_C +#define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PK_WRITE_C +#define MBEDTLS_PKCS5_C +#define MBEDTLS_PLATFORM_C +//#define MBEDTLS_PLATFORM_MEMORY +#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS +#define MBEDTLS_PSA_CRYPTO_C +#define MBEDTLS_PSA_CRYPTO_CONFIG +#define MBEDTLS_PSA_CRYPTO_DRIVERS +#define MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS +#define MBEDTLS_PSA_CRYPTO_STORAGE_C +#define MBEDTLS_SHA256_SMALLER +#define MBEDTLS_SHA512_C +#define MBEDTLS_SSL_CLI_C +#define MBEDTLS_SSL_COOKIE_C +#define MBEDTLS_SSL_DTLS_ANTI_REPLAY +#define MBEDTLS_SSL_DTLS_HELLO_VERIFY +#define MBEDTLS_SSL_EXPORT_KEYS +#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE +#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH +#define MBEDTLS_SSL_PROTO_TLS1_2 +#define MBEDTLS_SSL_PROTO_DTLS +#define MBEDTLS_SSL_SRV_C +#define MBEDTLS_SSL_TLS_C +#define MBEDTLS_X509_CREATE_C +#define MBEDTLS_X509_CSR_WRITE_C +#define MBEDTLS_X509_CRL_PARSE_C +#define MBEDTLS_X509_CRT_PARSE_C +#define MBEDTLS_X509_CSR_PARSE_C +#define MBEDTLS_X509_USE_C + +#define MBEDTLS_MPI_WINDOW_SIZE 1 /**< Maximum windows size used. */ +#define MBEDTLS_MPI_MAX_SIZE 32 /**< Maximum number of bytes for usable MPIs. */ +#define MBEDTLS_ECP_MAX_BITS 256 /**< Maximum bit size of groups */ +#define MBEDTLS_ECP_WINDOW_SIZE 2 /**< Maximum window size used */ +#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0 /**< Enable fixed-point speed-up */ +#define MBEDTLS_ENTROPY_MAX_SOURCES 2 /**< Maximum number of sources supported */ + +#if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE +#define MBEDTLS_SSL_MAX_CONTENT_LEN 900 /**< Maxium fragment length in bytes */ +#else +#define MBEDTLS_SSL_MAX_CONTENT_LEN 768 /**< Maxium fragment length in bytes */ +#endif + +#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 + +//#include "config-device-acceleration.h" +#include "mbedtls/check_config.h" diff --git a/src/platform/bouffalolab/BL602/gatt.xml b/src/platform/bouffalolab/BL602/gatt.xml new file mode 100644 index 00000000000000..4cc1351b399117 --- /dev/null +++ b/src/platform/bouffalolab/BL602/gatt.xml @@ -0,0 +1,98 @@ + + + + + + + + + Abstract: The generic_access service contains generic information about the device. All available Characteristics are readonly. + + + + + Empty Example + + + + + + Abstract: The external appearance of this device. The values are composed of a category (10-bits) and sub-categories (6-bits). + 0000 + + + + + + + Abstract: The Device Information Service exposes manufacturer and/or vendor information about a device. Summary: This service exposes manufacturer information about a device. The Device Information Service is instantiated as a Primary Service. Only one instance of the Device Information Service is exposed on a device. + + + + Abstract: The value of this characteristic is a UTF-8 string representing the name of the manufacturer of the device. + Bouffalolab + + + + + + Abstract: The value of this characteristic is a UTF-8 string representing the model number assigned by the device vendor. + Blue Gecko + + + + + + Abstract: The SYSTEM ID characteristic consists of a structure with two fields. The first field are the LSOs and the second field contains the MSOs. This is a 64-bit structure which consists of a 40-bit manufacturer-defined identifier concatenated with a 24 bit unique Organizationally Unique Identifier (OUI). The OUI is issued by the IEEE Registration Authority (http://standards.ieee.org/regauth/index.html) and is required to be used in accordance with IEEE Standard 802-2001.6 while the least significant 40 bits are manufacturer defined. If System ID generated based on a Bluetooth Device Address, it is required to be done as follows. System ID and the Bluetooth Device Address have a very similar structure: a Bluetooth Device Address is 48 bits in length and consists of a 24 bit Company Assigned Identifier (manufacturer defined identifier) concatenated with a 24 bit Company Identifier (OUI). In order to encapsulate a Bluetooth Device Address as System ID, the Company Identifier is concatenated with 0xFFFE followed by the Company Assigned Identifier of the Bluetooth Address. For more guidelines related to EUI-64, refer to http://standards.ieee.org/develop/regauth/tut/eui64.pdf. Examples: If the system ID is based of a Bluetooth Device Address with a Company Identifier (OUI) is 0x123456 and the Company Assigned Identifier is 0x9ABCDE, then the System Identifier is required to be 0x123456FFFE9ABCDE. + 000102030405 + + + + + + + Abstract: The Bouffalolab OTA Service enables over-the-air firmware update of the device. + + + + Abstract: Bouffalolab OTA Control. + + + + + + + + Custom service + + + + Custom characteristic + 0x00 + + + + + + Custom characteristic + 0x00 + + + + diff --git a/src/platform/bouffalolab/BL602/gatt_db.c b/src/platform/bouffalolab/BL602/gatt_db.c new file mode 100644 index 00000000000000..6a4d4977a3a8f1 --- /dev/null +++ b/src/platform/bouffalolab/BL602/gatt_db.c @@ -0,0 +1,379 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/******************************************************************** + * Autogenerated file, do not edit. + *******************************************************************/ + +#include "bg_gattdb_def.h" + +#include + +#define GATT_HEADER(F) F +#define GATT_DATA(F) F +GATT_DATA(const uint16_t bg_gattdb_data_uuidtable_16_map[]) = { + 0x2800, 0x2801, 0x2803, 0x1800, 0x2a00, 0x2a01, 0x180a, 0x2a29, 0x2a24, 0x2a23, 0xfff6, 0x1801, 0x2a05, 0x2b2a, 0x2b29, 0x2902, +}; + +GATT_DATA(const uint8_t bg_gattdb_data_uuidtable_128_map[]) = { + 0xf0, 0x19, 0x21, 0xb4, 0x47, 0x8f, 0xa4, 0xbf, 0xa1, 0x4f, 0x63, 0xfd, 0xee, 0xd6, 0x14, 0x1d, + 0x63, 0x60, 0x32, 0xe0, 0x37, 0x5e, 0xa4, 0x88, 0x53, 0x4e, 0x6d, 0xfb, 0x64, 0x35, 0xbf, 0xf7, + 0x11, 0x9d, 0x9f, 0x42, 0x9c, 0x4f, 0x9f, 0x95, 0x59, 0x45, 0x3d, 0x26, 0xf5, 0x2e, 0xee, 0x18, + 0x12, 0x9d, 0x9f, 0x42, 0x9c, 0x4f, 0x9f, 0x95, 0x59, 0x45, 0x3d, 0x26, 0xf5, 0x2e, 0xee, 0x18, +}; + +struct bg_gattdb_buffer_with_len + bg_gattdb_data_attribute_field_27_data = { .len = 1, + .data = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + } }; +GATT_DATA(const struct bg_gattdb_attribute_chrvalue bg_gattdb_data_attribute_field_27) = { + .properties = 0x2e, + .index = 6, + .max_len = 247, + .data_varlen = &bg_gattdb_data_attribute_field_27_data, +}; + +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_26) = { .len = 19, + .data = { + 0x2e, 0x1c, 0x00, 0x12, 0x9d, + 0x9f, 0x42, 0x9c, 0x4f, 0x9f, + 0x95, 0x59, 0x45, 0x3d, 0x26, + 0xf5, 0x2e, 0xee, 0x18, + } }; +struct bg_gattdb_buffer_with_len + bg_gattdb_data_attribute_field_25_data = { .len = 1, + .data = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + } }; +GATT_DATA(const struct bg_gattdb_attribute_chrvalue bg_gattdb_data_attribute_field_25) = { + .properties = 0x0a, + .index = 5, + .max_len = 247, + .data_varlen = &bg_gattdb_data_attribute_field_25_data, +}; + +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_24) = { .len = 19, + .data = { + 0x0a, 0x1a, 0x00, 0x11, 0x9d, + 0x9f, 0x42, 0x9c, 0x4f, 0x9f, + 0x95, 0x59, 0x45, 0x3d, 0x26, + 0xf5, 0x2e, 0xee, 0x18, + } }; +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_23) = { .len = 2, + .data = { + 0xf6, + 0xff, + } }; +GATT_DATA(const struct bg_gattdb_attribute_chrvalue bg_gattdb_data_attribute_field_22) = { + .properties = 0x08, + .index = 4, + .max_len = 0, + .data = NULL, +}; + +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_21) = { .len = 19, + .data = { + 0x08, 0x17, 0x00, 0x63, 0x60, + 0x32, 0xe0, 0x37, 0x5e, 0xa4, + 0x88, 0x53, 0x4e, 0x6d, 0xfb, + 0x64, 0x35, 0xbf, 0xf7, + } }; +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_20) = { .len = 16, + .data = { + 0xf0, + 0x19, + 0x21, + 0xb4, + 0x47, + 0x8f, + 0xa4, + 0xbf, + 0xa1, + 0x4f, + 0x63, + 0xfd, + 0xee, + 0xd6, + 0x14, + 0x1d, + } }; +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_19) = { .len = 6, + .data = { + 0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + } }; +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_18) = { .len = 5, + .data = { + 0x02, + 0x14, + 0x00, + 0x23, + 0x2a, + } }; +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_17) = { .len = 10, + .data = { + 0x42, + 0x6c, + 0x75, + 0x65, + 0x20, + 0x47, + 0x65, + 0x63, + 0x6b, + 0x6f, + } }; +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_16) = { .len = 5, + .data = { + 0x02, + 0x12, + 0x00, + 0x24, + 0x2a, + } }; +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_15) = { .len = 12, + .data = { + 0x53, + 0x69, + 0x6c, + 0x69, + 0x63, + 0x6f, + 0x6e, + 0x20, + 0x4c, + 0x61, + 0x62, + 0x73, + } }; +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_14) = { .len = 5, + .data = { + 0x02, + 0x10, + 0x00, + 0x29, + 0x2a, + } }; +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_13) = { .len = 2, + .data = { + 0x0a, + 0x18, + } }; +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_12) = { .len = 2, + .data = { + 0x00, + 0x00, + } }; +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_11) = { .len = 5, + .data = { + 0x02, + 0x0d, + 0x00, + 0x01, + 0x2a, + } }; +uint8_t bg_gattdb_data_attribute_field_10_data[13] = { + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x20, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, +}; +GATT_DATA(const struct bg_gattdb_attribute_chrvalue bg_gattdb_data_attribute_field_10) = { + .properties = 0x0a, + .index = 3, + .max_len = 13, + .data = bg_gattdb_data_attribute_field_10_data, +}; + +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_9) = { .len = 5, + .data = { + 0x0a, + 0x0b, + 0x00, + 0x00, + 0x2a, + } }; +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_8) = { .len = 2, + .data = { + 0x00, + 0x18, + } }; +uint8_t bg_gattdb_data_attribute_field_7_data[1] = { + 0x00, +}; +GATT_DATA(const struct bg_gattdb_attribute_chrvalue bg_gattdb_data_attribute_field_7) = { + .properties = 0x0a, + .index = 2, + .max_len = 1, + .data = bg_gattdb_data_attribute_field_7_data, +}; + +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_6) = { .len = 5, + .data = { + 0x0a, + 0x08, + 0x00, + 0x29, + 0x2b, + } }; +uint8_t bg_gattdb_data_attribute_field_5_data[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +GATT_DATA(const struct bg_gattdb_attribute_chrvalue bg_gattdb_data_attribute_field_5) = { + .properties = 0x02, + .index = 1, + .max_len = 16, + .data = bg_gattdb_data_attribute_field_5_data, +}; + +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_4) = { .len = 5, + .data = { + 0x02, + 0x06, + 0x00, + 0x2a, + 0x2b, + } }; +uint8_t bg_gattdb_data_attribute_field_2_data[4] = { + 0x00, + 0x00, + 0x00, + 0x00, +}; +GATT_DATA(const struct bg_gattdb_attribute_chrvalue bg_gattdb_data_attribute_field_2) = { + .properties = 0x20, + .index = 0, + .max_len = 4, + .data = bg_gattdb_data_attribute_field_2_data, +}; + +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_1) = { .len = 5, + .data = { + 0x20, + 0x03, + 0x00, + 0x05, + 0x2a, + } }; +GATT_DATA(const struct bg_gattdb_buffer_with_len bg_gattdb_data_attribute_field_0) = { .len = 2, + .data = { + 0x01, + 0x18, + } }; +GATT_DATA(const struct bg_gattdb_attribute bg_gattdb_data_attributes_map[]) = { + { .uuid = 0x0000, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_0 }, + { .uuid = 0x0002, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_1 }, + { .uuid = 0x000c, .permissions = 0x800, .caps = 0xffff, .datatype = 0x01, .dynamicdata = &bg_gattdb_data_attribute_field_2 }, + { .uuid = 0x000f, + .permissions = 0x807, + .caps = 0xffff, + .datatype = 0x03, + .configdata = { .flags = 0x02, .index = 0x00, .clientconfig_index = 0x00 } }, + { .uuid = 0x0002, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_4 }, + { .uuid = 0x000d, .permissions = 0x801, .caps = 0xffff, .datatype = 0x01, .dynamicdata = &bg_gattdb_data_attribute_field_5 }, + { .uuid = 0x0002, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_6 }, + { .uuid = 0x000e, .permissions = 0x803, .caps = 0xffff, .datatype = 0x01, .dynamicdata = &bg_gattdb_data_attribute_field_7 }, + { .uuid = 0x0000, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_8 }, + { .uuid = 0x0002, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_9 }, + { .uuid = 0x0004, .permissions = 0x803, .caps = 0xffff, .datatype = 0x01, .dynamicdata = &bg_gattdb_data_attribute_field_10 }, + { .uuid = 0x0002, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_11 }, + { .uuid = 0x0005, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_12 }, + { .uuid = 0x0000, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_13 }, + { .uuid = 0x0002, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_14 }, + { .uuid = 0x0007, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_15 }, + { .uuid = 0x0002, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_16 }, + { .uuid = 0x0008, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_17 }, + { .uuid = 0x0002, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_18 }, + { .uuid = 0x0009, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_19 }, + { .uuid = 0x0000, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_20 }, + { .uuid = 0x0002, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_21 }, + { .uuid = 0x8001, .permissions = 0x802, .caps = 0xffff, .datatype = 0x07, .dynamicdata = &bg_gattdb_data_attribute_field_22 }, + { .uuid = 0x0000, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_23 }, + { .uuid = 0x0002, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_24 }, + { .uuid = 0x8002, .permissions = 0x803, .caps = 0xffff, .datatype = 0x02, .dynamicdata = &bg_gattdb_data_attribute_field_25 }, + { .uuid = 0x0002, .permissions = 0x801, .caps = 0xffff, .datatype = 0x00, .constdata = &bg_gattdb_data_attribute_field_26 }, + { .uuid = 0x8003, .permissions = 0x807, .caps = 0xffff, .datatype = 0x02, .dynamicdata = &bg_gattdb_data_attribute_field_27 }, + { .uuid = 0x000f, + .permissions = 0x807, + .caps = 0xffff, + .datatype = 0x03, + .configdata = { .flags = 0x02, .index = 0x06, .clientconfig_index = 0x01 } }, +}; + +GATT_DATA(const uint16_t bg_gattdb_data_attributes_dynamic_mapping_map[]) = { + 0x0003, 0x0006, 0x0008, 0x000b, 0x0017, 0x001a, 0x001c, +}; + +GATT_DATA(const uint8_t bg_gattdb_data_adv_uuid16_map[]) = { 0x0 }; +GATT_DATA(const uint8_t bg_gattdb_data_adv_uuid128_map[]) = { 0x0 }; +GATT_HEADER(const struct bg_gattdb_def bg_gattdb_data) = { + .attributes = bg_gattdb_data_attributes_map, + .attributes_max = 29, + .uuidtable_16_size = 16, + .uuidtable_16 = bg_gattdb_data_uuidtable_16_map, + .uuidtable_128_size = 4, + .uuidtable_128 = bg_gattdb_data_uuidtable_128_map, + .attributes_dynamic_max = 7, + .attributes_dynamic_mapping = bg_gattdb_data_attributes_dynamic_mapping_map, + .adv_uuid16 = bg_gattdb_data_adv_uuid16_map, + .adv_uuid16_num = 0, + .adv_uuid128 = bg_gattdb_data_adv_uuid128_map, + .adv_uuid128_num = 0, + .caps_mask = 0xffff, + .enabled_caps = 0xffff, +}; + +const struct bg_gattdb_def * bg_gattdb = &bg_gattdb_data; diff --git a/src/platform/bouffalolab/BL602/gatt_db.h b/src/platform/bouffalolab/BL602/gatt_db.h new file mode 100644 index 00000000000000..1007bbe901fc3a --- /dev/null +++ b/src/platform/bouffalolab/BL602/gatt_db.h @@ -0,0 +1,42 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GATT_DB_H +#define __GATT_DB_H + +#if __cplusplus +extern "C" { +#endif + +#include "bg_gattdb_def.h" + +extern const struct bg_gattdb_def bg_gattdb_data; + +#define gattdb_service_changed_char 3 +#define gattdb_database_hash 6 +#define gattdb_client_support_features 8 +#define gattdb_device_name 11 +#define gattdb_ota_control 23 +#define gattdb_CHIPoBLEChar_Rx 26 +#define gattdb_CHIPoBLEChar_Tx 28 + +#if __cplusplus +} +#endif + +#endif diff --git a/src/platform/device.gni b/src/platform/device.gni index 61dddb0ec8ae72..a9e630a7eeb1e6 100755 --- a/src/platform/device.gni +++ b/src/platform/device.gni @@ -16,7 +16,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/src/ble/ble.gni") declare_args() { - # Device platform layer: cc13x2_26x2, darwin, efr32, esp32, external, freertos, linux, nrfconnect, k32w0, qpg, tizen, cyw30739, none. + # Device platform layer: cc13x2_26x2, darwin, efr32, esp32, external, freertos, linux, nrfconnect, k32w0, qpg, tizen, cyw30739, bl602, none. chip_device_platform = "auto" chip_platform_target = "" @@ -58,7 +58,7 @@ declare_args() { chip_device_platform == "linux" || chip_device_platform == "esp32" || chip_device_platform == "mbed" || chip_device_platform == "tizen" || chip_device_platform == "android" || chip_device_platform == "ameba" || - chip_device_platform == "webos" + chip_device_platform == "webos" || chip_device_platform == "bl602" # Enable ble support. if (chip_device_platform == "fake") { @@ -117,6 +117,8 @@ if (chip_device_platform == "cc13x2_26x2") { _chip_device_layer = "android" } else if (chip_device_platform == "ameba") { _chip_device_layer = "Ameba" +} else if (chip_device_platform == "bl602") { + _chip_device_layer = "bouffalolab/BL602" } else if (chip_device_platform == "cyw30739") { _chip_device_layer = "CYW30739" } else if (chip_device_platform == "webos") { @@ -166,5 +168,5 @@ assert( chip_device_platform == "telink" || chip_device_platform == "mbed" || chip_device_platform == "p6" || chip_device_platform == "android" || chip_device_platform == "ameba" || chip_device_platform == "cyw30739" || - chip_device_platform == "webos", + chip_device_platform == "webos" || chip_device_platform == "bl602", "Please select a valid value for chip_device_platform") diff --git a/third_party/bouffalolab/bl602_sdk/BUILD.gn b/third_party/bouffalolab/bl602_sdk/BUILD.gn new file mode 100644 index 00000000000000..fef5d55d847d25 --- /dev/null +++ b/third_party/bouffalolab/bl602_sdk/BUILD.gn @@ -0,0 +1,27 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/bl602_sdk.gni") +import("${bl602_sdk_build_root}/bl602_sdk.gni") + +declare_args() { + # Build target to use for bl602 SDK. Use this to set global SDK defines. + bl602_sdk_target = "" +} + +assert(bl602_sdk_target != "", "bl602_sdk_target must be specified") + +group("bl602_sdk") { + public_deps = [ bl602_sdk_target ] +} diff --git a/third_party/bouffalolab/bl602_sdk/bl602_board.gni b/third_party/bouffalolab/bl602_sdk/bl602_board.gni new file mode 100644 index 00000000000000..db983afd4a52bf --- /dev/null +++ b/third_party/bouffalolab/bl602_sdk/bl602_board.gni @@ -0,0 +1,31 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +declare_args() { + # BL602 board used + bl602_board = "BL-HWC-G1" +} + +if (bl602_board == "") { + # bl602_board = getenv("BL602_BOARD") + bl602_board = "BL-HWC-G1" +} + +assert(bl602_board != "", "bl602_board must be specified") + +board_defines = [] +# bl602_family = "" +# bl602_mcu = "" +# enable_fem = true +# board_defines += [ "PAL_RTCC_CLOCK_LFRCO" ] diff --git a/third_party/bouffalolab/bl602_sdk/bl602_executable.gni b/third_party/bouffalolab/bl602_sdk/bl602_executable.gni new file mode 100644 index 00000000000000..39c84480c5cf1e --- /dev/null +++ b/third_party/bouffalolab/bl602_sdk/bl602_executable.gni @@ -0,0 +1,51 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +import("${build_root}/toolchain/flashable_executable.gni") + +template("bl602_executable") { + output_base_name = get_path_info(invoker.output_name, "name") + + objcopy_image_name = output_base_name + ".bin" + objcopy_image_format = "binary" + objcopy = "${root_build_dir}/../../third_party/bouffalolab/bl602_sdk/repo/toolchain/riscv/Linux/bin/riscv64-unknown-elf-objcopy" + + # Copy flashing dependencies to the output directory so that the output + # is collectively self-contained; this allows flashing to work reliably + # even if the build and flashing steps take place on different machines + # or in different containers. + + flashing_runtime_target = target_name + ".flashing_runtime" + flashing_script_inputs = [ + "${chip_root}/scripts/flashing/firmware_utils.py", + "${chip_root}/scripts/flashing/bl602_firmware_utils.py", + ] + copy(flashing_runtime_target) { + sources = flashing_script_inputs + outputs = [ "${root_out_dir}/{{source_file_part}}" ] + } + + flashing_script_generator = + "${chip_root}/scripts/flashing/gen_flashing_script.py" + flashing_script_name = output_base_name + ".flash.py" + flashing_options = [ "bl602" ] + + flashable_executable(target_name) { + forward_variables_from(invoker, "*") + data_deps = [ ":${flashing_runtime_target}" ] + } +} diff --git a/third_party/bouffalolab/bl602_sdk/bl602_riscv.gni b/third_party/bouffalolab/bl602_sdk/bl602_riscv.gni new file mode 100644 index 00000000000000..3c72c6fdf06fe9 --- /dev/null +++ b/third_party/bouffalolab/bl602_sdk/bl602_riscv.gni @@ -0,0 +1,21 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("bl602_board.gni") + +riscv_arch = "rv32imfc" +riscv_abi = "ilp32f" +# riscv_cpu = "" +# riscv_float_abi = "hard" +# riscv_fpu = "" diff --git a/third_party/bouffalolab/bl602_sdk/bl602_sdk.gni b/third_party/bouffalolab/bl602_sdk/bl602_sdk.gni new file mode 100644 index 00000000000000..428a8439e3789e --- /dev/null +++ b/third_party/bouffalolab/bl602_sdk/bl602_sdk.gni @@ -0,0 +1,567 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/bl602_sdk.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/mbedtls.gni") + +import("bl602_board.gni") + +declare_args() { + # Location of the bl602 SDK. + bl602_sdk_root = "${chip_root}/third_party/bouffalolab/bl602_sdk/repo" +} + +assert(bl602_sdk_root != "", "bl602_sdk_root must be specified") + +# Defines an bl602 SDK build target. +# +# Parameters: +# bl602_sdk_root - The location of the bl602 SDK. +# sources - The sources files to build. +template("bl602_sdk") { + if (defined(invoker.bl602_sdk_root)) { + bl602_sdk_root = invoker.bl602_sdk_root + } + + assert(bl602_sdk_root != "", "bl602_sdk_root must be specified") + + sdk_target_name = target_name + + config("${sdk_target_name}_config") { + include_dirs = [] + libs = [] + if (defined(invoker.include_dirs)) { + include_dirs += invoker.include_dirs + } + + # Treat these includes as system includes, so warnings in them are not fatal. + _include_dirs = [ + "${bl602_sdk_root}", + "${bl602_sdk_root}/components/platform/soc/bl602/freertos_riscv_ram/config", + "${bl602_sdk_root}/components/platform/soc/bl602/freertos_riscv_ram/portable/GCC/RISC-V", + "${bl602_sdk_root}/components/platform/soc/bl602/freertos_riscv_ram/portable/GCC/RISC-V/chip_specific_extensions/RV32F_float_abi_single", + "${bl602_sdk_root}/components/platform/soc/bl602/freertos_riscv_ram/panic", + + "${bl602_sdk_root}/components/network/lwip/lwip-port/config", + "${bl602_sdk_root}/components/network/lwip/src/include", + "${bl602_sdk_root}/components/network/lwip/src/include/lwip", + "${bl602_sdk_root}/components/network/lwip/src/include/lwip/apps", + "${bl602_sdk_root}/components/network/lwip/lwip-port", + "${bl602_sdk_root}/components/network/lwip/lwip-port/FreeRTOS", + "${bl602_sdk_root}/components/network/lwip_mdns", + + # "${bl602_sdk_root}/components/network/lwip_dhcpd", + + "${bl602_sdk_root}/components/platform/hosal", + "${bl602_sdk_root}/components/platform/hosal/include", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal", + "${bl602_sdk_root}/components/utils/include", + "${bl602_sdk_root}/components/security/blcrypto_suite/priv_inc", + "${bl602_sdk_root}/components/security/blcrypto_suite/inc/blcrypto_suite", + + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Inc", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/Device/Bouffalo/BL602/Peripherals", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/RISCV/Device/Bouffalo/BL602/Startup", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/Common/platform_print", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/RISCV/Core/Include", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/Common/soft_crc", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/Common/partition", + + "${bl602_sdk_root}/components/sys/bltime/include", + + "${bl602_sdk_root}/components/stage/easyflash4/inc", + "${bl602_sdk_root}/components/sys/blmtd/include", + "${bl602_sdk_root}/components/stage/blfdt/inc", + + "${bl602_sdk_root}/components/stage/blog", + "${bl602_sdk_root}/components/stage/cli/cli/include", + "${bl602_sdk_root}/components/utils/include", + + "${chip_root}/third_party/mbedtls/repo/include", + + "${bl602_sdk_root}/components/sys/bloop/bloop/include", + "${bl602_sdk_root}/components/sys/bloop/loopset/include", + "${bl602_sdk_root}/components/sys/bloop/looprt/include", + + "${bl602_sdk_root}/components/fs/vfs/include", + "${bl602_sdk_root}/components/stage/yloop/include", + + "${bl602_sdk_root}/components/network/wifi/include", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal", + "${bl602_sdk_root}/components/stage/yloop/include/aos", + "${bl602_sdk_root}/components/stage/yloop/include/aos", + + "${bl602_sdk_root}/components/network/ble/blestack/src/common/include/zephyr", + "${bl602_sdk_root}/components/network/ble/blestack/src/port/include", + "${bl602_sdk_root}/components/network/ble/blestack/src/common/include", + "${bl602_sdk_root}/components/network/ble/blestack/src/include", + "${bl602_sdk_root}/components/network/ble/blestack/src/include/bluetooth", + "${bl602_sdk_root}/components/network/ble/blecontroller/ble_inc", + "${bl602_sdk_root}/components/network/ble/blestack/src/host", + "${bl602_sdk_root}/components/network/ble/blestack/src/include/drivers/bluetooth", + "${bl602_sdk_root}/components/network/ble/blestack/src/common/include/misc", + "${bl602_sdk_root}/components/network/ble/blestack/src/common", + "${bl602_sdk_root}/components/network/ble/blestack/src/bl_hci_wrapper", + "${bl602_sdk_root}/components/network/ble/blestack/src/common/tinycrypt/include/tinycrypt", + + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/include", + "${bl602_sdk_root}/components/network/dns_server/include", + + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Inc", + "${bl602_sdk_root}/components/security/blcrypto_suite/inc/blcrypto_suite", + "${bl602_sdk_root}/components/security/blcrypto_suite/priv_inc", + "${bl602_sdk_root}/components/network/wifi/modules/supplicant/src/sae", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/Common/platform_print", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/Common/ring_buffer", + "${bl602_sdk_root}/components/utils/include", + + "${bl602_sdk_root}/components/stage/cli/cli/include/", + "${bl602_sdk_root}/components/sys/blota/include", + "${bl602_sdk_root}/components/utils/include/", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Inc/", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/", + ] + + # if (bl602_board == "BL-HWC-G1") { + # _include_dirs += [ "${bl602_sdk_root}/hardware/board/config/bl_hwc_g1" ] + # } + + bl_sdk_ver = getenv("BL_SDK_VER") + defines = [ + "MBEDTLS_CONFIG_FILE=\"bl602-chip-mbedtls-config.h\"", + "__STARTUP_CLEAR_BSS", + "HARD_FAULT_LOG_ENABLE", + "RETARGET_VCOM", + "RETARGET_USART0", + "ARCH_RISCV", + "portasmHANDLE_INTERRUPT=interrupt_entry", + + "SYS_APP_TASK_STACK_SIZE=1024", + "SYS_APP_TASK_PRIORITY=28", + "BL_SDK_VER=\"$bl_sdk_ver\"", + + "SYS_BLOG_ENABLE=1", + "SYS_VFS_ENABLE=1", + "SYS_VFS_UART_ENABLE=1", + "SYS_AOS_LOOP_ENABLE=1", + "BL602=BL602", + "SYS_LOOPRT_ENABLE=1", + "CFG_TXDESC=2", + "CFG_STA_MAX=1", + + # "SYS_AOS_CLI_ENABLE=1", + + # set CONFIG_RENDEZVOUS_MODE to RENDEZVOUS_MODE_BLE (2) + "CONFIG_RENDEZVOUS_MODE=2", + + # bluetooth + "CONFIG_SET_TX_PWR", + "CFG_BLE_ENABLE", + "BFLB_BLE", + "CFG_BLE", + "CFG_SLEEP", + "OPTIMIZE_DATA_EVT_FLOW_FROM_CONTROLLER", + "CFG_BT_RESET", + "CFG_CON=1", + "CFG_BLE_TX_BUFF_DATA=2", + + # "CONFIG_BLE_TX_BUFF_DATA=2", + "CONFIG_BT_PERIPHERAL=1", + "CONFIG_BT_L2CAP_DYNAMIC_CHANNEL", + "CONFIG_BT_GATT_CLIENT", + "CONFIG_BT_CONN=1", + "CONFIG_BT_GATT_DIS_PNP", + "CONFIG_BT_GATT_DIS_SERIAL_NUMBER", + "CONFIG_BT_GATT_DIS_FW_REV", + "CONFIG_BT_GATT_DIS_HW_REV", + "CONFIG_BT_GATT_DIS_SW_REV", + "CONFIG_BT_ECC", + "CONFIG_BT_GATT_DYNAMIC_DB", + "CONFIG_BT_GATT_SERVICE_CHANGED", + "CONFIG_BT_KEYS_OVERWRITE_OLDEST", + "CONFIG_BT_KEYS_SAVE_AGING_COUNTER_ON_PAIRING", + "CONFIG_BT_GAP_PERIPHERAL_PREF_PARAMS", + "CONFIG_BT_BONDABLE", + "CONFIG_BT_HCI_VS_EVT_USER", + "CONFIG_BT_ASSERT", + "CONFIG_BT_SETTINGS_CCC_LAZY_LOADING", + "CONFIG_BT_SETTINGS_USE_PRINTK", + "CFG_BLE_STACK_DBG_PRINT", + + "CONFIG_ENABLE_PW_RPC=0", + "__FILENAME__=__FILE__", + "BL602_LOG_ENABLED=1", + + # "${bl602_mcu}=1", + # "${bl602_board}=1", + # "CHIP_KVS_SECTOR_COUNT=4", + # "CHIP_KVS_BASE_SECTOR_INDEX=((FLASH_SIZE/FLASH_PAGE_SIZE)-(CHIP_KVS_SECTOR_COUNT))", + "__HEAP_SIZE=0", + + #dump backtrace + "CONF_ENABLE_FRAME_PTR=1", + "CONF_ENABLE_FUNC_BACKTRACE_ELF=connectedhomeip/examples/lock-app/bl602/out/debug/chip-bl602-lock-example.out", + "CHIP_SYSTEM_HEADER_RESERVE_SIZE=134", + ] + + if (bl602_board == "BL-HWC-G1") { + defines += [ + "BL602_UART0_TX_GPIO=16", + "BL602_UART0_RX_GPIO=7", + ] + } else if (bl602_board == "3R-HWC-G1") { + defines += [ + "BL602_UART0_TX_GPIO=2", + "BL602_UART0_RX_GPIO=1", + ] + } + + defines += board_defines + + # if (bl_family == "bl602") { + # _include_dirs += [ + # "${efr32_sdk_root}/platform/Device/SiliconLabs/EFR32MG12P/Include", + # ] + # + # libs += [ + # "${efr32_sdk_root}/protocol/bluetooth/lib/EFR32MG12P/GCC/libbluetooth.a", + # ] + + # defines += [ "EFR32MG12" ] + # } + libs += [ + "${bl602_sdk_root}/components/network/wifi/lib/libwifi.a", + "${bl602_sdk_root}/components/network/ble/blecontroller/lib/libblecontroller.a", + ] + + cflags = [ + "-include", + rebase_path( + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/errno.h", + root_build_dir), + ] + + #cflags = ["-include", rebase_path("${bl602_sdk_root}/components/network/ble/blestack/src/common/include/errno.h", root_build_dir), ] + # for src/platform/bouffalolab/BL602/BLEManagerImpl.cpp + # TODO: 3R + #cflags += [ "-fpermissive" ] + + cflags += [ + "-Wno-maybe-uninitialized", + "-Wno-shadow", + "-Wno-error", + ] + + cflags_cc = [ "-fpermissive" ] + + foreach(include_dir, _include_dirs) { + cflags += [ "-isystem" + rebase_path(include_dir, root_build_dir) ] + } + + cflags += [ "-save-temps=obj" ] + cflags += [ "-Wno-maybe-uninitialized" ] + + if (defined(invoker.defines)) { + defines += invoker.defines + } + } + + source_set(sdk_target_name) { + sources = [ + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_boot2.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_flash.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_wdt.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/hosal_ota.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Src/bl602_mfg_flash.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Src/bl602_sf_cfg_ext.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Src/bl602_sflash_ext.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Src/bl602_timer.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Src/bl602_xip_sflash_ext.c", + "${bl602_sdk_root}/components/stage/cli/cli/cli.c", + "${bl602_sdk_root}/components/stage/easyflash4/src/easyflash.c", + "${bl602_sdk_root}/components/stage/easyflash4/src/ef_env.c", + "${bl602_sdk_root}/components/stage/easyflash4/src/ef_port.c", + "${bl602_sdk_root}/components/stage/easyflash4/src/ef_utils.c", + "${bl602_sdk_root}/components/sys/blmtd/bl_mtd.c", + "${bl602_sdk_root}/components/sys/blota/bl_sys_ota_cli.c", + "${bl602_sdk_root}/components/utils/src/utils_hexdump.c", + "${bl602_sdk_root}/components/utils/src/utils_sha256.c", + "${chip_root}/third_party/mbedtls/repo/library/aes.c", + "${chip_root}/third_party/mbedtls/repo/library/asn1parse.c", + "${chip_root}/third_party/mbedtls/repo/library/asn1write.c", + "${chip_root}/third_party/mbedtls/repo/library/bignum.c", + "${chip_root}/third_party/mbedtls/repo/library/ccm.c", + "${chip_root}/third_party/mbedtls/repo/library/cipher.c", + "${chip_root}/third_party/mbedtls/repo/library/cipher_wrap.c", + "${chip_root}/third_party/mbedtls/repo/library/ctr_drbg.c", + "${chip_root}/third_party/mbedtls/repo/library/ecdh.c", + "${chip_root}/third_party/mbedtls/repo/library/ecdsa.c", + "${chip_root}/third_party/mbedtls/repo/library/ecp.c", + "${chip_root}/third_party/mbedtls/repo/library/ecp_curves.c", + "${chip_root}/third_party/mbedtls/repo/library/entropy.c", + "${chip_root}/third_party/mbedtls/repo/library/hkdf.c", + "${chip_root}/third_party/mbedtls/repo/library/hmac_drbg.c", + "${chip_root}/third_party/mbedtls/repo/library/md.c", + "${chip_root}/third_party/mbedtls/repo/library/oid.c", + "${chip_root}/third_party/mbedtls/repo/library/pk.c", + "${chip_root}/third_party/mbedtls/repo/library/pk_wrap.c", + "${chip_root}/third_party/mbedtls/repo/library/pkcs5.c", + "${chip_root}/third_party/mbedtls/repo/library/pkwrite.c", + "${chip_root}/third_party/mbedtls/repo/library/platform.c", + "${chip_root}/third_party/mbedtls/repo/library/platform_util.c", + "${chip_root}/third_party/mbedtls/repo/library/sha256.c", + "${chip_root}/third_party/mbedtls/repo/library/sha512.c", + "${chip_root}/third_party/mbedtls/repo/library/x509_create.c", + "${chip_root}/third_party/mbedtls/repo/library/x509write_csr.c", + ] + + if (defined(enable_fem)) { + sources += [ + # "${efr32_sdk_root}/util/plugin/plugin-common/fem-control/fem-control.c", + ] + } + + if (defined(invoker.show_qr_code)) { + if (invoker.show_qr_code) { + sources += [ + # "${efr32_sdk_root}/hardware/kit/common/drivers/display.c", + ] + } + } + + # if (bl_family == "bl602") { + # sources += [ + # "${efr32_sdk_root}/platform/Device/SiliconLabs/EFR32MG12P/Source/system_efr32mg12p.c", + # ] + # } + + # if (bl_family == "bl602") { + sources += [ + "${bl602_sdk_root}/components/fs/vfs/device/vfs_uart.c", + "${bl602_sdk_root}/components/fs/vfs/src/vfs.c", + "${bl602_sdk_root}/components/fs/vfs/src/vfs_file.c", + "${bl602_sdk_root}/components/fs/vfs/src/vfs_inode.c", + "${bl602_sdk_root}/components/fs/vfs/src/vfs_register.c", + "${bl602_sdk_root}/components/libc/newlibc/stdatomic.c", + "${bl602_sdk_root}/components/libc/newlibc/syscalls.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/bl_hci_wrapper/bl_hci_wrapper.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/common/atomic_c.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/common/buf.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/common/dec.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/common/log.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/common/poll.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/common/work_q.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/hci_onchip/hci_driver.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/host/att.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/host/bl_host_assist.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/host/conn.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/host/crypto.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/host/gatt.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/host/hci_core.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/host/l2cap.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/host/settings.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/host/uuid.c", + "${bl602_sdk_root}/components/network/ble/blestack/src/port/bl_port.c", + "${bl602_sdk_root}/components/network/dns_server/src/dns_server.c", + "${bl602_sdk_root}/components/network/dns_server/src/web_server.c", + "${bl602_sdk_root}/components/network/lwip/lwip-port/FreeRTOS/ethernetif.c", + "${bl602_sdk_root}/components/network/lwip/lwip-port/FreeRTOS/sys_arch.c", + "${bl602_sdk_root}/components/network/lwip/src/api/api_lib.c", + "${bl602_sdk_root}/components/network/lwip/src/api/api_msg.c", + "${bl602_sdk_root}/components/network/lwip/src/api/err.c", + "${bl602_sdk_root}/components/network/lwip/src/api/if_api.c", + "${bl602_sdk_root}/components/network/lwip/src/api/netbuf.c", + "${bl602_sdk_root}/components/network/lwip/src/api/netdb.c", + "${bl602_sdk_root}/components/network/lwip/src/api/netifapi.c", + "${bl602_sdk_root}/components/network/lwip/src/api/sockets.c", + "${bl602_sdk_root}/components/network/lwip/src/api/tcpip.c", + "${bl602_sdk_root}/components/network/lwip/src/apps/altcp_tls/altcp_tls_mbedtls.c", + "${bl602_sdk_root}/components/network/lwip/src/apps/altcp_tls/altcp_tls_mbedtls_mem.c", + "${bl602_sdk_root}/components/network/lwip/src/core/altcp.c", + "${bl602_sdk_root}/components/network/lwip/src/core/altcp_alloc.c", + "${bl602_sdk_root}/components/network/lwip/src/core/altcp_tcp.c", + "${bl602_sdk_root}/components/network/lwip/src/core/def.c", + "${bl602_sdk_root}/components/network/lwip/src/core/dns.c", + "${bl602_sdk_root}/components/network/lwip/src/core/inet_chksum.c", + "${bl602_sdk_root}/components/network/lwip/src/core/init.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ip.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ipv4/autoip.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ipv4/dhcp.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ipv4/etharp.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ipv4/icmp.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ipv4/igmp.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ipv4/ip4.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ipv4/ip4_addr.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ipv4/ip4_frag.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ipv6/dhcp6.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ipv6/ethip6.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ipv6/icmp6.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ipv6/inet6.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ipv6/ip6.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ipv6/ip6_addr.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ipv6/ip6_frag.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ipv6/mld6.c", + "${bl602_sdk_root}/components/network/lwip/src/core/ipv6/nd6.c", + "${bl602_sdk_root}/components/network/lwip/src/core/mem.c", + "${bl602_sdk_root}/components/network/lwip/src/core/memp.c", + "${bl602_sdk_root}/components/network/lwip/src/core/netif.c", + "${bl602_sdk_root}/components/network/lwip/src/core/pbuf.c", + "${bl602_sdk_root}/components/network/lwip/src/core/raw.c", + "${bl602_sdk_root}/components/network/lwip/src/core/stats.c", + "${bl602_sdk_root}/components/network/lwip/src/core/sys.c", + "${bl602_sdk_root}/components/network/lwip/src/core/tcp.c", + "${bl602_sdk_root}/components/network/lwip/src/core/tcp_in.c", + "${bl602_sdk_root}/components/network/lwip/src/core/tcp_out.c", + "${bl602_sdk_root}/components/network/lwip/src/core/timeouts.c", + "${bl602_sdk_root}/components/network/lwip/src/core/udp.c", + "${bl602_sdk_root}/components/network/lwip/src/core/utils.c", + "${bl602_sdk_root}/components/network/lwip/src/netif/bridgeif.c", + "${bl602_sdk_root}/components/network/lwip/src/netif/bridgeif_fdb.c", + "${bl602_sdk_root}/components/network/lwip/src/netif/ethernet.c", + "${bl602_sdk_root}/components/network/lwip/src/netif/lowpan6.c", + "${bl602_sdk_root}/components/network/lwip/src/netif/lowpan6_ble.c", + "${bl602_sdk_root}/components/network/lwip/src/netif/lowpan6_common.c", + "${bl602_sdk_root}/components/network/lwip/src/netif/slipif.c", + "${bl602_sdk_root}/components/network/lwip/src/netif/zepif.c", + "${bl602_sdk_root}/components/network/lwip_dhcpd/dhcp_server_raw.c", + "${bl602_sdk_root}/components/network/lwip_mdns/mdns_server.c", + "${bl602_sdk_root}/components/network/sntp/sntp.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/bl_cmds.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/bl_irqs.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/bl_main.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/bl_mod_params.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/bl_msg_rx.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/bl_msg_tx.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/bl_platform.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/bl_rx.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/bl_tx.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/bl_utils.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/ipc_host.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/os_hal.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/stateMachine.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/wifi.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/wifi_mgmr.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/wifi_mgmr_api.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/wifi_mgmr_cli.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/wifi_mgmr_event.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/wifi_mgmr_ext.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/wifi_mgmr_profile.c", + "${bl602_sdk_root}/components/network/wifi_manager/bl60x_wifi_driver/wifi_netif.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_chip.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_dma.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_efuse.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_gpio.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_hbn.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_irq.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_pds.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_pm.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_pwm.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_rtc.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_sec.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_sec_sha.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_sys.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_timer.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_uart.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/bl_wifi.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/hal_board.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/hal_boot2.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/hal_button.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/hal_gpio.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/hal_hbn.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/hal_sys.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/hal_wifi.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/hosal_dma.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/hosal_pwm.c", + "${bl602_sdk_root}/components/platform/hosal/bl602_hal/hosal_uart.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602/bfl_main.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602/evb/src/boot/gcc/start.S", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602/evb/src/debug.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602/evb/src/strntoumax.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/Common/platform_print/platform_device.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Src/bl602_dma.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Src/bl602_ef_ctrl.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Src/bl602_glb.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Src/bl602_hbn.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Src/bl602_mfg_efuse.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Src/bl602_mfg_media.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Src/bl602_pwm.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Src/bl602_romapi.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Src/bl602_sec_eng.c", + "${bl602_sdk_root}/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Src/bl602_uart.c", + "${bl602_sdk_root}/components/platform/soc/bl602/freertos_riscv_ram/event_groups.c", + "${bl602_sdk_root}/components/platform/soc/bl602/freertos_riscv_ram/list.c", + "${bl602_sdk_root}/components/platform/soc/bl602/freertos_riscv_ram/misaligned/fp_asm.S", + "${bl602_sdk_root}/components/platform/soc/bl602/freertos_riscv_ram/misaligned/misaligned_ldst.c", + "${bl602_sdk_root}/components/platform/soc/bl602/freertos_riscv_ram/panic/panic_c.c", + "${bl602_sdk_root}/components/platform/soc/bl602/freertos_riscv_ram/portable/GCC/RISC-V/port.c", + "${bl602_sdk_root}/components/platform/soc/bl602/freertos_riscv_ram/portable/GCC/RISC-V/portASM.S", + "${bl602_sdk_root}/components/platform/soc/bl602/freertos_riscv_ram/portable/MemMang/heap_5.c", + "${bl602_sdk_root}/components/platform/soc/bl602/freertos_riscv_ram/queue.c", + "${bl602_sdk_root}/components/platform/soc/bl602/freertos_riscv_ram/stream_buffer.c", + "${bl602_sdk_root}/components/platform/soc/bl602/freertos_riscv_ram/tasks.c", + "${bl602_sdk_root}/components/platform/soc/bl602/freertos_riscv_ram/timers.c", + "${bl602_sdk_root}/components/security/blcrypto_suite/src/blcrypto_suite_aes.c", + "${bl602_sdk_root}/components/security/blcrypto_suite/src/blcrypto_suite_bignum.c", + "${bl602_sdk_root}/components/security/blcrypto_suite/src/blcrypto_suite_ecp.c", + "${bl602_sdk_root}/components/security/blcrypto_suite/src/blcrypto_suite_ecp_curves.c", + "${bl602_sdk_root}/components/security/blcrypto_suite/src/blcrypto_suite_export_fw.c", + "${bl602_sdk_root}/components/security/blcrypto_suite/src/blcrypto_suite_fw_api.c", + "${bl602_sdk_root}/components/security/blcrypto_suite/src/blcrypto_suite_hacc.c", + "${bl602_sdk_root}/components/security/blcrypto_suite/src/blcrypto_suite_hacc_glue.c", + "${bl602_sdk_root}/components/security/blcrypto_suite/src/blcrypto_suite_hacc_secp256r1_mul.c", + "${bl602_sdk_root}/components/security/blcrypto_suite/src/blcrypto_suite_platform_util.c", + "${bl602_sdk_root}/components/security/blcrypto_suite/src/blcrypto_suite_porting.c", + "${bl602_sdk_root}/components/stage/blfdt/src/fdt.c", + "${bl602_sdk_root}/components/stage/blfdt/src/fdt_ro.c", + "${bl602_sdk_root}/components/stage/blog/blog.c", + "${bl602_sdk_root}/components/stage/yloop/src/aos_freertos.c", + "${bl602_sdk_root}/components/stage/yloop/src/device.c", + "${bl602_sdk_root}/components/stage/yloop/src/local_event.c", + "${bl602_sdk_root}/components/stage/yloop/src/select.c", + "${bl602_sdk_root}/components/stage/yloop/src/yloop.c", + "${bl602_sdk_root}/components/sys/bloop/bloop/src/bloop_base.c", + "${bl602_sdk_root}/components/sys/bloop/bloop/src/bloop_handler_sys.c", + "${bl602_sdk_root}/components/sys/bloop/looprt/src/looprt.c", + "${bl602_sdk_root}/components/sys/bloop/loopset/src/loopset_led.c", + "${bl602_sdk_root}/components/sys/bltime/bl_sys_time.c", + "${bl602_sdk_root}/components/utils/src/utils_crc.c", + "${bl602_sdk_root}/components/utils/src/utils_dns.c", + "${bl602_sdk_root}/components/utils/src/utils_hmac_sha1_fast.c", + "${bl602_sdk_root}/components/utils/src/utils_list.c", + "${bl602_sdk_root}/components/utils/src/utils_log.c", + "${bl602_sdk_root}/components/utils/src/utils_notifier.c", + "${bl602_sdk_root}/components/utils/src/utils_psk_fast.c", + "${bl602_sdk_root}/components/utils/src/utils_rbtree.c", + "${bl602_sdk_root}/components/utils/src/utils_tlv_bl.c", + ] + + # } else if (bl_family == "bl706") { + # sources += [ + # ] + # } + + public_deps = [ + # "${segger_rtt_root}:segger_rtt", + # "${segger_rtt_root}:segger_rtt_printf", + # "${segger_rtt_root}:segger_rtt_syscalls", + ] + + if (defined(invoker.sources)) { + sources += invoker.sources + } + + public_configs = [ ":${sdk_target_name}_config" ] + } +} diff --git a/third_party/bouffalolab/bl602_sdk/repo b/third_party/bouffalolab/bl602_sdk/repo new file mode 160000 index 00000000000000..9b3e3f3e9cc193 --- /dev/null +++ b/third_party/bouffalolab/bl602_sdk/repo @@ -0,0 +1 @@ +Subproject commit 9b3e3f3e9cc1932e2334d755fde864459944e2f9