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()