From d9b2565f1ad22583b28ef76ce30fe1e4b17c4ba3 Mon Sep 17 00:00:00 2001 From: Tibor Laczko Date: Thu, 19 Sep 2024 13:27:08 +0200 Subject: [PATCH] drivers: bluetooth: siwx917: Add Bluetooth HCI driver Driver was tested with a custom application which enabled the BT_SHELL. Basic functionalities were verified: - Scanning - Advertising - Connecting Configuration needed for the test: - CONFIG_BT=y - CONFIG_BT_PERIPHERAL=y - CONFIG_BT_CENTRAL=y - CONFIG_SHELL=y - CONFIG_BT_SHELL=y Signed-off-by: Tibor Laczko --- .github/workflows/build.yml | 1 + .github/workflows/upstream-build.yml | 1 + .../siwx917_rb4338a/siwx917_rb4338a.dts | 5 + .../siwx917_rb4338a/siwx917_rb4338a.yaml | 1 + drivers/CMakeLists.txt | 1 + drivers/bluetooth/CMakeLists.txt | 4 + drivers/bluetooth/Kconfig | 8 + drivers/bluetooth/hci/CMakeLists.txt | 4 + drivers/bluetooth/hci/Kconfig.siwx917 | 37 ++++ drivers/bluetooth/hci/siwx917_hci.c | 167 ++++++++++++++++++ dts/arm/silabs/siwg917.dtsi | 5 + .../bluetooth/silabs,siwx917-bt-hci.yaml | 13 ++ west.yml | 2 +- 13 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 drivers/bluetooth/CMakeLists.txt create mode 100644 drivers/bluetooth/Kconfig create mode 100644 drivers/bluetooth/hci/CMakeLists.txt create mode 100644 drivers/bluetooth/hci/Kconfig.siwx917 create mode 100644 drivers/bluetooth/hci/siwx917_hci.c create mode 100644 dts/bindings/bluetooth/silabs,siwx917-bt-hci.yaml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3fe9c14..0dc5bb9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,3 +45,4 @@ jobs: fi west twister --test sample.basic.helloworld -p siwx917_rb4338a -v --inline-logs $EXTRA_TWISTER_FLAGS west twister --test sample.net.wifi -p siwx917_rb4338a -v --inline-logs $EXTRA_TWISTER_FLAGS + west twister --test sample.bluetooth.peripheral_hr -p siwx917_rb4338a -v --inline-logs -K $EXTRA_TWISTER_FLAGS diff --git a/.github/workflows/upstream-build.yml b/.github/workflows/upstream-build.yml index fb49d13..dbaceb8 100644 --- a/.github/workflows/upstream-build.yml +++ b/.github/workflows/upstream-build.yml @@ -58,3 +58,4 @@ jobs: fi west twister -T ../zephyr/samples -s sample.basic.helloworld -p siwx917_rb4338a -v --inline-logs $EXTRA_TWISTER_FLAGS west twister -T ../zephyr/samples -s sample.net.wifi -p siwx917_rb4338a -v --inline-logs $EXTRA_TWISTER_FLAGS + west twister -T ../zephyr/samples -s sample.bluetooth.peripheral_hr -p siwx917_rb4338a -v --inline-logs -K $EXTRA_TWISTER_FLAGS diff --git a/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.dts b/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.dts index b50d750..5b24c5f 100644 --- a/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.dts +++ b/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.dts @@ -20,6 +20,7 @@ zephyr,flash = &flash0; zephyr,console = &ulpuart0; zephyr,shell-uart = &ulpuart0; + zephyr,bt-hci = &bt_hci_silabs_siwx917; }; aliases { @@ -58,6 +59,10 @@ status = "okay"; }; +&bt_hci_silabs_siwx917 { + status = "okay"; +}; + &ulpuart0 { status = "okay"; pinctrl-0 = <&ulpuart0_default>; diff --git a/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.yaml b/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.yaml index 45ea1e5..d589c17 100644 --- a/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.yaml +++ b/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.yaml @@ -11,4 +11,5 @@ toolchain: supported: - gpio - i2c + - bluetooth vendor: silabs diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index 90b743b..1e2076c 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -1,6 +1,7 @@ # Copyright (c) 2024 Silicon Laboratories Inc. # SPDX-License-Identifier: Apache-2.0 +add_subdirectory(bluetooth) add_subdirectory(gpio) add_subdirectory(pinctrl) add_subdirectory(wifi) diff --git a/drivers/bluetooth/CMakeLists.txt b/drivers/bluetooth/CMakeLists.txt new file mode 100644 index 0000000..054016a --- /dev/null +++ b/drivers/bluetooth/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(hci) diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig new file mode 100644 index 0000000..fa0e433 --- /dev/null +++ b/drivers/bluetooth/Kconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +if BT_HCI + +rsource "hci/Kconfig.siwx917" + +endif diff --git a/drivers/bluetooth/hci/CMakeLists.txt b/drivers/bluetooth/hci/CMakeLists.txt new file mode 100644 index 0000000..5f5ff38 --- /dev/null +++ b/drivers/bluetooth/hci/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library_sources_ifdef(CONFIG_BT_SIWX917 siwx917_hci.c) diff --git a/drivers/bluetooth/hci/Kconfig.siwx917 b/drivers/bluetooth/hci/Kconfig.siwx917 new file mode 100644 index 0000000..72317f6 --- /dev/null +++ b/drivers/bluetooth/hci/Kconfig.siwx917 @@ -0,0 +1,37 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BT_SIWX917 + bool "Silabs SiWx917 Bluetooth interface" + default y + depends on DT_HAS_SILABS_SIWX917_BT_HCI_ENABLED + select CMSIS_RTOS_V2 + select POLL + select DYNAMIC_THREAD + select THREAD_NAME + select THREAD_STACK_INFO + select THREAD_MONITOR + select INIT_STACKS + help + Use Silicon Labs Wiseconnect 3.x Bluetooth library to connect to the controller. + +if BT_SIWX917 + +# WiseConnect create threads with realtime priority. Default (10kHz) clock tick +# prevent proper use of the system with these threads. +config SYS_CLOCK_TICKS_PER_SEC + default 1024 + +config NUM_PREEMPT_PRIORITIES + default 56 + +config CMSIS_V2_THREAD_DYNAMIC_MAX_COUNT + default 2 + +config CMSIS_V2_THREAD_DYNAMIC_STACK_SIZE + default 1024 + +config CMSIS_V2_THREAD_MAX_STACK_SIZE + default 2048 + +endif #BT_SIWX917 \ No newline at end of file diff --git a/drivers/bluetooth/hci/siwx917_hci.c b/drivers/bluetooth/hci/siwx917_hci.c new file mode 100644 index 0000000..be74f20 --- /dev/null +++ b/drivers/bluetooth/hci/siwx917_hci.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define DT_DRV_COMPAT silabs_siwx917_bt_hci +#define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL +#include +LOG_MODULE_REGISTER(bt_hci_driver_siwg917); + +#include "sl_wifi.h" +#include "sl_wifi_callback_framework.h" +#include "rsi_ble_common_config.h" +#include "rsi_ble.h" + +static void bt_siwg917_resp_rcvd(uint16_t status, rsi_ble_event_rcp_rcvd_info_t *resp_buf); + +struct hci_data { + bt_hci_recv_t recv; + rsi_data_packet_t rsi_data_packet; +}; + +static const sl_wifi_device_configuration_t network_config = { + .boot_option = LOAD_NWP_FW, + .mac_address = NULL, + .band = SL_SI91X_WIFI_BAND_2_4GHZ, + .region_code = DEFAULT_REGION, + .boot_config = { + .oper_mode = SL_SI91X_CLIENT_MODE, + .coex_mode = SL_SI91X_BLE_MODE, + .feature_bit_map = + SL_SI91X_FEAT_SECURITY_OPEN | + SL_SI91X_FEAT_WPS_DISABLE, + .tcp_ip_feature_bit_map = + SL_SI91X_TCP_IP_FEAT_DHCPV4_CLIENT | + SL_SI91X_TCP_IP_FEAT_EXTENSION_VALID, + .ext_tcp_ip_feature_bit_map = SL_SI91X_CONFIG_FEAT_EXTENSION_VALID, + .custom_feature_bit_map = SL_SI91X_CUSTOM_FEAT_EXTENSION_VALID, + .ext_custom_feature_bit_map = + MEMORY_CONFIG | + SL_SI91X_EXT_FEAT_XTAL_CLK | + SL_SI91X_EXT_FEAT_FRONT_END_SWITCH_PINS_ULP_GPIO_4_5_0 | + SL_SI91X_EXT_FEAT_BT_CUSTOM_FEAT_ENABLE, + .config_feature_bit_map = SL_SI91X_ENABLE_ENHANCED_MAX_PSP, + .bt_feature_bit_map = + SL_SI91X_BT_RF_TYPE | + SL_SI91X_ENABLE_BLE_PROTOCOL, + .ble_feature_bit_map = + SL_SI91X_BLE_MAX_NBR_PERIPHERALS(RSI_BLE_MAX_NBR_PERIPHERALS) | + SL_SI91X_BLE_MAX_NBR_CENTRALS(RSI_BLE_MAX_NBR_CENTRALS) | + SL_SI91X_BLE_MAX_NBR_ATT_SERV(RSI_BLE_MAX_NBR_ATT_SERV) | + SL_SI91X_BLE_MAX_NBR_ATT_REC(RSI_BLE_MAX_NBR_ATT_REC) | + SL_SI91X_BLE_PWR_INX(RSI_BLE_PWR_INX) | + SL_SI91X_BLE_PWR_SAVE_OPTIONS(RSI_BLE_PWR_SAVE_OPTIONS) | + SL_SI91X_916_BLE_COMPATIBLE_FEAT_ENABLE | + SL_SI91X_FEAT_BLE_CUSTOM_FEAT_EXTENSION_VALID, + .ble_ext_feature_bit_map = + SL_SI91X_BLE_NUM_CONN_EVENTS(RSI_BLE_NUM_CONN_EVENTS) | + SL_SI91X_BLE_NUM_REC_BYTES(RSI_BLE_NUM_REC_BYTES) | + SL_SI91X_BLE_ENABLE_ADV_EXTN | + SL_SI91X_BLE_AE_MAX_ADV_SETS(RSI_BLE_AE_MAX_ADV_SETS), + }}; + +static int bt_siwg917_open(const struct device *dev, bt_hci_recv_t recv) +{ + struct hci_data *hci = dev->data; + + int status = sl_wifi_init(&network_config, NULL, sl_wifi_default_event_handler); + status |= rsi_ble_enhanced_gap_extended_register_callbacks(RSI_BLE_ON_RCP_EVENT, + (void *)bt_siwg917_resp_rcvd); + + if (!status) { + hci->recv = recv; + } + return status ? -EIO : 0; +} + +static int bt_siwg917_send(const struct device *dev, struct net_buf *buf) +{ + struct hci_data *hci = dev->data; + int sc = -EOVERFLOW; + uint8_t packet_type = BT_HCI_H4_NONE; + + switch (bt_buf_get_type(buf)) { + case BT_BUF_ACL_OUT: + packet_type = BT_HCI_H4_ACL; + break; + case BT_BUF_CMD: + packet_type = BT_HCI_H4_CMD; + break; + default: + sc = -EINVAL; + break; + } + + if ((packet_type != BT_HCI_H4_NONE) && (buf->len < sizeof(hci->rsi_data_packet.data))) { + net_buf_push_u8(buf, packet_type); + memcpy(&hci->rsi_data_packet, buf->data, buf->len); + sc = rsi_bt_driver_send_cmd(RSI_BLE_REQ_HCI_RAW, &hci->rsi_data_packet, NULL); + /* TODO SILABS ZEPHYR Convert to errno. A common function from rsi/sl_status should + * be introduced + */ + if (sc) { + LOG_ERR("BT command send failure: %d", sc); + sc = -EIO; + } + } + net_buf_unref(buf); + return sc; +} + +static void bt_siwg917_resp_rcvd(uint16_t status, rsi_ble_event_rcp_rcvd_info_t *resp_buf) +{ + const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0)); + struct hci_data *hci = dev->data; + uint8_t packet_type = BT_HCI_H4_NONE; + size_t len = 0; + struct net_buf *buf = NULL; + + /* TODO SILABS ZEPHYR This horror expression is from the WiseConnect from the HCI example... + * No workaround have been found until now. + */ + memcpy(&packet_type, (resp_buf->data - 12), 1); + switch (packet_type) { + case BT_HCI_H4_EVT: { + struct bt_hci_evt_hdr *hdr = (void *)resp_buf->data; + + len = hdr->len + sizeof(*hdr); + buf = bt_buf_get_evt(hdr->evt, false, K_FOREVER); + break; + } + case BT_HCI_H4_ACL: { + struct bt_hci_acl_hdr *hdr = (void *)resp_buf->data; + + len = hdr->len + sizeof(*hdr); + buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER); + break; + } + default: + LOG_ERR("Unknown/Unhandled HCI type: %d", packet_type); + break; + } + + if (buf && (len <= net_buf_tailroom(buf))) { + net_buf_add_mem(buf, resp_buf->data, len); + hci->recv(dev, buf); + } +} + +static const struct bt_hci_driver_api drv = { + .open = bt_siwg917_open, + .send = bt_siwg917_send, +}; + +#define HCI_DEVICE_INIT(inst) \ + static struct hci_data hci_data_##inst; \ + DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &hci_data_##inst, NULL, POST_KERNEL, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv) + +/* Only one instance supported right now */ +HCI_DEVICE_INIT(0) + +/* IRQn 74 is used for communication with co-processor */ +Z_ISR_DECLARE(74, ISR_FLAG_DIRECT, IRQ074_Handler, 0); diff --git a/dts/arm/silabs/siwg917.dtsi b/dts/arm/silabs/siwg917.dtsi index f07a943..c8e26b2 100644 --- a/dts/arm/silabs/siwg917.dtsi +++ b/dts/arm/silabs/siwg917.dtsi @@ -24,6 +24,11 @@ reg = <0x00000000 DT_SIZE_K(191)>; }; + bt_hci_silabs_siwx917: bt_hci_silabs_siwx917 { + compatible = "silabs,siwx917-bt-hci"; + status = "disabled"; + }; + flash0: flash@8202000 { compatible = "soc-nv-flash"; reg = <0x8202000 DT_SIZE_K(2040)>; diff --git a/dts/bindings/bluetooth/silabs,siwx917-bt-hci.yaml b/dts/bindings/bluetooth/silabs,siwx917-bt-hci.yaml new file mode 100644 index 0000000..ab23280 --- /dev/null +++ b/dts/bindings/bluetooth/silabs,siwx917-bt-hci.yaml @@ -0,0 +1,13 @@ +description: Bluetooth HCI on Silabs boards + +compatible: "silabs,siwx917-bt-hci" + +include: bt-hci.yaml + +properties: + bt-hci-name: + default: "sl:siwx917:bt" + bt-hci-bus: + default: "BT_HCI_BUS_VIRTUAL" + bt-hci-quirks: + default: ["BT_HCI_QUIRK_NO_RESET"] diff --git a/west.yml b/west.yml index 09157ef..5e3b6aa 100644 --- a/west.yml +++ b/west.yml @@ -11,7 +11,7 @@ manifest: projects: - name: hal_silabs remote: silabs - revision: 3febda5e93f51324961a7e374321d10d6b2688f3 + revision: pull/6/head path: modules/hal/silabs - name: zephyr remote: zephyrproject-rtos