Skip to content

Commit 4a614de

Browse files
fkokosinskicarlescufi
authored andcommitted
drivers/bluetooth/hci: add SiLabs BLE HCI driver
This commit adds the SiLabs Bluetooth HCI driver. It also enables this BLE HCI driver on the efr32bg_sltb010a board. Signed-off-by: Filip Kokosinski <fkokosinski@antmicro.com>
1 parent 905443e commit 4a614de

File tree

7 files changed

+246
-1
lines changed

7 files changed

+246
-1
lines changed

boards/arm/efr32bg_sltb010a/Kconfig.defconfig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,21 @@ config CMU_HFXO_FREQ
1414
config CMU_LFXO_FREQ
1515
default 32768
1616

17+
if BT
18+
19+
config FPU
20+
default y
21+
22+
config MINIMAL_LIBC_MALLOC_ARENA_SIZE
23+
default 8192
24+
25+
config MAIN_STACK_SIZE
26+
default 2304
27+
28+
choice BT_HCI_BUS_TYPE
29+
default BT_SILABS_HCI
30+
endchoice
31+
32+
endif # BT
33+
1734
endif # BOARD_EFR32BG_SLTB010A

boards/arm/efr32bg_sltb010a/doc/index.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ The efr32bg_sltb010a board configuration supports the following hardware feature
7676
+-----------+------------+-------------------------------------+
7777
| I2C(M/S) | on-chip | i2c |
7878
+-----------+------------+-------------------------------------+
79+
| RADIO | on-chip | bluetooth |
80+
+-----------+------------+-------------------------------------+
7981

8082
The default configuration can be found in the defconfig file:
8183
``boards/arm/efr32bg_sltb010a/efr32bg_sltb010a_defconfig``.
@@ -163,6 +165,25 @@ the following message:
163165
Hello World! efr32bg_sltb010a
164166
165167
168+
Bluetooth
169+
=========
170+
171+
To use the BLE function, run the command below to retrieve necessary binary
172+
blobs from the SiLabs HAL repository.
173+
174+
.. code-block:: console
175+
176+
west blobs fetch silabs
177+
178+
Then build the Zephyr kernel and a Bluetooth sample with the following
179+
command. The :ref:`bluetooth-observer-sample` sample application is used in
180+
this example.
181+
182+
.. zephyr-app-commands::
183+
:zephyr-app: samples/bluetooth/observer
184+
:board: efr32bg_sltb010a
185+
:goals: build
186+
166187
.. _EFR32BG22-SLTB010A Website:
167188
https://www.silabs.com/development-tools/thunderboard/thunderboard-bg22-kit
168189

drivers/bluetooth/hci/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ zephyr_library_sources_ifdef(CONFIG_BT_RPMSG rpmsg.c)
99
zephyr_library_sources_ifdef(CONFIG_BT_SPI spi.c)
1010
zephyr_library_sources_ifdef(CONFIG_BT_STM32_IPM ipm_stm32wb.c)
1111
zephyr_library_sources_ifdef(CONFIG_BT_USERCHAN userchan.c)
12+
zephyr_library_sources_ifdef(CONFIG_BT_SILABS_HCI slz_hci.c)

drivers/bluetooth/hci/Kconfig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,18 @@ config BT_STM32_IPM
5656
help
5757
TODO
5858

59+
config BT_SILABS_HCI
60+
bool "Silicon Labs Bluetooth interface"
61+
depends on SOC_SERIES_EFR32BG22
62+
select ENTROPY_GENERATOR
63+
select MBEDTLS
64+
select MBEDTLS_PSA_CRYPTO_C
65+
select MBEDTLS_ENTROPY_ENABLED
66+
select MBEDTLS_ZEPHYR_ENTROPY
67+
help
68+
Use Silicon Labs binary Bluetooth library to connect to the
69+
controller.
70+
5971
config BT_USERCHAN
6072
bool "HCI User Channel based driver"
6173
depends on BOARD_NATIVE_POSIX
@@ -162,3 +174,11 @@ config BT_DRV_RX_STACK_SIZE
162174
default 256
163175
help
164176
Stack size for the HCI driver's RX thread.
177+
178+
config BT_SILABS_HCI_BUFFER_MEMORY
179+
int "Silicon Labs Bluetooth Library memory buffer size"
180+
depends on BT_SILABS_HCI
181+
default 6144
182+
help
183+
Select the size of allocated memory buffer for the Silicon Labs
184+
Bluetooth Library.

