Skip to content

Commit 0fad170

Browse files
silabs-TiborLjerome-pouiller
authored andcommitted
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 <[email protected]>
1 parent 075a92d commit 0fad170

File tree

13 files changed

+248
-1
lines changed

13 files changed

+248
-1
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,4 @@ jobs:
4545
fi
4646
west twister --test sample.basic.helloworld -p siwx917_rb4338a -v --inline-logs $EXTRA_TWISTER_FLAGS
4747
west twister --test sample.net.wifi -p siwx917_rb4338a -v --inline-logs -K $EXTRA_TWISTER_FLAGS
48+
west twister --test sample.bluetooth.peripheral_hr -p siwx917_rb4338a -v --inline-logs -K $EXTRA_TWISTER_FLAGS

.github/workflows/upstream-build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,4 @@ jobs:
5858
fi
5959
west twister -T ../zephyr/samples -s sample.basic.helloworld -p siwx917_rb4338a -v --inline-logs $EXTRA_TWISTER_FLAGS
6060
west twister -T ../zephyr/samples -s sample.net.wifi -p siwx917_rb4338a -v --inline-logs -K $EXTRA_TWISTER_FLAGS
61+
west twister -T ../zephyr/samples -s sample.bluetooth.peripheral_hr -p siwx917_rb4338a -v --inline-logs -K $EXTRA_TWISTER_FLAGS

boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.dts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
zephyr,flash = &flash0;
2121
zephyr,console = &ulpuart0;
2222
zephyr,shell-uart = &ulpuart0;
23+
zephyr,bt-hci = &bt_hci_silabs_siwx917;
2324
};
2425

2526
aliases {
@@ -58,6 +59,10 @@
5859
status = "okay";
5960
};
6061

