Skip to content

Commit ea591e2

Browse files
sreeramIfxjhedberg
authored andcommitted
drivers: bluetooth: Add Infineon Bluetooth driver
Add initial version of the Bluetooth driver for the cy8cproto_063_ble board Signed-off-by: Sreeram Tatapudi <[email protected]>
1 parent 706cfbb commit ea591e2

File tree

13 files changed

+366
-2
lines changed

13 files changed

+366
-2
lines changed

boards/arm/cy8cproto_063_ble/Kconfig.defconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,8 @@ if BOARD_CY8CPROTO_063_BLE
99
config BOARD
1010
default "cy8cproto_063_ble"
1111

12+
choice BT_HCI_BUS_TYPE
13+
default BT_PSOC6_BLESS if BT
14+
endchoice
15+
1216
endif # BOARD_CY8CPROTO_063_BLE

boards/arm/cy8cproto_063_ble/cy8cproto_063_ble.dts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
status = "okay";
5252
};
5353

54-
5554
&gpio_prt5 {
5655
status = "okay";
5756
};
@@ -117,3 +116,7 @@ uart5: &scb5 {
117116
&clk_peri {
118117
clock-div = <1>;
119118
};
119+
120+
&bluetooth {
121+
status = "okay";
122+
};

drivers/bluetooth/hci/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ 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)
1212
zephyr_library_sources_ifdef(CONFIG_BT_SILABS_HCI slz_hci.c)
13+
zephyr_library_sources_ifdef(CONFIG_BT_PSOC6_BLESS hci_psoc6_bless.c)

drivers/bluetooth/hci/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,13 @@ config BT_B91
8888
help
8989
Telink B91 HCI bluetooth interface
9090

91+
config BT_PSOC6_BLESS
92+
bool "PSOC6 BLESS driver"
93+
select BT_HCI_SETUP
94+
help
95+
PSOC6 BLESS driver with BLE Controller which operates in
96+
Single CPU mode.
97+
9198
config BT_NO_DRIVER
9299
bool "No default HCI driver"
93100
help

drivers/bluetooth/hci/Kconfig.infineon

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,17 @@ config BT_ATT_ENFORCE_FLOW
135135
default n
136136

