diff --git a/.github/workflows/examples-efr32.yaml b/.github/workflows/examples-efr32.yaml index 084226e14510a0..a80505fcfd8ab3 100644 --- a/.github/workflows/examples-efr32.yaml +++ b/.github/workflows/examples-efr32.yaml @@ -82,7 +82,11 @@ jobs: path: | .environment/gn_out/.ninja_log .environment/pigweed-venv/*.log - + - name: Test SLC gen + timeout-minutes: 30 + run: | + scripts/examples/gn_efr32_example.sh examples/lighting-app/silabs/efr32 ./out/light-app BRD4187C --slc_generate --docker + rm -rf ./out/ - name: Build some BRD4187C variants timeout-minutes: 90 run: | diff --git a/examples/lighting-app/silabs/efr32/BUILD.gn b/examples/lighting-app/silabs/efr32/BUILD.gn index c47228b35dc589..5656bbf53db9ab 100644 --- a/examples/lighting-app/silabs/efr32/BUILD.gn +++ b/examples/lighting-app/silabs/efr32/BUILD.gn @@ -46,6 +46,20 @@ declare_args() { chip_print_memory_usage = false } +if (slc_generate) { + # Generate Project Specific config (Board, hardware used etc..) + print(exec_script("${chip_root}/third_party/silabs/slc_gen/run_slc.py", + [ + rebase_path(chip_root), + "${silabs_board}", + "${disable_lcd}", + "${use_wstk_buttons}", + "${use_wstk_leds}", + "${use_external_flash}", + ], + "list lines")) +} + efr32_sdk("sdk") { sources = [ "${efr32_project_dir}/include/CHIPProjectConfig.h", diff --git a/examples/platform/silabs/gatt_configuration.btconf b/examples/platform/silabs/gatt_configuration.btconf new file mode 100644 index 00000000000000..4d1efd972514d5 --- /dev/null +++ b/examples/platform/silabs/gatt_configuration.btconf @@ -0,0 +1,99 @@ + + + + + + + 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. + Silicon Labs + + + + + + + + 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 + + + + + + + + + Custom service + + + + Custom characteristic + 00 + + + + + + + + + Custom characteristic + 00 + + + + + + + + + + Custom characteristic + 00 + + + + + + + + + + diff --git a/examples/platform/silabs/matter-platform.slcp b/examples/platform/silabs/matter-platform.slcp new file mode 100644 index 00000000000000..0eee476075016c --- /dev/null +++ b/examples/platform/silabs/matter-platform.slcp @@ -0,0 +1,90 @@ +# Silicon Labs Project Configuration Tools: slcp, v0, Component selection file. +project_name: matter-platform +label: matter-platform +description: | + This project contains the minimal requirements to generate the dependencies needed by all Matter examples +category: Matter Examples +filter: +- name: Capability + value: [Multiprotocol] +- name: Device Type + value: [SoC] +- name: Project Difficulty + value: [Advanced] +- name: Wireless Technology + value: [Bluetooth, Thread] +package: OpenThread +quality: production +readme: +- {path: README.md} +source: +- {path: main.c} +- {path: app.c} +- {path: bluetooth_event_callback.c} +tag: [prebuilt_demo] +include: +- path: '' + file_list: + - {path: app.h} + - {path: reset_util.h} +sdk: {id: gecko_sdk, version: 4.2.0} +toolchain_settings: [] + +component: +- {id: bluetooth_feature_nvm} +- {id: bluetooth_feature_gatt_server} +- {id: nvm3_lib} +- {id: bluetooth_feature_sm} +- {id: bluetooth_feature_gap} +- {id: bluetooth_feature_legacy_advertiser} +- {id: gatt_configuration} +- {id: freertos} +- {id: bluetooth_stack} +- {id: brd4002a} +- {id: rail_util_pti} +- {id: bluetooth_feature_gatt} +- {id: bluetooth_feature_connection} +- {id: psa_crypto} +- {id: rail_lib_multiprotocol} +- {id: bluetooth_feature_system} +- {id: bluetooth_feature_scanner} +- instance: [vcom] + id: uartdrv_usart +- instance: [vcom] + id: uartdrv_eusart + + +config_file: + - override: + component: gatt_configuration + file_id: gatt_configuration_file_id + path: gatt_configuration.btconf + directory: btconf + +configuration: +- {name: SL_BOARD_ENABLE_VCOM, value: '1'} +- {name: SL_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED, value: '1'} +- {name: SL_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED, value: '1'} +- condition: [uartdrv_usart] + name: UARTDRV_RESTRICT_ENERGY_MODE_TO_ALLOW_RECEPTION + value: '0' +- condition: [iostream_usart] + name: SL_IOSTREAM_USART_VCOM_RESTRICT_ENERGY_MODE_TO_ALLOW_RECEPTION + value: '0' +- condition: [iostream_usart] + name: SL_IOSTREAM_USART_VCOM_RX_BUFFER_SIZE + value: '128' +- {name: SL_HEAP_SIZE, value: '16384'} +- {name: SL_STACK_SIZE, value: '4608'} + +requires: +- condition: [device_series_1] + name: uartdrv_usart +- condition: [device_series_2] + name: uartdrv_eusart +- condition: [device_series_2] + name: device_init_dpll + +ui_hints: + highlight: + - {path: ./README.md, focus: true} diff --git a/scripts/examples/gn_efr32_example.sh b/scripts/examples/gn_efr32_example.sh index f02b39b3a405ca..2bf76edb93a3ea 100755 --- a/scripts/examples/gn_efr32_example.sh +++ b/scripts/examples/gn_efr32_example.sh @@ -28,13 +28,14 @@ else CHIP_ROOT="$MATTER_ROOT" fi -source "$CHIP_ROOT/scripts/activate.sh" - set -x env USE_WIFI=false USE_DOCKER=false USE_GIT_SHA_FOR_VERSION=true +USE_SLC=false +GN_PATH=gn +GN_PATH_PROVIDED=false SILABS_THREAD_TARGET=\""../silabs:ot-efr32-cert"\" USAGE="./scripts/examples/gn_efr32_example.sh []" @@ -125,6 +126,10 @@ if [ "$#" == "0" ]; then Change GSDK root for docker builds --uart_log Forward Logs to Uart instead of RTT + --slc_generate + Generate files with SLC for current board and options Requires an SLC-CLI installation or running in Docker. + --slc_reuse_files + Use generated files without running slc again. " elif [ "$#" -lt "2" ]; then @@ -214,12 +219,32 @@ else shift ;; + --slc_generate) + optArgs+="slc_generate=true " + USE_SLC=true + shift + ;; + --slc_reuse_files) + optArgs+="slc_reuse_files=true " + USE_SLC=true + shift + ;; + --gn_path) + if [ -z "$2" ]; then + echo "--gn_path requires a path to GN" + exit 1 + else + GN_PATH="$2" + fi + GN_PATH_PROVIDED=true + shift + shift + ;; *"sl_matter_version_str="*) optArgs+="$1 " USE_GIT_SHA_FOR_VERSION=false shift ;; - *) if [ "$1" =~ *"use_rs9116=true"* ] || [ "$1" =~ *"use_SiWx917=true"* ] || [ "$1" =~ *"use_wf200=true"* ]; then USE_WIFI=true @@ -243,6 +268,10 @@ else } &>/dev/null fi + if [ "$USE_SLC" == true ] && [ "$GN_PATH_PROVIDED" == false ]; then + GN_PATH=./.environment/cipd/packages/pigweed/gn + fi + BUILD_DIR=$OUTDIR/$SILABS_BOARD echo BUILD_DIR="$BUILD_DIR" @@ -254,7 +283,7 @@ else # wifi build # NCP mode EFR32 + wifi module optArgs+="$ipArgs" - gn gen --check --fail-on-unused-args --export-compile-commands --root="$ROOT" --dotfile="$ROOT"/build_for_wifi_gnfile.gn --args="silabs_board=\"$SILABS_BOARD\" $optArgs" "$BUILD_DIR" + "$GN_PATH" gen --check --fail-on-unused-args --export-compile-commands --root="$ROOT" --dotfile="$ROOT"/build_for_wifi_gnfile.gn --args="silabs_board=\"$SILABS_BOARD\" $optArgs" "$BUILD_DIR" else # OpenThread/SoC build # @@ -263,11 +292,16 @@ else fi if [ -z "$optArgs" ]; then - gn gen --check --fail-on-unused-args --export-compile-commands --root="$ROOT" --args="silabs_board=\"$SILABS_BOARD\"" "$BUILD_DIR" + "$GN_PATH" gen --check --script-executable="/usr/bin/python3" --root="$ROOT" --args="silabs_board=\"$SILABS_BOARD\"" "$BUILD_DIR" else - gn gen --check --fail-on-unused-args --export-compile-commands --root="$ROOT" --args="silabs_board=\"$SILABS_BOARD\" $optArgs" "$BUILD_DIR" + "$GN_PATH" gen --check --script-executable="/usr/bin/python3" --root="$ROOT" --args="silabs_board=\"$SILABS_BOARD\" $optArgs" "$BUILD_DIR" fi fi + + # Activation needs to be after SLC generation which is done in gn gen. + # Zap generation requires activation and is done in the build phase + source "$CHIP_ROOT/scripts/activate.sh" + ninja -v -C "$BUILD_DIR"/ #print stats arm-none-eabi-size -A "$BUILD_DIR"/*.out diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index 5ba8df783142da..8803d087df4558 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -55,6 +55,13 @@ declare_args() { # Argument to enable IPv4 for wifi # aligning to match chip_inet_config_enable_ipv4 default configuration chip_enable_wifi_ipv4 = false + silabs_gen_folder = "" + + # Calls SLC-CLI at run time + slc_generate = false + + # Use SLC generated files + slc_reuse_files = false } assert(efr32_sdk_root != "", "efr32_sdk_root must be specified") @@ -66,6 +73,14 @@ declare_args() { sl_openthread_root = "${efr32_sdk_root}/util/third_party/openthread" } +if (slc_generate || slc_reuse_files) { + silabs_gen_folder = "${chip_root}/third_party/silabs/slc_gen/${silabs_board}/" +} else { + print("Using pre-generate files") + silabs_gen_folder = + "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/" +} + # Defines an efr32 SDK build target. # # Parameters: @@ -156,10 +171,16 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/security/sl_component/se_manager/src/", "${efr32_sdk_root}/util/third_party/freertos/cmsis/Include", "${efr32_sdk_root}/util/third_party/freertos/kernel/include", - "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/config", - "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen", + "${efr32_sdk_root}/platform/driver/debug/inc", + "${silabs_gen_folder}/config", + "${silabs_gen_folder}/autogen", ] + if (slc_generate || slc_reuse_files) { + _include_dirs += + [ "${efr32_sdk_root}/hardware/driver/configuration_over_swo/inc/" ] + } + if (silabs_family != "mgm24") { _include_dirs += [ "${efr32_sdk_root}/platform/radio/rail_lib/hal", @@ -296,7 +317,6 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/radio/rail_lib/plugin/fem_util/", "${efr32_sdk_root}/platform/radio/rail_lib/plugin/rail_util_rssi/", "${efr32_sdk_root}/platform/driver/debug/inc/", - "${efr32_sdk_root}/hardware/driver/configuration_over_swo/inc/", ] } @@ -672,11 +692,11 @@ template("efr32_sdk") { "${efr32_sdk_root}/util/third_party/mbedtls/library/x509_csr.c", "${efr32_sdk_root}/util/third_party/mbedtls/library/x509write_crt.c", "${efr32_sdk_root}/util/third_party/mbedtls/library/x509write_csr.c", - "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/gatt_db.c", - "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_bluetooth.c", - "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_board_default_init.c", - "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_device_init_clocks.c", - "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_event_handler.c", + "${silabs_gen_folder}/autogen/gatt_db.c", + "${silabs_gen_folder}/autogen/sl_bluetooth.c", + "${silabs_gen_folder}/autogen/sl_board_default_init.c", + "${silabs_gen_folder}/autogen/sl_device_init_clocks.c", + "${silabs_gen_folder}/autogen/sl_event_handler.c", ] if (enable_dic) { sources += [ @@ -684,6 +704,14 @@ template("efr32_sdk") { "${efr32_sdk_root}/util/third_party/mbedtls/library/rsa_alt_helpers.c", ] } + + if (slc_generate || slc_reuse_files) { + sources += [ + "${efr32_sdk_root}/hardware/driver/configuration_over_swo/src/sl_cos.c", + "${efr32_sdk_root}/platform/driver/debug/src/sl_debug_swo.c", + ] + } + if (silabs_family != "mgm24") { sources += [ "${efr32_sdk_root}/platform/radio/rail_lib/hal/efr32/hal_efr.c" ] @@ -693,7 +721,7 @@ template("efr32_sdk") { sources += [ "${efr32_sdk_root}/platform/driver/button/src/sl_button.c", "${efr32_sdk_root}/platform/driver/button/src/sl_simple_button.c", - "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_simple_button_instances.c", + "${silabs_gen_folder}/autogen/sl_simple_button_instances.c", ] } @@ -728,7 +756,7 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/driver/leddrv/src/sl_pwm_led.c", "${efr32_sdk_root}/platform/driver/leddrv/src/sl_simple_led.c", "${efr32_sdk_root}/platform/driver/leddrv/src/sl_simple_rgb_pwm_led.c", - "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_simple_led_instances.c", + "${silabs_gen_folder}/autogen/sl_simple_led_instances.c", ] } @@ -736,7 +764,7 @@ template("efr32_sdk") { if (defined(invoker.chip_enable_wifi) && invoker.chip_enable_wifi) { sources += [ "${efr32_sdk_root}/platform/emdrv/spidrv/src/spidrv.c", - "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_spidrv_init.c", + "${silabs_gen_folder}/autogen/sl_spidrv_init.c", ] } @@ -761,7 +789,7 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/emlib/src/em_eusart.c", "${efr32_sdk_root}/platform/emlib/src/em_leuart.c", "${efr32_sdk_root}/platform/emlib/src/em_usart.c", - "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_uartdrv_init.c", + "${silabs_gen_folder}/autogen/sl_uartdrv_init.c", ] if (use_external_flash) { @@ -933,8 +961,6 @@ template("efr32_sdk") { if (silabs_board == "BRD2704A" || silabs_board == "BRD4318A") { sources += [ - "${efr32_sdk_root}/hardware/driver/configuration_over_swo/src/sl_cos.c", - "${efr32_sdk_root}/platform/driver/debug/src/sl_debug_swo.c", "${efr32_sdk_root}/platform/radio/rail_lib/plugin/fem_util/sl_fem_util.c", "${efr32_sdk_root}/platform/radio/rail_lib/plugin/rail_util_rssi/sl_rail_util_rssi.c", ] diff --git a/third_party/silabs/slc_gen/buildgn_template.txt b/third_party/silabs/slc_gen/buildgn_template.txt new file mode 100644 index 00000000000000..b68e497f6522fe --- /dev/null +++ b/third_party/silabs/slc_gen/buildgn_template.txt @@ -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/chip.gni") + +source_set("board_setup") { + include_dirs = [ + "autogen/", + "config/" + ] + + sources = [ + //REPLACE_ME + ] + +} diff --git a/third_party/silabs/slc_gen/run_slc.py b/third_party/silabs/slc_gen/run_slc.py new file mode 100644 index 00000000000000..5083948e3e7eb1 --- /dev/null +++ b/third_party/silabs/slc_gen/run_slc.py @@ -0,0 +1,78 @@ +# Importing required module +import glob +import os +import subprocess +import sys + +if len(sys.argv) != 7: + print("wrong number of arguments") + sys.exit(1) + + +def asBoolean(valueToTest): + return ("true" == valueToTest) + + +root_path = sys.argv[1] +silabs_board = str(sys.argv[2]).lower() +disable_lcd = asBoolean(sys.argv[3]) +use_wstk_buttons = asBoolean(sys.argv[4]) +use_wstk_leds = asBoolean(sys.argv[5]) +use_external_flash = asBoolean(sys.argv[6]) + +slcp_file_path = os.path.join(root_path, "examples/platform/silabs/matter-platform.slcp") +template_path = os.path.join(root_path, "third_party/silabs/slc_gen/") +output_path = template_path + sys.argv[2] + '/' + +slc_arguments = "" + +# Translate GN arguments in SLC arguments +if not disable_lcd: + slc_arguments += "memlcd_usart,dmd_memlcd," +if use_wstk_buttons: + slc_arguments += "simple_button:btn0:btn1," +if use_wstk_leds: + # Sparkfun board + if silabs_board == "brd2704a": + slc_arguments += "simple_led:led0," + else: + slc_arguments += "simple_led:led0:led1," +if use_external_flash: + slc_arguments += "mx25_flash_shutdown_usart," + +slc_arguments += silabs_board + +print(slc_arguments) + +subprocess.run(["slc", "generate", slcp_file_path, "-d", output_path, "--with", slc_arguments], check=True) + +# cleanup of unwanted files +fileList = glob.glob(os.path.join(output_path, "matter-platform.*")) +for filePath in fileList: + try: + os.remove(filePath) + except OSError: + print("failed to remove file: {}".format(filePath)) + +try: + os.remove(os.path.join(output_path, "vscode.conf")) +except OSError: + print("failed to remove file: {}".format(filePath)) + + +# Create a Build.gn files with all of the sources +source_file_path = " \"autogen/{fileName}\",\r\n" + +template = open(os.path.join(template_path, "buildgn_template.txt"), "r") +final = open(os.path.join(output_path, "BUILD.gn"), "w") +for line in template: + if "//REPLACE_ME" in line: + for file in os.listdir(os.path.join(output_path, 'autogen/')): + if file.endswith(".c"): + # print path name of selected files + final.write(source_file_path.format(fileName=file)) + else: + final.write(line) + +template.close() +final.close()