drivers/bluetooth/hci/slz_hci.c

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/*
2+
* Copyright (c) 2023 Antmicro <www.antmicro.com>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/drivers/bluetooth/hci_driver.h>
8+
9+
#include <sl_btctrl_linklayer.h>
10+
#include <sl_hci_common_transport.h>
11+
#include <pa_conversions_efr32.h>
12+
#include <sl_bt_ll_zephyr.h>
13+
14+
#define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL
15+
#include <zephyr/logging/log.h>
16+
LOG_MODULE_REGISTER(bt_hci_driver_slz);
17+
18+
#define SL_BT_CONFIG_ACCEPT_LIST_SIZE 1
19+
#define SL_BT_CONFIG_MAX_CONNECTIONS 1
20+
#define SL_BT_CONFIG_USER_ADVERTISERS 1
21+
#define SL_BT_CONTROLLER_BUFFER_MEMORY CONFIG_BT_SILABS_HCI_BUFFER_MEMORY
22+
#define SL_BT_SILABS_LL_STACK_SIZE 1024
23+
24+
static K_KERNEL_STACK_DEFINE(slz_ll_stack, SL_BT_SILABS_LL_STACK_SIZE);
25+
static struct k_thread slz_ll_thread;
26+
27+
void rail_isr_installer(void)
28+
{
29+
IRQ_CONNECT(RDMAILBOX_IRQn, 0, RDMAILBOX_IRQHandler, NULL, 0);
30+
IRQ_CONNECT(RAC_SEQ_IRQn, 0, RAC_SEQ_IRQHandler, NULL, 0);
31+
IRQ_CONNECT(RAC_RSM_IRQn, 0, RAC_RSM_IRQHandler, NULL, 0);
32+
IRQ_CONNECT(PROTIMER_IRQn, 0, PROTIMER_IRQHandler, NULL, 0);
33+
IRQ_CONNECT(MODEM_IRQn, 0, MODEM_IRQHandler, NULL, 0);
34+
IRQ_CONNECT(FRC_IRQn, 0, FRC_IRQHandler, NULL, 0);
35+
IRQ_CONNECT(BUFC_IRQn, 0, BUFC_IRQHandler, NULL, 0);
36+
IRQ_CONNECT(AGC_IRQn, 0, AGC_IRQHandler, NULL, 0);
37+
}
38+
39+
/**
40+
* @brief Transmit HCI message using the currently used transport layer.
41+
* The HCI calls this function to transmit a full HCI message.
42+
* @param[in] data Packet type followed by HCI packet data.
43+
* @param[in] len Length of the `data` parameter
44+
* @return 0 - on success, or non-zero on failure.
45+
*/
46+
uint32_t hci_common_transport_transmit(uint8_t *data, int16_t len)
47+
{
48+
struct net_buf *buf;
49+
uint8_t packet_type = data[0];
50+
uint8_t flags;
51+
uint8_t event_code;
52+
53+
LOG_HEXDUMP_DBG(data, len, "host packet data:");
54+
55+
/* drop packet type from the frame buffer - it is no longer needed */
56+
data = &data[1];
57+
len -= 1;
58+
59+
switch (packet_type) {
60+
case h4_event:
61+
event_code = data[0];
62+
flags = bt_hci_evt_get_flags(event_code);
63+
buf = bt_buf_get_evt(event_code, false, K_FOREVER);
64+
break;
65+
case h4_acl:
66+
buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER);
67+
break;
68+
default:
69+
LOG_ERR("Unknown HCI type: %d", packet_type);
70+
return -EINVAL;
71+
}
72+
73+
net_buf_add_mem(buf, data, len);
74+
if ((packet_type == h4_event) && (flags & BT_HCI_EVT_FLAG_RECV_PRIO)) {
75+
bt_recv_prio(buf);
76+
} else {
77+
bt_recv(buf);
78+
}
79+
80+
sl_btctrl_hci_transmit_complete(0);
81+
82+
return 0;
83+
}
84+
85+
static int slz_bt_send(struct net_buf *buf)
86+
{
87+
int rv = 0;
88+
89+
switch (bt_buf_get_type(buf)) {
90+
case BT_BUF_ACL_OUT:
91+
net_buf_push_u8(buf, h4_acl);
92+
break;
93+
case BT_BUF_CMD:
94+
net_buf_push_u8(buf, h4_command);
95+
break;
96+
default:
97+
rv = -EINVAL;
98+
goto done;
99+
}
100+
101+
rv = hci_common_transport_receive(buf->data, buf->len, true);
102+
if (!rv) {
103+
goto done;
104+
}
105+
106+
done:
107+
net_buf_unref(buf);
108+
return rv;
109+
}
110+
111+
static int slz_bt_open(void)
112+
{
113+
int ret;
114+
115+
/* Start RX thread */
116+
k_thread_create(&slz_ll_thread, slz_ll_stack,
117+
K_KERNEL_STACK_SIZEOF(slz_ll_stack),
118+
(k_thread_entry_t)slz_ll_thread_func, NULL, NULL, NULL,
119+
K_PRIO_COOP(CONFIG_BT_DRIVER_RX_HIGH_PRIO), 0,
120+
K_NO_WAIT);
121+
122+
rail_isr_installer();
123+
sl_rail_util_pa_init();
124+
125+
/* sl_btctrl_init_mem returns the number of memory buffers allocated */
126+
ret = sl_btctrl_init_mem(SL_BT_CONTROLLER_BUFFER_MEMORY);
127+
if (!ret) {
128+
LOG_ERR("Failed to allocate memory %d", ret);
129+
return -ENOMEM;
130+
}
131+
132+
ret = sl_btctrl_init_ll();
133+
if (ret) {
134+
LOG_ERR("Bluetooth link layer init failed %d", ret);
135+
goto deinit;
136+
}
137+
138+
sl_btctrl_init_scan();
139+
sl_btctrl_init_adv();
140+
sl_btctrl_init_conn();
141+
142+
sl_btctrl_hci_parser_init_adv();
143+
sl_btctrl_hci_parser_init_conn();
144+
145+
ret = sl_btctrl_init_basic(SL_BT_CONFIG_MAX_CONNECTIONS,
146+
SL_BT_CONFIG_USER_ADVERTISERS,
147+
SL_BT_CONFIG_ACCEPT_LIST_SIZE);
148+
if (ret) {
149+
LOG_ERR("Failed to initialize the controller %d", ret);
150+
goto deinit;
151+
}
152+
153+
sl_bthci_init_upper();
154+
155+
LOG_DBG("SiLabs BT HCI started");
156+
157+
return 0;
158+
deinit:
159+
sli_btctrl_deinit_mem();
160+
return ret;
161+
}
162+
163+
static const struct bt_hci_driver drv = {
164+
.name = "sl:bt",
165+
.bus = BT_HCI_DRIVER_BUS_UART,
166+
.open = slz_bt_open,
167+
.send = slz_bt_send,
168+
.quirks = BT_QUIRK_NO_RESET
169+
};
170+
171+
static int slz_bt_init(const struct device *unused)
172+
{
173+
ARG_UNUSED(unused);
174+
175+
int ret;
176+
177+
ret = bt_hci_driver_register(&drv);
178+
if (ret) {
179+
LOG_ERR("Failed to register SiLabs BT HCI %d", ret);
180+
}
181+
182+
return ret;
183+
}
184+
185+
SYS_INIT(slz_bt_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);

soc/arm/silabs_exx32/efr32bg22/Kconfig.series

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ config SOC_SERIES_EFR32BG22
1818
select SOC_GECKO_CMU
1919
select SOC_GECKO_CORE
2020
select SOC_GECKO_DEV_INIT
21+
select SOC_GECKO_SE
2122
help
2223
Enable support for EFR32BG22 Blue Gecko MCU series

west.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ manifest:
126126
groups:
127127
- hal
128128
- name: hal_silabs
129-
revision: ed4185ce6f6598892fba6ce1b6dede77b217fb37
129+
revision: 793db3cb744a6873f5564a901d6c9a1bb7dd5fd8
130130
path: modules/hal/silabs
131131
groups:
132132
- hal

0 commit comments

Comments
 (0)