137137
endif # BT_CYW43XXX
138+
139+
if BT_PSOC6_BLESS
140+
141+
config BT_PSOC6_BLESS_MAX_TX_PAYLOAD
142+
int "Max Tx payload size"
143+
range 27 251
144+
default 27
145+
146+
config BT_PSOC6_BLESS_MAX_RX_PAYLOAD
147+
int "Max Rx payload size"
148+
range 27 251
149+
default 27
150+
151+
endif # BT_PSOC6_BLESS
Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
/*
2+
* Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or
3+
* an affiliate of Cypress Semiconductor Corporation
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
/**
9+
* @brief PSoC 6 BLE (BLESS) driver.
10+
*/
11+
12+
#include <errno.h>
13+
#include <stddef.h>
14+
#include <string.h>
15+
16+
#include <zephyr/arch/cpu.h>
17+
#include <zephyr/bluetooth/bluetooth.h>
18+
#include <zephyr/bluetooth/hci.h>
19+
#include <zephyr/drivers/bluetooth/hci_driver.h>
20+
#include <zephyr/drivers/uart.h>
21+
#include <zephyr/init.h>
22+
#include <zephyr/sys/byteorder.h>
23+
#include <zephyr/sys/util.h>
24+
#include "zephyr/logging/log.h"
25+
26+
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
27+
#define LOG_LEVEL CONFIG_BT_HCI_DRIVER_LOG_LEVEL
28+
#include <zephyr/logging/log.h>
29+
LOG_MODULE_REGISTER(psoc6_bless);
30+
31+
#include "cy_ble_stack_pvt.h"
32+
#include "cycfg_ble.h"
33+
34+
#define DT_DRV_COMPAT infineon_cat1_bless_hci
35+
36+
#define PACKET_TYPE_HCI_COMMAND 0X1
37+
#define PACKET_TYPE_HCI_ACL_DATA 0x2
38+
#define PACKET_TYPE_HCI_SYNCHRONOUS 0X3
39+
#define PACKET_TYPE_HCI_EVENT 0X4
40+
41+
#define BLE_LOCK_TMOUT_MS (1000)
42+
#define BLE_THREAD_SEM_TMOUT_MS (1000)
43+
44+
#define CYBLE_STACK_SIZE (CY_BLE_STACK_RAM_SIZE + 4096)
45+
46+
#define PSOC6_BLESS_OP_SET_PUBLIC_ADDR BT_OP(BT_OGF_VS, 0x1a0)
47+
48+
static K_SEM_DEFINE(psoc6_bless_rx_sem, 0, 1);
49+
static K_SEM_DEFINE(psoc6_bless_operation_sem, 1, 1);
50+
static K_KERNEL_STACK_DEFINE(psoc6_bless_rx_thread_stack, CONFIG_BT_RX_STACK_SIZE);
51+
static struct k_thread psoc6_bless_rx_thread_data;
52+
static cy_stc_ble_hci_tx_packet_info_t hci_tx_pkt;
53+
54+
extern void Cy_BLE_EnableLowPowerMode(void);
55+
56+
CY_ALIGN(sizeof(uint32_t)) CY_NOINIT uint8_t psoc6_bless_stack_memory[CYBLE_STACK_SIZE];
57+
58+
/** BLE Stack parameters */
59+
static cy_stc_ble_stack_params_t psoc6_bless_stack_param = {
60+
.memoryHeapPtr = psoc6_bless_stack_memory,
61+
.totalHeapSz = CYBLE_STACK_SIZE,
62+
.dleMaxTxCapability = CONFIG_BT_PSOC6_BLESS_MAX_TX_PAYLOAD,
63+
.dleMaxRxCapability = CONFIG_BT_PSOC6_BLESS_MAX_RX_PAYLOAD,
64+
.featureMask = (CY_BLE_DLE_FEATURE | CY_BLE_LL_PRIVACY_FEATURE |
65+
CY_BLE_SECURE_CONN_FEATURE | CY_BLE_PHY_UPDATE_FEATURE |
66+
CY_BLE_STORE_BONDLIST_FEATURE | CY_BLE_STORE_RESOLVING_LIST_FEATURE |
67+
CY_BLE_STORE_WHITELIST_FEATURE | CY_BLE_TX_POWER_CALIBRATION_FEATURE),
68+
.maxConnCount = CY_BLE_CONN_COUNT,
69+
.tx5dbmModeEn = CY_BLE_ENABLE_TX_5DBM,
70+
};
71+
72+
static const cy_stc_sysint_t psoc6_bless_isr_cfg = {
73+
.intrSrc = DT_INST_IRQN(0),
74+
.intrPriority = DT_INST_IRQ(0, priority),
75+
};
76+
77+
static cy_stc_ble_hw_config_t psoc6_bless_hw_config = {
78+
.blessIsrConfig = &psoc6_bless_isr_cfg,
79+
};
80+
81+
static const cy_stc_ble_config_t psoc6_bless_config = {
82+
.stackParam = &psoc6_bless_stack_param,
83+
.hw = &psoc6_bless_hw_config,
84+
};
85+
86+
static void psoc6_bless_rx_thread(void *, void *, void *)
87+
{
88+
while (true) {
89+
k_sem_take(&psoc6_bless_rx_sem, K_MSEC(BLE_THREAD_SEM_TMOUT_MS));
90+
Cy_BLE_ProcessEvents();
91+
}
92+
}
93+
94+
static void psoc6_bless_isr_handler(const struct device *dev)
95+
{
96+
if (Cy_BLE_HAL_BlessInterruptHandler()) {
97+
k_sem_give(&psoc6_bless_rx_sem);
98+
}
99+
}
100+
101+
static void psoc6_bless_events_handler(uint32_t eventCode, void *eventParam)
102+
{
103+
cy_stc_ble_hci_tx_packet_info_t *hci_rx = NULL;
104+
struct net_buf *buf = NULL;
105+
size_t buf_tailroom = 0;
106+
107+
if (eventCode != CY_BLE_EVT_HCI_PKT_RCVD) {
108+
LOG_DBG("Other EVENT 0x%X", eventCode);
109+
return;
110+
}
111+
112+
hci_rx = eventParam;
113+
114+
switch (hci_rx->packetType) {
115+
case PACKET_TYPE_HCI_EVENT:
116+
buf = bt_buf_get_evt(hci_rx->data[0], 0, K_NO_WAIT);
117+
if (!buf) {
118+
LOG_ERR("Failed to allocate the buffer for RX: EVENT ");
119+
return;
120+
}
121+
122+
break;
123+
case PACKET_TYPE_HCI_ACL_DATA:
124+
buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_NO_WAIT);
125+
if (!buf) {
126+
LOG_ERR("Failed to allocate the buffer for RX: ACL ");
127+
return;
128+
}
129+
bt_buf_set_type(buf, BT_BUF_ACL_IN);
130+
131+
break;
132+
133+
default:
134+
LOG_WRN("Unsupported HCI Packet Received");
135+
return;
136+
}
137+
138+
buf_tailroom = net_buf_tailroom(buf);
139+
if (buf_tailroom < hci_rx->dataLength) {
140+
LOG_WRN("Not enough space for rx data");
141+
return;
142+
}
143+
net_buf_add_mem(buf, hci_rx->data, hci_rx->dataLength);
144+
bt_recv(buf);
145+
}
146+
147+
static int psoc6_bless_open(void)
148+
{
149+
k_tid_t tid;
150+
151+
tid = k_thread_create(&psoc6_bless_rx_thread_data, psoc6_bless_rx_thread_stack,
152+
K_KERNEL_STACK_SIZEOF(psoc6_bless_rx_thread_stack),
153+
psoc6_bless_rx_thread, NULL, NULL, NULL,
154+
K_PRIO_COOP(CONFIG_BT_RX_PRIO), 0, K_NO_WAIT);
155+
k_thread_name_set(tid, "psoc6_bless_rx_thread");
156+
157+
return 0;
158+
}
159+
160+
static int psoc6_bless_send(struct net_buf *buf)
161+
{
162+
cy_en_ble_api_result_t result;
163+
164+
memset(&hci_tx_pkt, 0, sizeof(cy_stc_ble_hci_tx_packet_info_t));
165+
166+
hci_tx_pkt.dataLength = buf->len;
167+
hci_tx_pkt.data = buf->data;
168+
169+
switch (bt_buf_get_type(buf)) {
170+
case BT_BUF_ACL_OUT:
171+
hci_tx_pkt.packetType = PACKET_TYPE_HCI_ACL_DATA;
172+
break;
173+
case BT_BUF_CMD:
174+
hci_tx_pkt.packetType = PACKET_TYPE_HCI_COMMAND;
175+
break;
176+
default:
177+
net_buf_unref(buf);
178+
return -ENOTSUP;
179+
}
180+
181+
if (k_sem_take(&psoc6_bless_operation_sem, K_MSEC(BLE_LOCK_TMOUT_MS)) != 0) {
182+
LOG_ERR("Failed to acquire BLE DRV Semaphore");
183+
net_buf_unref(buf);
184+
return -EIO;
185+
}
186+
187+
result = Cy_BLE_SoftHciSendAppPkt(&hci_tx_pkt);
188+
if (result != CY_BLE_SUCCESS) {
189+
LOG_ERR("Error in sending packet reason %d\r\n", result);
190+
}
191+
192+
k_sem_give(&psoc6_bless_operation_sem);
193+
194+
net_buf_unref(buf);
195+
196+
return 0;
197+
}
198+
199+
static int psoc6_bless_setup(void)
200+
{
201+
struct net_buf *buf;
202+
int err;
203+
uint8_t *addr = (uint8_t *)&SFLASH_BLE_DEVICE_ADDRESS[0];
204+
uint8_t hci_data[] = {
205+
addr[5], addr[4], addr[3], addr[2], addr[1], addr[0], BT_ADDR_LE_PUBLIC,
206+
};
207+
208+
buf = bt_hci_cmd_create(PSOC6_BLESS_OP_SET_PUBLIC_ADDR, sizeof(hci_data));
209+
if (buf == NULL) {
210+
LOG_ERR("Unable to allocate command buffer");
211+
return -ENOMEM;
212+
}
213+
214+
/* Add data part of packet */
215+
net_buf_add_mem(buf, hci_data, sizeof(hci_data));
216+
217+
err = bt_hci_cmd_send_sync(PSOC6_BLESS_OP_SET_PUBLIC_ADDR, buf, NULL);
218+
if (err) {
219+
return err;
220+
}
221+
222+
return 0;
223+
}
224+
225+
static int psoc6_bless_hci_init(void)
226+
{
227+
cy_en_ble_api_result_t result;
228+
static const struct bt_hci_driver drv = {
229+
.name = "PSoC 6 BLESS",
230+
.bus = BT_HCI_DRIVER_BUS_VIRTUAL,
231+
.quirks = BT_QUIRK_NO_RESET,
232+
.open = psoc6_bless_open,
233+
.send = psoc6_bless_send,
234+
.setup = psoc6_bless_setup,
235+
};
236+
237+
/* Connect BLE interrupt to ISR */
238+
IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), psoc6_bless_isr_handler, 0, 0);
239+
240+
/* Registers the generic callback functions. */
241+
Cy_BLE_RegisterEventCallback(psoc6_bless_events_handler);
242+
243+
/* Initializes the PSoC 6 BLESS Controller. */
244+
result = Cy_BLE_InitController(&psoc6_bless_config);
245+
if (result != CY_BLE_SUCCESS) {
246+
LOG_ERR("Failed to init the BLE Controller");
247+
return -EIO;
248+
}
249+
250+
/* Enables the BLESS controller in HCI only mode. */
251+
result = Cy_BLE_EnableHCIModeController();
252+
if (result != CY_BLE_SUCCESS) {
253+
LOG_ERR("Failed to enable the BLE Controller in hci mode");
254+
return -EIO;
255+
}
256+
257+
/* Enables BLE Low-power mode (LPM)*/
258+
Cy_BLE_EnableLowPowerMode();
259+
260+
/* Register a BLESS HCI driver to the Bluetooth stack. */
261+
bt_hci_driver_register(&drv);
262+
263+
return 0;
264+
}
265+
266+
SYS_INIT(psoc6_bless_hci_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);