62+
&bt_hci_silabs_siwx917 {
63+
status = "okay";
64+
};
65+
6166
&ulpuart0 {
6267
status = "okay";
6368
pinctrl-0 = <&ulpuart0_default>;

boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ supported:
1212
- gpio
1313
- i2c
1414
- wifi
15+
- bluetooth
1516
vendor: silabs

drivers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Copyright (c) 2024 Silicon Laboratories Inc.
22
# SPDX-License-Identifier: Apache-2.0
33

4+
add_subdirectory(bluetooth)
45
add_subdirectory(gpio)
56
add_subdirectory(pinctrl)
67
add_subdirectory(wifi)

drivers/bluetooth/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright (c) 2024 Silicon Laboratories Inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
add_subdirectory(hci)

drivers/bluetooth/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2024 Silicon Laboratories Inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
if BT_HCI
5+
6+
rsource "hci/Kconfig.siwx917"
7+
8+
endif
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright (c) 2024 Silicon Laboratories Inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
zephyr_library_sources_ifdef(CONFIG_BT_SIWX917 hci_silabs_siwx917.c)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright (c) 2024 Silicon Laboratories Inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config BT_SIWX917
5+
bool "Silabs SiWx917 Bluetooth interface"
6+
default y
7+
depends on DT_HAS_SILABS_SIWX917_BT_HCI_ENABLED
8+
select CMSIS_RTOS_V2
9+
select POLL
10+
select DYNAMIC_THREAD
11+
select THREAD_NAME
12+
select THREAD_STACK_INFO
13+
select THREAD_MONITOR
14+
select INIT_STACKS
15+
help
16+
Use Silicon Labs Wiseconnect 3.x Bluetooth library to connect to the controller.
17+
18+
if BT_SIWX917
19+
20+
# WiseConnect create threads with realtime priority. Default (10kHz) clock tick
21+
# prevent proper use of the system with these threads.
22+
config SYS_CLOCK_TICKS_PER_SEC
23+
default 1024
24+
25+
config NUM_PREEMPT_PRIORITIES
26+
default 56
27+
28+
config CMSIS_V2_THREAD_DYNAMIC_MAX_COUNT
29+
default 2
30+
31+
config CMSIS_V2_THREAD_DYNAMIC_STACK_SIZE
32+
default 1024
33+
34+
config CMSIS_V2_THREAD_MAX_STACK_SIZE
35+
default 2048
36+
37+
endif #BT_SIWX917
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/*
2+
* Copyright (c) 2024 Silicon Laboratories Inc.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include <zephyr/kernel.h>
7+
#include <zephyr/drivers/bluetooth.h>
8+
9+
#define DT_DRV_COMPAT silabs_bt_hci_siwx917
10+
#define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL
11+
#include <zephyr/logging/log.h>
12+
LOG_MODULE_REGISTER(bt_hci_driver_siwg917);
13+
14+
#include "sl_wifi.h"
15+
#include "sl_wifi_callback_framework.h"
16+
#include "rsi_ble_common_config.h"
17+
#include "rsi_ble.h"
18+
19+
static void bt_siwg917_resp_rcvd(uint16_t status, rsi_ble_event_rcp_rcvd_info_t *resp_buf);
20+
21+
struct hci_data {
22+
bt_hci_recv_t recv;
23+
rsi_data_packet_t rsi_data_packet;
24+
};
25+
26+
static const sl_wifi_device_configuration_t network_config = {
27+
.boot_option = LOAD_NWP_FW,
28+
.mac_address = NULL,
29+
.band = SL_SI91X_WIFI_BAND_2_4GHZ,
30+
.region_code = DEFAULT_REGION,
31+
.boot_config = {
32+
.oper_mode = SL_SI91X_CLIENT_MODE,
33+
.coex_mode = SL_SI91X_BLE_MODE,
34+
.feature_bit_map =
35+
SL_SI91X_FEAT_SECURITY_OPEN |
36+
SL_SI91X_FEAT_WPS_DISABLE,
37+
.tcp_ip_feature_bit_map =
38+
SL_SI91X_TCP_IP_FEAT_DHCPV4_CLIENT |
39+
SL_SI91X_TCP_IP_FEAT_EXTENSION_VALID,
40+
.ext_tcp_ip_feature_bit_map = SL_SI91X_CONFIG_FEAT_EXTENSION_VALID,
41+
.custom_feature_bit_map = SL_SI91X_CUSTOM_FEAT_EXTENSION_VALID,
42+
.ext_custom_feature_bit_map =
43+
MEMORY_CONFIG |
44+
SL_SI91X_EXT_FEAT_XTAL_CLK |
45+
SL_SI91X_EXT_FEAT_FRONT_END_SWITCH_PINS_ULP_GPIO_4_5_0 |
46+
SL_SI91X_EXT_FEAT_BT_CUSTOM_FEAT_ENABLE,
47+
.config_feature_bit_map = SL_SI91X_ENABLE_ENHANCED_MAX_PSP,
48+
.bt_feature_bit_map =
49+
SL_SI91X_BT_RF_TYPE |
50+
SL_SI91X_ENABLE_BLE_PROTOCOL,
51+
.ble_feature_bit_map =
52+
SL_SI91X_BLE_MAX_NBR_PERIPHERALS(RSI_BLE_MAX_NBR_PERIPHERALS) |
53+
SL_SI91X_BLE_MAX_NBR_CENTRALS(RSI_BLE_MAX_NBR_CENTRALS) |
54+
SL_SI91X_BLE_MAX_NBR_ATT_SERV(RSI_BLE_MAX_NBR_ATT_SERV) |
55+
SL_SI91X_BLE_MAX_NBR_ATT_REC(RSI_BLE_MAX_NBR_ATT_REC) |
56+
SL_SI91X_BLE_PWR_INX(RSI_BLE_PWR_INX) |
57+
SL_SI91X_BLE_PWR_SAVE_OPTIONS(RSI_BLE_PWR_SAVE_OPTIONS) |
58+
SL_SI91X_916_BLE_COMPATIBLE_FEAT_ENABLE |
59+
SL_SI91X_FEAT_BLE_CUSTOM_FEAT_EXTENSION_VALID,
60+
.ble_ext_feature_bit_map =
61+
SL_SI91X_BLE_NUM_CONN_EVENTS(RSI_BLE_NUM_CONN_EVENTS) |
62+
SL_SI91X_BLE_NUM_REC_BYTES(RSI_BLE_NUM_REC_BYTES) |
63+
SL_SI91X_BLE_ENABLE_ADV_EXTN |
64+
SL_SI91X_BLE_AE_MAX_ADV_SETS(RSI_BLE_AE_MAX_ADV_SETS),
65+
}};
66+
67+
static int bt_siwg917_open(const struct device *dev, bt_hci_recv_t recv)
68+
{
69+
struct hci_data *hci = dev->data;
70+
71+
int status = sl_wifi_init(&network_config, NULL, sl_wifi_default_event_handler);
72+
status |= rsi_ble_enhanced_gap_extended_register_callbacks(RSI_BLE_ON_RCP_EVENT,
73+
(void *)bt_siwg917_resp_rcvd);
74+
75+
if (!status) {
76+
hci->recv = recv;
77+
}
78+
return status ? -EIO : 0;
79+
}
80+
81+
static int bt_siwg917_send(const struct device *dev, struct net_buf *buf)
82+
{
83+
struct hci_data *hci = dev->data;
84+
int sc = -EOVERFLOW;
85+
uint8_t packet_type = BT_HCI_H4_NONE;
86+
87+
switch (bt_buf_get_type(buf)) {
88+
case BT_BUF_ACL_OUT:
89+
packet_type = BT_HCI_H4_ACL;
90+
break;
91+
case BT_BUF_CMD:
92+
packet_type = BT_HCI_H4_CMD;
93+
break;
94+
default:
95+
sc = -EINVAL;
96+
break;
97+
}
98+
99+
if ((packet_type != BT_HCI_H4_NONE) && (buf->len < sizeof(hci->rsi_data_packet.data))) {
100+
net_buf_push_u8(buf, packet_type);
101+
memcpy(&hci->rsi_data_packet, buf->data, buf->len);
102+
sc = rsi_bt_driver_send_cmd(RSI_BLE_REQ_HCI_RAW, &hci->rsi_data_packet, NULL);
103+
/* TODO SILABS ZEPHYR Convert to errno. A common function from rsi/sl_status should
104+
* be introduced
105+
*/
106+
if (sc) {
107+
LOG_ERR("BT command send failure: %d", sc);
108+
sc = -EIO;
109+
}
110+
}
111+
net_buf_unref(buf);
112+
return sc;
113+
}
114+
115+
static void bt_siwg917_resp_rcvd(uint16_t status, rsi_ble_event_rcp_rcvd_info_t *resp_buf)
116+
{
117+
const struct device *dev = DEVICE_DT_GET(DT_DRV_INST(0));
118+
struct hci_data *hci = dev->data;
119+
uint8_t packet_type = BT_HCI_H4_NONE;
120+
size_t len = 0;
121+
struct net_buf *buf = NULL;
122+
123+
/* TODO SILABS ZEPHYR This horror expression is from the WiseConnect from the HCI example...
124+
* No workaround have been found until now.
125+
*/
126+
memcpy(&packet_type, (resp_buf->data - 12), 1);
127+
switch (packet_type) {
128+
case BT_HCI_H4_EVT: {
129+
struct bt_hci_evt_hdr *hdr = (void *)resp_buf->data;
130+
131+
len = hdr->len + sizeof(*hdr);
132+
buf = bt_buf_get_evt(hdr->evt, false, K_FOREVER);
133+
break;
134+
}
135+
case BT_HCI_H4_ACL: {
136+
struct bt_hci_acl_hdr *hdr = (void *)resp_buf->data;
137+
138+
len = hdr->len + sizeof(*hdr);
139+
buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER);
140+
break;
141+
}
142+
default:
143+
LOG_ERR("Unknown/Unhandled HCI type: %d", packet_type);
144+
break;
145+
}
146+
147+
if (buf && (len <= net_buf_tailroom(buf))) {
148+
net_buf_add_mem(buf, resp_buf->data, len);
149+
hci->recv(dev, buf);
150+
}
151+
}
152+
153+
static const struct bt_hci_driver_api drv = {
154+
.open = bt_siwg917_open,
155+
.send = bt_siwg917_send,
156+
};
157+
158+
#define HCI_DEVICE_INIT(inst) \
159+
static struct hci_data hci_data_##inst; \
160+
DEVICE_DT_INST_DEFINE(inst, NULL, NULL, &hci_data_##inst, NULL, POST_KERNEL, \
161+
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &drv)
162+
163+
/* Only one instance supported right now */
164+
HCI_DEVICE_INIT(0)
165+
166+
/* IRQn 74 is used for communication with co-processor */
167+
Z_ISR_DECLARE(74, ISR_FLAG_DIRECT, IRQ074_Handler, 0);

0 commit comments

Comments
 (0)