]> Git Repo - esp-hosted.git/blame - esp/esp_driver/network_adapter/main/slave_bt.c
Merge branch 'pr129_vuhailongkl97' into 'master'
[esp-hosted.git] / esp / esp_driver / network_adapter / main / slave_bt.c
CommitLineData
2fcc401a 1// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16#ifdef CONFIG_BT_ENABLED
47a682ac 17#include <string.h>
18#include "driver/periph_ctrl.h"
19#include "driver/gpio.h"
20#include "driver/uart.h"
21#include "soc/lldesc.h"
2fcc401a 22#include "esp_bt.h"
47a682ac 23#include "esp_log.h"
2fcc401a 24#include "slave_bt.h"
25
47a682ac 26#ifdef CONFIG_IDF_TARGET_ESP32C3
27#include "esp_private/gdma.h"
a1990b7d 28#if BLUETOOTH_UART
47a682ac 29#include "hal/uhci_ll.h"
30#endif
a1990b7d 31#endif
47a682ac 32
2fcc401a 33static const char BT_TAG[] = "ESP_BT";
2fcc401a 34
35#if BLUETOOTH_HCI
36/* ***** HCI specific part ***** */
37
38#define VHCI_MAX_TIMEOUT_MS 2000
39static SemaphoreHandle_t vhci_send_sem;
40
41static void controller_rcv_pkt_ready(void)
42{
43 if (vhci_send_sem)
44 xSemaphoreGive(vhci_send_sem);
45}
46
47static int host_rcv_pkt(uint8_t *data, uint16_t len)
48{
2fcc401a 49 interface_buffer_handle_t buf_handle;
50 uint8_t *buf = NULL;
51
52 buf = (uint8_t *) malloc(len);
53
54 if (!buf) {
55 ESP_LOGE(BT_TAG, "HCI Send packet: memory allocation failed");
56 return ESP_FAIL;
57 }
58
59 memcpy(buf, data, len);
60
61 memset(&buf_handle, 0, sizeof(buf_handle));
62
63 buf_handle.if_type = ESP_HCI_IF;
64 buf_handle.if_num = 0;
65 buf_handle.payload_len = len;
66 buf_handle.payload = buf;
67 buf_handle.wlan_buf_handle = buf;
68 buf_handle.free_buf_handle = free;
69
70#if CONFIG_ESP_BT_DEBUG
71 ESP_LOG_BUFFER_HEXDUMP("bt_tx", data, len, ESP_LOG_INFO);
72#endif
2fcc401a 73
6a993f3d 74 if (send_to_host_queue(&buf_handle, PRIO_Q_BT)) {
2fcc401a 75 free(buf);
76 return ESP_FAIL;
77 }
78
79 return 0;
80}
81
82static esp_vhci_host_callback_t vhci_host_cb = {
83 controller_rcv_pkt_ready,
84 host_rcv_pkt
85};
86
87void process_hci_rx_pkt(uint8_t *payload, uint16_t payload_len) {
88 /* VHCI needs one extra byte at the start of payload */
89 /* that is accomodated in esp_payload_header */
90#if CONFIG_ESP_BT_DEBUG
91 ESP_LOG_BUFFER_HEXDUMP("bt_rx", payload, payload_len, ESP_LOG_INFO);
92#endif
93 payload--;
94 payload_len++;
95
96 if (!esp_vhci_host_check_send_available()) {
97 ESP_LOGD(BT_TAG, "VHCI not available");
98 }
99
100 if (vhci_send_sem) {
101 if (xSemaphoreTake(vhci_send_sem, VHCI_MAX_TIMEOUT_MS) == pdTRUE) {
102 esp_vhci_host_send_packet(payload, payload_len);
103 } else {
104 ESP_LOGI(BT_TAG, "VHCI sem timeout");
105 }
106 }
107}
108
109#elif BLUETOOTH_UART
110/* ***** UART specific part ***** */
111
47a682ac 112#ifdef CONFIG_IDF_TARGET_ESP32C3
113// Operation functions for HCI UART Transport Layer
114static bool hci_uart_tl_init(void);
115static void hci_uart_tl_deinit(void);
116static void hci_uart_tl_recv_async(uint8_t *buf, uint32_t size, esp_bt_hci_tl_callback_t callback, void *arg);
117static void hci_uart_tl_send_async(uint8_t *buf, uint32_t size, esp_bt_hci_tl_callback_t callback, void *arg);
118static void hci_uart_tl_flow_on(void);
119static bool hci_uart_tl_flow_off(void);
120static void hci_uart_tl_finish_transfers(void);
121
122struct uart_txrxchannel {
123 esp_bt_hci_tl_callback_t callback;
124 void *arg;
125 lldesc_t link;
126};
127
128struct uart_env_tag {
129 struct uart_txrxchannel tx;
130 struct uart_txrxchannel rx;
131};
132
133struct uart_env_tag uart_env;
134
135static volatile uhci_dev_t *s_uhci_hw = &UHCI0;
136static gdma_channel_handle_t s_rx_channel;
137static gdma_channel_handle_t s_tx_channel;
138
139static esp_bt_hci_tl_t s_hci_uart_tl_funcs = {
140 ._magic = ESP_BT_HCI_TL_MAGIC_VALUE,
141 ._version = ESP_BT_HCI_TL_VERSION,
142 ._reserved = 0,
143 ._open = (void *)hci_uart_tl_init,
144 ._close = (void *)hci_uart_tl_deinit,
145 ._finish_transfers = (void *)hci_uart_tl_finish_transfers,
146 ._recv = (void *)hci_uart_tl_recv_async,
147 ._send = (void *)hci_uart_tl_send_async,
148 ._flow_on = (void *)hci_uart_tl_flow_on,
149 ._flow_off = (void *)hci_uart_tl_flow_off,
150};
151
152static bool hci_uart_tl_init(void)
153{
154 return true;
155}
156
157static void hci_uart_tl_deinit(void)
158{
159}
160
161static IRAM_ATTR void hci_uart_tl_recv_async(uint8_t *buf, uint32_t size,
162 esp_bt_hci_tl_callback_t callback, void *arg)
163{
164 assert(buf != NULL);
165 assert(size != 0);
166 assert(callback != NULL);
167 uart_env.rx.callback = callback;
168 uart_env.rx.arg = arg;
169
170 memset(&uart_env.rx.link, 0, sizeof(lldesc_t));
171 uart_env.rx.link.buf = buf;
172 uart_env.rx.link.size = size;
173
174 s_uhci_hw->pkt_thres.thrs = size;
175
176 gdma_start(s_rx_channel, (intptr_t)(&uart_env.rx.link));
177}
178
179static IRAM_ATTR void hci_uart_tl_send_async(uint8_t *buf, uint32_t size,
180 esp_bt_hci_tl_callback_t callback, void *arg)
181{
182 assert(buf != NULL);
183 assert(size != 0);
184 assert(callback != NULL);
185
186 uart_env.tx.callback = callback;
187 uart_env.tx.arg = arg;
188
189 memset(&uart_env.tx.link, 0, sizeof(lldesc_t));
190 uart_env.tx.link.length = size;
191 uart_env.tx.link.buf = buf;
192 uart_env.tx.link.eof = 1;
193
194 gdma_start(s_tx_channel, (intptr_t)(&uart_env.tx.link));
195}
196
197static void hci_uart_tl_flow_on(void)
198{
199}
200
201static bool hci_uart_tl_flow_off(void)
202{
203 return true;
204}
205
206static void hci_uart_tl_finish_transfers(void)
207{
208}
209
210static IRAM_ATTR bool hci_uart_tl_rx_eof_callback(gdma_channel_handle_t dma_chan,
211 gdma_event_data_t *event_data, void *user_data)
212{
213 assert(dma_chan == s_rx_channel);
214 assert(uart_env.rx.callback != NULL);
215 esp_bt_hci_tl_callback_t callback = uart_env.rx.callback;
216 void *arg = uart_env.rx.arg;
217
218 // clear callback pointer
219 uart_env.rx.callback = NULL;
220 uart_env.rx.arg = NULL;
221
222 // call handler
223 callback(arg, ESP_BT_HCI_TL_STATUS_OK);
224
225 // send notification to Bluetooth Controller task
226 esp_bt_h4tl_eif_io_event_notify(1);
227
228 return true;
229}
230
231static IRAM_ATTR bool hci_uart_tl_tx_eof_callback(gdma_channel_handle_t dma_chan,
232 gdma_event_data_t *event_data, void *user_data)
233{
234 assert(dma_chan == s_tx_channel);
235 assert(uart_env.tx.callback != NULL);
236 esp_bt_hci_tl_callback_t callback = uart_env.tx.callback;
237 void *arg = uart_env.tx.arg;
238
239 // clear callback pointer
240 uart_env.tx.callback = NULL;
241 uart_env.tx.arg = NULL;
242
243 // call handler
244 callback(arg, ESP_BT_HCI_TL_STATUS_OK);
245
246 // send notification to Bluetooth Controller task
247 esp_bt_h4tl_eif_io_event_notify(1);
248
249 return true;
250}
251#endif
252
2fcc401a 253static void init_uart(void)
254{
255#if BLUETOOTH_UART == 1
256 periph_module_enable(PERIPH_UART1_MODULE);
257 periph_module_reset(PERIPH_UART1_MODULE);
258#elif BLUETOOTH_UART == 2
259 periph_module_enable(PERIPH_UART2_MODULE);
260 periph_module_reset(PERIPH_UART2_MODULE);
261#endif
262
263 periph_module_enable(PERIPH_UHCI0_MODULE);
264 periph_module_reset(PERIPH_UHCI0_MODULE);
265
47a682ac 266#ifdef CONFIG_IDF_TARGET_ESP32C3
267 gpio_config_t io_output_conf = {
268 .intr_type = GPIO_PIN_INTR_DISABLE, //disable interrupt
269 .mode = GPIO_MODE_OUTPUT, // output mode
270 .pin_bit_mask = GPIO_OUTPUT_PIN_SEL, // bit mask of the output pins
271 .pull_down_en = 0, // disable pull-down mode
272 .pull_up_en = 0, // disable pull-up mode
273 };
274 gpio_config(&io_output_conf);
275
276 gpio_config_t io_input_conf = {
277 .intr_type = GPIO_PIN_INTR_DISABLE, //disable interrupt
278 .mode = GPIO_MODE_INPUT, // input mode
279 .pin_bit_mask = GPIO_INPUT_PIN_SEL, // bit mask of the input pins
280 .pull_down_en = 0, // disable pull-down mode
281 .pull_up_en = 0, // disable pull-down mode
282 };
283 gpio_config(&io_input_conf);
284#endif
285
2fcc401a 286 ESP_ERROR_CHECK( uart_set_pin(BLUETOOTH_UART, BT_TX_PIN,
287 BT_RX_PIN, BT_RTS_PIN, BT_CTS_PIN) );
288
47a682ac 289#ifdef CONFIG_IDF_TARGET_ESP32C3
290 // configure UART1
291 ESP_LOGI(BT_TAG, "baud rate for HCI uart :: %d \n",
292 CONFIG_EXAMPLE_ESP32C3_HCI_UART_BAUDRATE);
293
294 uart_config_t uart_config = {
295 .baud_rate = CONFIG_EXAMPLE_ESP32C3_HCI_UART_BAUDRATE,
296
297 .data_bits = UART_DATA_8_BITS,
298 .parity = UART_PARITY_DISABLE,
299 .stop_bits = UART_STOP_BITS_1,
300 .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS,
301 .rx_flow_ctrl_thresh = UART_RX_THRS,
302 .source_clk = UART_SCLK_APB,
303 };
304 ESP_ERROR_CHECK(uart_param_config(BLUETOOTH_UART, &uart_config));
305
306 // install DMA driver
307 gdma_channel_alloc_config_t tx_channel_config = {
308 .flags.reserve_sibling = 1,
309 .direction = GDMA_CHANNEL_DIRECTION_TX,
310 };
311 ESP_ERROR_CHECK(gdma_new_channel(&tx_channel_config, &s_tx_channel));
312 gdma_channel_alloc_config_t rx_channel_config = {
313 .direction = GDMA_CHANNEL_DIRECTION_RX,
314 .sibling_chan = s_tx_channel,
315 };
316 ESP_ERROR_CHECK(gdma_new_channel(&rx_channel_config, &s_rx_channel));
317
318 gdma_connect(s_tx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_UART, 0));
319 gdma_connect(s_rx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_UART, 0));
320
321 gdma_strategy_config_t strategy_config = {
322 .auto_update_desc = false,
323 .owner_check = false
324 };
325 gdma_apply_strategy(s_tx_channel, &strategy_config);
326 gdma_apply_strategy(s_rx_channel, &strategy_config);
327
328 gdma_rx_event_callbacks_t rx_cbs = {
329 .on_recv_eof = hci_uart_tl_rx_eof_callback
330 };
331 gdma_register_rx_event_callbacks(s_rx_channel, &rx_cbs, NULL);
332
333 gdma_tx_event_callbacks_t tx_cbs = {
334 .on_trans_eof = hci_uart_tl_tx_eof_callback
335 };
336 gdma_register_tx_event_callbacks(s_tx_channel, &tx_cbs, NULL);
337
338 // configure UHCI
339 uhci_ll_init(s_uhci_hw);
340 uhci_ll_set_eof_mode(s_uhci_hw, UHCI_RX_LEN_EOF);
341 // disable software flow control
342 s_uhci_hw->escape_conf.val = 0;
343 uhci_ll_attach_uart_port(s_uhci_hw, 1);
344#endif
2fcc401a 345}
346
347#endif
348
349esp_err_t initialise_bluetooth(void)
350{
351 esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
352
47a682ac 353
2fcc401a 354#ifdef BLUETOOTH_UART
47a682ac 355 #ifdef CONFIG_IDF_TARGET_ESP32C3
356 bt_cfg.hci_tl_funcs = &s_hci_uart_tl_funcs;
357 #endif
358
2fcc401a 359 init_uart();
360#endif
361 ESP_ERROR_CHECK( esp_bt_controller_init(&bt_cfg) );
362#if BLUETOOTH_BLE
363 ESP_ERROR_CHECK( esp_bt_controller_enable(ESP_BT_MODE_BLE) );
364#elif BLUETOOTH_BT
365 ESP_ERROR_CHECK( esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT) );
366#elif BLUETOOTH_BT_BLE
367 ESP_ERROR_CHECK( esp_bt_controller_enable(ESP_BT_MODE_BTDM) );
368#endif
369
370#if BLUETOOTH_HCI
371 esp_err_t ret = ESP_OK;
372 ret = esp_vhci_host_register_callback(&vhci_host_cb);
373
374 if (ret != ESP_OK) {
375 ESP_LOGE(BT_TAG, "Failed to register VHCI callback");
376 return ret;
377 }
378
379 vhci_send_sem = xSemaphoreCreateBinary();
380 if (vhci_send_sem == NULL) {
381 ESP_LOGE(BT_TAG, "Failed to create VHCI send sem");
382 return ESP_ERR_NO_MEM;
383 }
384
385 xSemaphoreGive(vhci_send_sem);
386#endif
387
388 return ESP_OK;
389}
390
391void deinitialize_bluetooth(void)
392{
393#if BLUETOOTH_HCI
394 if (vhci_send_sem) {
395 /* Dummy take and give sema before deleting it */
396 xSemaphoreTake(vhci_send_sem, portMAX_DELAY);
397 xSemaphoreGive(vhci_send_sem);
398 vSemaphoreDelete(vhci_send_sem);
399 vhci_send_sem = NULL;
400 }
401 esp_bt_controller_disable();
402 esp_bt_controller_deinit();
403#endif
404}
405
406uint8_t get_bluetooth_capabilities(void)
407{
408 uint8_t cap = 0;
409 ESP_LOGI(BT_TAG, "- BT/BLE");
410#if BLUETOOTH_HCI
411#if CONFIG_ESP_SPI_HOST_INTERFACE
412 ESP_LOGI(BT_TAG, " - HCI Over SPI");
413 cap |= ESP_BT_SPI_SUPPORT;
414#else
415 ESP_LOGI(BT_TAG, " - HCI Over SDIO");
416 cap |= ESP_BT_SDIO_SUPPORT;
417#endif
418#elif BLUETOOTH_UART
419 ESP_LOGI(BT_TAG, " - HCI Over UART");
420 cap |= ESP_BT_UART_SUPPORT;
421#endif
422
423#if BLUETOOTH_BLE
424 ESP_LOGI(BT_TAG, " - BLE only");
425 cap |= ESP_BLE_ONLY_SUPPORT;
426#elif BLUETOOTH_BT
427 ESP_LOGI(BT_TAG, " - BR_EDR only");
428 cap |= ESP_BR_EDR_ONLY_SUPPORT;
429#elif BLUETOOTH_BT_BLE
430 ESP_LOGI(BT_TAG, " - BT/BLE dual mode");
431 cap |= ESP_BLE_ONLY_SUPPORT | ESP_BR_EDR_ONLY_SUPPORT;
432#endif
433 return cap;
434}
435
436
437#endif
This page took 0.069463 seconds and 4 git commands to generate.