dts/arm/infineon/psoc6/psoc6_01/psoc6_01.dtsi

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,5 +314,11 @@
314314
interrupts = <22 6>;
315315
status = "disabled";
316316
};
317+
318+
bluetooth: bless {
319+
compatible = "infineon,cat1-bless-hci";
320+
interrupts = <24 1>;
321+
status = "disabled";
322+
};
317323
};
318324
};
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or
2+
# an affiliate of Cypress Semiconductor Corporation
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
description: |
7+
Bluetooth module that uses Infineon's Host Controller Interface
8+
9+
compatible: "infineon,cat1-bless-hci"
10+
11+
include: base.yaml
12+
13+
properties:
14+
interrupts:
15+
required: true

modules/hal_infineon/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,7 @@ endif()
3737
if (CONFIG_BT_CYW43XXX)
3838
add_subdirectory(btstack-integration)
3939
endif()
40+
41+
if (CONFIG_BT_PSOC6_BLESS)
42+
add_subdirectory(bless)
43+
endif()
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Copyright (c) 2022 Cypress Semiconductor Corporation.
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
set(bless_dir ${ZEPHYR_HAL_INFINEON_MODULE_DIR}/bless)
6+
set(bless_blobs_dir ${ZEPHYR_HAL_INFINEON_MODULE_DIR}/zephyr/blobs/img/bluetooth/firmware)
7+
8+
zephyr_include_directories(${bless_dir}/include)
9+
10+
zephyr_compile_definitions(COMPONENT_BLESS_CONTROLLER)
11+
12+
zephyr_library_sources(${bless_dir}/cy_ble.c)
13+
zephyr_library_sources(${bless_dir}/cy_ble_clk.c)
14+
zephyr_library_sources(${bless_dir}/cy_ble_common.c)
15+
zephyr_library_sources(${bless_dir}/cy_ble_controller.c)
16+
zephyr_library_sources(${bless_dir}/cy_ble_event_handler.c)
17+
zephyr_library_sources(${bless_dir}/cy_ble_hal_int.c)
18+
zephyr_library_sources(${bless_dir}/cy_ble_hal_pvt.c)
19+
20+
zephyr_link_libraries(
21+
${bless_blobs_dir}/COMPONENT_BLESS_CONTROLLER/cy_ble_stack_controller.a
22+
${bless_blobs_dir}/COMPONENT_BLESS_CONTROLLER/cy_ble_stack_manager.a
23+
)

0 commit comments

Comments
 (0)