1 /*
2 * Copyright (c) 2017 Linaro Limited
3 * Copyright (c) 2016 Nordic Semiconductor ASA
4 * Copyright (c) 2015-2016 Intel Corporation
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <errno.h>
10 #include <stddef.h>
11 #include <stdio.h>
12
13 #include <zephyr/kernel.h>
14 #include <zephyr/sys/byteorder.h>
15 #include <zephyr/logging/log.h>
16 #include <zephyr/debug/stack.h>
17
18 #include <zephyr/device.h>
19 #include <zephyr/init.h>
20 #include <zephyr/drivers/gpio.h>
21 #include <zephyr/drivers/spi.h>
22
23 #include <zephyr/net_buf.h>
24 #include <zephyr/bluetooth/bluetooth.h>
25 #include <zephyr/bluetooth/l2cap.h>
26 #include <zephyr/bluetooth/hci.h>
27 #include <zephyr/bluetooth/buf.h>
28 #include <zephyr/bluetooth/hci_raw.h>
29
30 #define LOG_MODULE_NAME hci_spi
31 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
32
33 #define HCI_CMD 0x01
34 #define HCI_ACL 0x02
35 #define HCI_SCO 0x03
36 #define HCI_EVT 0x04
37
38 /* Special Values */
39 #define SPI_WRITE 0x0A
40 #define SPI_READ 0x0B
41 #define READY_NOW 0x02
42 #define SANITY_CHECK 0x02
43
44 /* Offsets */
45 #define STATUS_HEADER_READY 0
46 #define STATUS_HEADER_TOREAD 3
47
48 #define PACKET_TYPE 0
49 #define EVT_BLUE_INITIALIZED 0x01
50
51 /* Needs to be aligned with the SPI master buffer size */
52 #define SPI_MAX_MSG_LEN 255
53
54 static uint8_t rxmsg[SPI_MAX_MSG_LEN];
55 static struct spi_buf rx;
56 const static struct spi_buf_set rx_bufs = {
57 .buffers = &rx,
58 .count = 1,
59 };
60
61 static uint8_t txmsg[SPI_MAX_MSG_LEN];
62 static struct spi_buf tx;
63 const static struct spi_buf_set tx_bufs = {
64 .buffers = &tx,
65 .count = 1,
66 };
67
68 /* HCI buffer pools */
69 #define CMD_BUF_SIZE BT_BUF_RX_SIZE
70
71 /*
72 * This finds an arbitrary node with compatible
73 * "zephyr,bt-hci-spi-slave". There should just be one in the
74 * devicetree.
75 *
76 * If for some reason you have more than one of these in your
77 * devicetree, replace this macro definition to pick one, e.g. using
78 * DT_NODELABEL().
79 */
80 #define HCI_SPI_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(zephyr_bt_hci_spi_slave)
81
82 /*
83 * This is the SPI bus controller device used to exchange data with
84 * the SPI-based BT controller.
85 */
86 static const struct device *const spi_hci_dev = DEVICE_DT_GET(DT_BUS(HCI_SPI_NODE));
87 static struct spi_config spi_cfg = {
88 .operation = SPI_WORD_SET(8) | SPI_OP_MODE_SLAVE,
89 };
90
91 /*
92 * The GPIO used to send interrupts to the host,
93 * configured in the 'irq-gpios' property in HCI_SPI_NODE.
94 */
95 static const struct gpio_dt_spec irq = GPIO_DT_SPEC_GET(HCI_SPI_NODE, irq_gpios);
96
97 static K_THREAD_STACK_DEFINE(bt_tx_thread_stack, CONFIG_BT_HCI_TX_STACK_SIZE);
98 static struct k_thread bt_tx_thread_data;
99
100 static K_SEM_DEFINE(sem_spi_rx, 0, 1);
101 static K_SEM_DEFINE(sem_spi_tx, 0, 1);
102
spi_send(struct net_buf * buf)103 static inline int spi_send(struct net_buf *buf)
104 {
105 uint8_t header_master[5] = { 0 };
106 uint8_t header_slave[5] = { READY_NOW, SANITY_CHECK,
107 0x00, 0x00, 0x00 };
108 int ret;
109
110 LOG_DBG("buf %p type %u len %u", buf, buf->data[0], buf->len);
111
112 if (buf->len > SPI_MAX_MSG_LEN) {
113 LOG_ERR("TX message too long");
114 net_buf_unref(buf);
115 return -EINVAL;
116 }
117 header_slave[STATUS_HEADER_TOREAD] = buf->len;
118
119 gpio_pin_set(irq.port, irq.pin, 1);
120
121 /* Coordinate transfer lock with the spi rx thread */
122 k_sem_take(&sem_spi_tx, K_FOREVER);
123
124 tx.buf = header_slave;
125 tx.len = 5;
126 rx.buf = header_master;
127 rx.len = 5;
128 do {
129 ret = spi_transceive(spi_hci_dev, &spi_cfg, &tx_bufs, &rx_bufs);
130 if (ret < 0) {
131 LOG_ERR("SPI transceive error: %d", ret);
132 }
133 } while (header_master[STATUS_HEADER_READY] != SPI_READ);
134
135 tx.buf = buf->data;
136 tx.len = buf->len;
137
138 ret = spi_write(spi_hci_dev, &spi_cfg, &tx_bufs);
139 if (ret < 0) {
140 LOG_ERR("SPI transceive error: %d", ret);
141 }
142 net_buf_unref(buf);
143
144 gpio_pin_set(irq.port, irq.pin, 0);
145 k_sem_give(&sem_spi_rx);
146
147 return 0;
148 }
149
bt_tx_thread(void * p1,void * p2,void * p3)150 static void bt_tx_thread(void *p1, void *p2, void *p3)
151 {
152 uint8_t header_master[5];
153 uint8_t header_slave[5] = { READY_NOW, SANITY_CHECK,
154 0x00, 0x00, 0x00 };
155 struct net_buf *buf = NULL;
156
157 union {
158 struct bt_hci_cmd_hdr *cmd_hdr;
159 struct bt_hci_acl_hdr *acl_hdr;
160 } hci_hdr;
161 hci_hdr.cmd_hdr = (struct bt_hci_cmd_hdr *)&rxmsg[1];
162 int ret;
163
164 ARG_UNUSED(p1);
165 ARG_UNUSED(p2);
166 ARG_UNUSED(p3);
167
168 (void)memset(txmsg, 0xFF, SPI_MAX_MSG_LEN);
169
170 while (1) {
171 tx.buf = header_slave;
172 tx.len = 5;
173 rx.buf = header_master;
174 rx.len = 5;
175
176 do {
177 ret = spi_transceive(spi_hci_dev, &spi_cfg,
178 &tx_bufs, &rx_bufs);
179 if (ret < 0) {
180 LOG_ERR("SPI transceive error: %d", ret);
181 }
182 } while ((header_master[STATUS_HEADER_READY] != SPI_READ) &&
183 (header_master[STATUS_HEADER_READY] != SPI_WRITE));
184
185 if (header_master[STATUS_HEADER_READY] == SPI_READ) {
186 /* Unblock the spi tx thread and wait for it */
187 k_sem_give(&sem_spi_tx);
188 k_sem_take(&sem_spi_rx, K_FOREVER);
189 continue;
190 }
191
192 tx.buf = txmsg;
193 tx.len = SPI_MAX_MSG_LEN;
194 rx.buf = rxmsg;
195 rx.len = SPI_MAX_MSG_LEN;
196
197 /* Receiving data from the SPI Host */
198 ret = spi_transceive(spi_hci_dev, &spi_cfg,
199 &tx_bufs, &rx_bufs);
200 if (ret < 0) {
201 LOG_ERR("SPI transceive error: %d", ret);
202 continue;
203 }
204
205 switch (rxmsg[PACKET_TYPE]) {
206 case HCI_CMD:
207 buf = bt_buf_get_tx(BT_BUF_CMD, K_NO_WAIT,
208 hci_hdr.cmd_hdr,
209 sizeof(*hci_hdr.cmd_hdr));
210 if (buf) {
211 net_buf_add_mem(buf, &rxmsg[4],
212 hci_hdr.cmd_hdr->param_len);
213 } else {
214 LOG_ERR("No available command buffers!");
215 continue;
216 }
217 break;
218 case HCI_ACL:
219 buf = bt_buf_get_tx(BT_BUF_ACL_OUT, K_NO_WAIT,
220 hci_hdr.acl_hdr,
221 sizeof(*hci_hdr.acl_hdr));
222 if (buf) {
223 net_buf_add_mem(buf, &rxmsg[5],
224 sys_le16_to_cpu(hci_hdr.acl_hdr->len));
225 } else {
226 LOG_ERR("No available ACL buffers!");
227 continue;
228 }
229 break;
230 default:
231 LOG_ERR("Unknown BT HCI buf type");
232 continue;
233 }
234
235 LOG_DBG("buf %p type %u len %u", buf, buf->data[0], buf->len);
236
237 ret = bt_send(buf);
238 if (ret) {
239 LOG_ERR("Unable to send (ret %d)", ret);
240 net_buf_unref(buf);
241 }
242
243 /* Make sure other threads get a chance to run */
244 k_yield();
245 }
246 }
247
hci_spi_init(void)248 static int hci_spi_init(void)
249 {
250
251 LOG_DBG("");
252
253 if (!device_is_ready(spi_hci_dev)) {
254 LOG_ERR("SPI bus %s is not ready", spi_hci_dev->name);
255 return -EINVAL;
256 }
257
258 if (!gpio_is_ready_dt(&irq)) {
259 LOG_ERR("IRQ GPIO port %s is not ready", irq.port->name);
260 return -EINVAL;
261 }
262 gpio_pin_configure_dt(&irq, GPIO_OUTPUT_INACTIVE);
263
264 return 0;
265 }
266
267 SYS_INIT(hci_spi_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
268
main(void)269 int main(void)
270 {
271 static K_FIFO_DEFINE(rx_queue);
272 struct bt_hci_evt_hdr *evt_hdr;
273 struct net_buf *buf;
274 k_tid_t tx_id;
275 int err;
276
277 LOG_DBG("Start");
278
279 err = bt_enable_raw(&rx_queue);
280 if (err) {
281 LOG_ERR("bt_enable_raw: %d; aborting", err);
282 return 0;
283 }
284
285 /* Spawn the TX thread, which feeds cmds and data to the controller */
286 tx_id = k_thread_create(&bt_tx_thread_data, bt_tx_thread_stack,
287 K_THREAD_STACK_SIZEOF(bt_tx_thread_stack),
288 bt_tx_thread, NULL, NULL, NULL, K_PRIO_COOP(7),
289 0, K_NO_WAIT);
290 k_thread_name_set(&bt_tx_thread_data, "bt_tx_thread");
291
292 /* Send a vendor event to announce that the slave is initialized */
293 buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
294 evt_hdr = net_buf_add(buf, sizeof(*evt_hdr));
295 evt_hdr->evt = BT_HCI_EVT_VENDOR;
296 evt_hdr->len = 2U;
297 net_buf_add_le16(buf, EVT_BLUE_INITIALIZED);
298 err = spi_send(buf);
299 if (err) {
300 LOG_ERR("can't send initialization event; aborting");
301 k_thread_abort(tx_id);
302 return 0;
303 }
304
305 while (1) {
306 buf = k_fifo_get(&rx_queue, K_FOREVER);
307 err = spi_send(buf);
308 if (err) {
309 LOG_ERR("Failed to send");
310 }
311 /* Ensure that the IRQ line is de-asserted for some minimum
312 * duration between buffers, so that the HCI controller has
313 * time to observe the edge.
314 */
315 k_sleep(K_TICKS(1));
316 }
317 return 0;
318 }
319