mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(bt/bluedroid): Added bt_discovery based host only example
This commit is contained in:
parent
b9ed6f722b
commit
59e504ef27
@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(host_hci_uart)
|
@ -0,0 +1,85 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
ESP-IDF UART HCI Host
|
||||
=====================
|
||||
|
||||
This is a Bluetooth Host use UART as HCI IO. This require the UART device support RTS/CTS mandatory.
|
||||
|
||||
It can do the configuration of UART baudrate by menuconfig.
|
||||
|
||||
## Example Layout
|
||||
|
||||
This example is modified based on [bt_discovery](../../classic_bt/bt_discovery), and all modifications are listed below:
|
||||
|
||||
- Removed all dependencies on controller from `main.c`.
|
||||
|
||||
```
|
||||
#include "esp_bt.h"
|
||||
|
||||
...
|
||||
|
||||
ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE));
|
||||
|
||||
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
|
||||
if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) {
|
||||
ESP_LOGE(GAP_TAG, "%s initialize controller failed: %s", __func__, esp_err_to_name(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ret = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) {
|
||||
ESP_LOGE(GAP_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret));
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
- Add support for uart driver: `uart_driver.c` and `uart_driver.h`.
|
||||
|
||||
- Initialize UART driver in `main.c`.
|
||||
|
||||
```
|
||||
#include "esp_hci_api.h"
|
||||
#include "uart_driver.h"
|
||||
|
||||
...
|
||||
|
||||
/* initialize HCI TRANSPORT first */
|
||||
hci_uart_open();
|
||||
/* get HCI driver operations */
|
||||
esp_bluedroid_hci_driver_operations_t operations = {
|
||||
.send = hci_uart_send,
|
||||
.check_send_available = hci_check_send_available,
|
||||
.register_host_callback = hci_register_host_callback,
|
||||
};
|
||||
esp_bluedroid_attach_hci_driver(&operations);
|
||||
```
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware Required
|
||||
|
||||
This example should be able to run on any commonly available ESP development board. To connect UART to another board running a Bluetooth controller. For example, [controller_hci_uart_esp32](../../../hci/controller_hci_uart_esp32).
|
||||
|
||||
### Configure the project
|
||||
|
||||
```
|
||||
idf.py menuconfig
|
||||
```
|
||||
|
||||
- UART baudrate can be configured in `Example Configuration > UART Baudrate for HCI`
|
||||
|
||||
### Build and Flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output:
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(Replace PORT with the name of the serial port to use.)
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Troubleshooting
|
@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "main.c"
|
||||
"uart_driver.c"
|
||||
INCLUDE_DIRS ".")
|
@ -0,0 +1,8 @@
|
||||
menu "Example Configuration"
|
||||
config EXAMPLE_HCI_UART_BAUDRATE
|
||||
int "UART Baudrate for HCI"
|
||||
range 115200 921600
|
||||
default 921600
|
||||
help
|
||||
UART Baudrate for HCI. Please use standard baudrate.
|
||||
endmenu
|
@ -0,0 +1,306 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* This file is for Classic Bluetooth device and service discovery Demo.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "nvs.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_bt_device.h"
|
||||
#include "esp_gap_bt_api.h"
|
||||
#include "esp_bluedroid_hci.h"
|
||||
#include "uart_driver.h"
|
||||
|
||||
#define GAP_TAG "GAP"
|
||||
|
||||
typedef enum {
|
||||
APP_GAP_STATE_IDLE = 0,
|
||||
APP_GAP_STATE_DEVICE_DISCOVERING,
|
||||
APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE,
|
||||
APP_GAP_STATE_SERVICE_DISCOVERING,
|
||||
APP_GAP_STATE_SERVICE_DISCOVER_COMPLETE,
|
||||
} app_gap_state_t;
|
||||
|
||||
typedef struct {
|
||||
bool dev_found;
|
||||
uint8_t bdname_len;
|
||||
uint8_t eir_len;
|
||||
uint8_t rssi;
|
||||
uint32_t cod;
|
||||
uint8_t eir[ESP_BT_GAP_EIR_DATA_LEN];
|
||||
uint8_t bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
|
||||
esp_bd_addr_t bda;
|
||||
app_gap_state_t state;
|
||||
} app_gap_cb_t;
|
||||
|
||||
static app_gap_cb_t m_dev_info;
|
||||
|
||||
static char *bda2str(esp_bd_addr_t bda, char *str, size_t size)
|
||||
{
|
||||
if (bda == NULL || str == NULL || size < 18) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t *p = bda;
|
||||
sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
p[0], p[1], p[2], p[3], p[4], p[5]);
|
||||
return str;
|
||||
}
|
||||
|
||||
static char *uuid2str(esp_bt_uuid_t *uuid, char *str, size_t size)
|
||||
{
|
||||
if (uuid == NULL || str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (uuid->len == 2 && size >= 5) {
|
||||
sprintf(str, "%04x", uuid->uuid.uuid16);
|
||||
} else if (uuid->len == 4 && size >= 9) {
|
||||
sprintf(str, "%08"PRIx32, uuid->uuid.uuid32);
|
||||
} else if (uuid->len == 16 && size >= 37) {
|
||||
uint8_t *p = uuid->uuid.uuid128;
|
||||
sprintf(str, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
p[15], p[14], p[13], p[12], p[11], p[10], p[9], p[8],
|
||||
p[7], p[6], p[5], p[4], p[3], p[2], p[1], p[0]);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
static bool get_name_from_eir(uint8_t *eir, uint8_t *bdname, uint8_t *bdname_len)
|
||||
{
|
||||
uint8_t *rmt_bdname = NULL;
|
||||
uint8_t rmt_bdname_len = 0;
|
||||
|
||||
if (!eir) {
|
||||
return false;
|
||||
}
|
||||
|
||||
rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME, &rmt_bdname_len);
|
||||
if (!rmt_bdname) {
|
||||
rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME, &rmt_bdname_len);
|
||||
}
|
||||
|
||||
if (rmt_bdname) {
|
||||
if (rmt_bdname_len > ESP_BT_GAP_MAX_BDNAME_LEN) {
|
||||
rmt_bdname_len = ESP_BT_GAP_MAX_BDNAME_LEN;
|
||||
}
|
||||
|
||||
if (bdname) {
|
||||
memcpy(bdname, rmt_bdname, rmt_bdname_len);
|
||||
bdname[rmt_bdname_len] = '\0';
|
||||
}
|
||||
if (bdname_len) {
|
||||
*bdname_len = rmt_bdname_len;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void update_device_info(esp_bt_gap_cb_param_t *param)
|
||||
{
|
||||
char bda_str[18];
|
||||
uint32_t cod = 0;
|
||||
int32_t rssi = -129; /* invalid value */
|
||||
uint8_t *bdname = NULL;
|
||||
uint8_t bdname_len = 0;
|
||||
uint8_t *eir = NULL;
|
||||
uint8_t eir_len = 0;
|
||||
esp_bt_gap_dev_prop_t *p;
|
||||
|
||||
ESP_LOGI(GAP_TAG, "Device found: %s", bda2str(param->disc_res.bda, bda_str, 18));
|
||||
for (int i = 0; i < param->disc_res.num_prop; i++) {
|
||||
p = param->disc_res.prop + i;
|
||||
switch (p->type) {
|
||||
case ESP_BT_GAP_DEV_PROP_COD:
|
||||
cod = *(uint32_t *)(p->val);
|
||||
ESP_LOGI(GAP_TAG, "--Class of Device: 0x%"PRIx32, cod);
|
||||
break;
|
||||
case ESP_BT_GAP_DEV_PROP_RSSI:
|
||||
rssi = *(int8_t *)(p->val);
|
||||
ESP_LOGI(GAP_TAG, "--RSSI: %"PRId32, rssi);
|
||||
break;
|
||||
case ESP_BT_GAP_DEV_PROP_BDNAME:
|
||||
bdname_len = (p->len > ESP_BT_GAP_MAX_BDNAME_LEN) ? ESP_BT_GAP_MAX_BDNAME_LEN :
|
||||
(uint8_t)p->len;
|
||||
bdname = (uint8_t *)(p->val);
|
||||
break;
|
||||
case ESP_BT_GAP_DEV_PROP_EIR: {
|
||||
eir_len = p->len;
|
||||
eir = (uint8_t *)(p->val);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* search for device with Major device type "PHONE" or "Audio/Video" in COD */
|
||||
app_gap_cb_t *p_dev = &m_dev_info;
|
||||
if (p_dev->dev_found) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!esp_bt_gap_is_valid_cod(cod) ||
|
||||
(!(esp_bt_gap_get_cod_major_dev(cod) == ESP_BT_COD_MAJOR_DEV_PHONE) &&
|
||||
!(esp_bt_gap_get_cod_major_dev(cod) == ESP_BT_COD_MAJOR_DEV_AV))) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(p_dev->bda, param->disc_res.bda, ESP_BD_ADDR_LEN);
|
||||
p_dev->dev_found = true;
|
||||
|
||||
p_dev->cod = cod;
|
||||
p_dev->rssi = rssi;
|
||||
if (bdname_len > 0) {
|
||||
memcpy(p_dev->bdname, bdname, bdname_len);
|
||||
p_dev->bdname[bdname_len] = '\0';
|
||||
p_dev->bdname_len = bdname_len;
|
||||
}
|
||||
if (eir_len > 0) {
|
||||
memcpy(p_dev->eir, eir, eir_len);
|
||||
p_dev->eir_len = eir_len;
|
||||
}
|
||||
|
||||
if (p_dev->bdname_len == 0) {
|
||||
get_name_from_eir(p_dev->eir, p_dev->bdname, &p_dev->bdname_len);
|
||||
}
|
||||
|
||||
ESP_LOGI(GAP_TAG, "Found a target device, address %s, name %s", bda_str, p_dev->bdname);
|
||||
p_dev->state = APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE;
|
||||
ESP_LOGI(GAP_TAG, "Cancel device discovery ...");
|
||||
esp_bt_gap_cancel_discovery();
|
||||
}
|
||||
|
||||
static void bt_app_gap_init(void)
|
||||
{
|
||||
app_gap_cb_t *p_dev = &m_dev_info;
|
||||
memset(p_dev, 0, sizeof(app_gap_cb_t));
|
||||
|
||||
p_dev->state = APP_GAP_STATE_IDLE;
|
||||
}
|
||||
|
||||
static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
|
||||
{
|
||||
app_gap_cb_t *p_dev = &m_dev_info;
|
||||
char bda_str[18];
|
||||
char uuid_str[37];
|
||||
|
||||
switch (event) {
|
||||
case ESP_BT_GAP_DISC_RES_EVT: {
|
||||
update_device_info(param);
|
||||
break;
|
||||
}
|
||||
case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: {
|
||||
if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) {
|
||||
ESP_LOGI(GAP_TAG, "Device discovery stopped.");
|
||||
if ( (p_dev->state == APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE ||
|
||||
p_dev->state == APP_GAP_STATE_DEVICE_DISCOVERING)
|
||||
&& p_dev->dev_found) {
|
||||
p_dev->state = APP_GAP_STATE_SERVICE_DISCOVERING;
|
||||
ESP_LOGI(GAP_TAG, "Discover services ...");
|
||||
esp_bt_gap_get_remote_services(p_dev->bda);
|
||||
}
|
||||
} else if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STARTED) {
|
||||
ESP_LOGI(GAP_TAG, "Discovery started.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ESP_BT_GAP_RMT_SRVCS_EVT: {
|
||||
if (memcmp(param->rmt_srvcs.bda, p_dev->bda, ESP_BD_ADDR_LEN) == 0 &&
|
||||
p_dev->state == APP_GAP_STATE_SERVICE_DISCOVERING) {
|
||||
p_dev->state = APP_GAP_STATE_SERVICE_DISCOVER_COMPLETE;
|
||||
if (param->rmt_srvcs.stat == ESP_BT_STATUS_SUCCESS) {
|
||||
ESP_LOGI(GAP_TAG, "Services for device %s found", bda2str(p_dev->bda, bda_str, 18));
|
||||
for (int i = 0; i < param->rmt_srvcs.num_uuids; i++) {
|
||||
esp_bt_uuid_t *u = param->rmt_srvcs.uuid_list + i;
|
||||
ESP_LOGI(GAP_TAG, "--%s", uuid2str(u, uuid_str, 37));
|
||||
}
|
||||
} else {
|
||||
ESP_LOGI(GAP_TAG, "Services for device %s not found", bda2str(p_dev->bda, bda_str, 18));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ESP_BT_GAP_RMT_SRVC_REC_EVT:
|
||||
default: {
|
||||
ESP_LOGI(GAP_TAG, "event: %d", event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void bt_app_gap_start_up(void)
|
||||
{
|
||||
/* register GAP callback function */
|
||||
esp_bt_gap_register_callback(bt_app_gap_cb);
|
||||
|
||||
char *dev_name = "ESP_GAP_INQRUIY";
|
||||
esp_bt_dev_set_device_name(dev_name);
|
||||
|
||||
/* set discoverable and connectable mode, wait to be connected */
|
||||
esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
|
||||
|
||||
/* inititialize device information and status */
|
||||
bt_app_gap_init();
|
||||
|
||||
/* start to discover nearby Bluetooth devices */
|
||||
app_gap_cb_t *p_dev = &m_dev_info;
|
||||
p_dev->state = APP_GAP_STATE_DEVICE_DISCOVERING;
|
||||
esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
/* Initialize NVS — it is used to store PHY calibration data and save key-value pairs in flash memory*/
|
||||
esp_err_t ret = nvs_flash_init();
|
||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ret = nvs_flash_init();
|
||||
}
|
||||
ESP_ERROR_CHECK( ret );
|
||||
|
||||
/* initialize HCI TRANSPORT first */
|
||||
hci_uart_open();
|
||||
/* get HCI driver operations */
|
||||
esp_bluedroid_hci_driver_operations_t operations = {
|
||||
.send = hci_uart_send,
|
||||
.check_send_available = hci_check_send_available,
|
||||
.register_host_callback = hci_register_host_callback,
|
||||
};
|
||||
esp_bluedroid_attach_hci_driver(&operations);
|
||||
|
||||
esp_bluedroid_config_t bluedroid_cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT();
|
||||
if ((ret = esp_bluedroid_init_with_cfg(&bluedroid_cfg)) != ESP_OK) {
|
||||
ESP_LOGE(GAP_TAG, "%s initialize bluedroid failed: %s", __func__, esp_err_to_name(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ret = esp_bluedroid_enable()) != ESP_OK) {
|
||||
ESP_LOGE(GAP_TAG, "%s enable bluedroid failed: %s", __func__, esp_err_to_name(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
bt_app_gap_start_up();
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "driver/uart.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_bluedroid_hci.h"
|
||||
#include "uart_driver.h"
|
||||
|
||||
#define TAG "UART_HCI"
|
||||
|
||||
#define UART_NO (1)
|
||||
#define UART_BUF_SZ (1024)
|
||||
|
||||
#define UART_TX_PIN (5)
|
||||
#define UART_RX_PIN (18)
|
||||
#define UART_RTS_PIN (19)
|
||||
#define UART_CTS_PIN (23)
|
||||
|
||||
enum {
|
||||
UART_RX_TYPE = 0,
|
||||
UART_RX_LEN,
|
||||
UART_RX_DATA,
|
||||
};
|
||||
|
||||
enum {
|
||||
DATA_TYPE_COMMAND = 1,
|
||||
DATA_TYPE_ACL = 2,
|
||||
DATA_TYPE_SCO = 3,
|
||||
DATA_TYPE_EVENT = 4
|
||||
};
|
||||
|
||||
TaskHandle_t s_rx_task_hdl;
|
||||
esp_bluedroid_hci_driver_callbacks_t s_callback = { 0 };
|
||||
|
||||
static void IRAM_ATTR hci_uart_rx_task(void *arg)
|
||||
{
|
||||
uint8_t buf[1026];
|
||||
int len_now_read = -1;
|
||||
uint32_t len_to_read = 1;
|
||||
uint32_t len_total_read = 0;
|
||||
uint8_t rx_st = UART_RX_TYPE;
|
||||
|
||||
while (1) {
|
||||
len_now_read = uart_read_bytes(UART_NO, &buf[len_total_read], len_to_read, portMAX_DELAY);
|
||||
assert(len_now_read == len_to_read);
|
||||
len_total_read += len_now_read;
|
||||
|
||||
switch (rx_st) {
|
||||
case UART_RX_TYPE: {
|
||||
assert(buf[0] >= DATA_TYPE_ACL && buf[0] <= DATA_TYPE_EVENT);
|
||||
if (buf[0] == DATA_TYPE_ACL) {
|
||||
len_to_read = 4;
|
||||
} else if (buf[0] == DATA_TYPE_SCO) {
|
||||
len_to_read = 3;
|
||||
} else if (buf[0] == DATA_TYPE_EVENT) {
|
||||
len_to_read = 2;
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
rx_st = UART_RX_LEN;
|
||||
}
|
||||
break;
|
||||
|
||||
case UART_RX_LEN: {
|
||||
if (buf[0] == DATA_TYPE_ACL) {
|
||||
len_to_read = buf[3] | (buf[4] << 8);
|
||||
} else if (buf[0] == DATA_TYPE_SCO) {
|
||||
len_to_read = buf[3];
|
||||
} else if (buf[0] == DATA_TYPE_EVENT) {
|
||||
len_to_read = buf[2];
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
rx_st = UART_RX_DATA;
|
||||
}
|
||||
break;
|
||||
|
||||
case UART_RX_DATA: {
|
||||
if (s_callback.notify_host_recv) {
|
||||
s_callback.notify_host_recv(buf, len_total_read);
|
||||
}
|
||||
|
||||
rx_st = UART_RX_TYPE;
|
||||
len_to_read = 1;
|
||||
len_total_read = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default: {
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void hci_uart_send(uint8_t *buf, uint16_t len)
|
||||
{
|
||||
uint8_t *p = buf;
|
||||
int len_write = 0;
|
||||
|
||||
while (len) {
|
||||
len_write = uart_write_bytes(UART_NO, p, len);
|
||||
assert(len_write > 0);
|
||||
len -= len_write;
|
||||
p += len_write;
|
||||
}
|
||||
}
|
||||
|
||||
bool hci_check_send_available(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
esp_err_t hci_register_host_callback(const esp_bluedroid_hci_driver_callbacks_t *callback)
|
||||
{
|
||||
s_callback.notify_host_send_available = callback->notify_host_send_available;
|
||||
s_callback.notify_host_recv = callback->notify_host_recv;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void hci_uart_open(void)
|
||||
{
|
||||
uart_config_t uart_config = {
|
||||
.baud_rate = CONFIG_EXAMPLE_HCI_UART_BAUDRATE,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
.rx_flow_ctrl_thresh = UART_HW_FIFO_LEN(UART_NO) - 1,
|
||||
};
|
||||
|
||||
int intr_alloc_flags = 0;
|
||||
#if CONFIG_UART_ISR_IN_IRAM
|
||||
intr_alloc_flags = ESP_INTR_FLAG_IRAM;
|
||||
#endif
|
||||
|
||||
ESP_ERROR_CHECK(uart_driver_install(UART_NO, UART_BUF_SZ * 2, UART_BUF_SZ * 2, 0, NULL, intr_alloc_flags));
|
||||
ESP_ERROR_CHECK(uart_param_config(UART_NO, &uart_config));
|
||||
ESP_ERROR_CHECK(uart_set_pin(UART_NO, UART_TX_PIN, UART_RX_PIN, UART_RTS_PIN, UART_CTS_PIN));
|
||||
|
||||
xTaskCreate(hci_uart_rx_task, "hci_uart_rx_task", 2048, NULL, 12, &s_rx_task_hdl);
|
||||
}
|
||||
|
||||
void hci_uart_close(void)
|
||||
{
|
||||
if (s_rx_task_hdl) {
|
||||
vTaskDelete(s_rx_task_hdl);
|
||||
}
|
||||
uart_driver_delete(UART_NO);
|
||||
memset(&s_callback, 0, sizeof(esp_bluedroid_hci_driver_callbacks_t));
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
#ifndef __UART_DRIVER_H__
|
||||
#define __UART_DRIVER_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_bluedroid_hci.h"
|
||||
|
||||
/**
|
||||
* @brief open HCI transport of uart
|
||||
*/
|
||||
void hci_uart_open(void);
|
||||
|
||||
/**
|
||||
* @brief close HCI transport of uart
|
||||
*/
|
||||
void hci_uart_close(void);
|
||||
|
||||
/**
|
||||
* @brief send data from host to HCI transport
|
||||
*
|
||||
* @param[in] data pointer to data buffer
|
||||
* @param[in] len length of data
|
||||
*/
|
||||
void hci_uart_send(uint8_t *data, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief host checks whether it can send data to HCI transport
|
||||
*
|
||||
* @return true if host can send data, false otherwise
|
||||
*/
|
||||
bool hci_check_send_available(void);
|
||||
|
||||
/**
|
||||
* @brief register host callbacks
|
||||
*
|
||||
* @param[in] callback HCI driver callbacks
|
||||
*/
|
||||
esp_err_t hci_register_host_callback(const esp_bluedroid_hci_driver_callbacks_t *callback);
|
||||
|
||||
#endif /* __UART_DRIVER_H__ */
|
@ -0,0 +1,4 @@
|
||||
CONFIG_BT_CONTROLLER_DISABLED=y
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BT_BLUEDROID_ENABLED=y
|
||||
CONFIG_BT_CLASSIC_ENABLED=y
|
Loading…
Reference in New Issue
Block a user