mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Added example(ESP32-C3), to use Bluetooth Controller through HCI UART transport
This commit is contained in:
parent
b455299bb0
commit
59c0825ed8
@ -93,6 +93,13 @@ enum {
|
||||
ESP_BT_COEX_PHY_CODED_TX_RX_TIME_LIMIT_FORCE_ENABLE, /*!< Always Enable the limit */
|
||||
};
|
||||
|
||||
#define ESP_BT_HCI_TL_STATUS_OK (0) /*!< HCI_TL Tx/Rx operation status OK */
|
||||
|
||||
/**
|
||||
* @brief callback function for HCI Transport Layer send/receive operations
|
||||
*/
|
||||
typedef void (* esp_bt_hci_tl_callback_t) (void *arg, uint8_t status);
|
||||
|
||||
#ifdef CONFIG_BT_ENABLED
|
||||
|
||||
#define BT_CTRL_BLE_MAX_ACT_LIMIT 10 //Maximum BLE activity limitation
|
||||
@ -180,8 +187,8 @@ typedef struct {
|
||||
int (* _open)(void); /* hci tl open */
|
||||
void (* _close)(void); /* hci tl close */
|
||||
void (* _finish_transfers)(void); /* hci tl finish trasnfers */
|
||||
void (* _recv)(uint8_t *buf, uint32_t len, void (*callback) (void*, uint8_t), void* dummy); /* hci tl recv */
|
||||
void (* _send)(uint8_t *buf, uint32_t len, void (*callback) (void*, uint8_t), void* dummy); /* hci tl send */
|
||||
void (* _recv)(uint8_t *buf, uint32_t len, esp_bt_hci_tl_callback_t callback, void* arg); /* hci tl recv */
|
||||
void (* _send)(uint8_t *buf, uint32_t len, esp_bt_hci_tl_callback_t callback, void* arg); /* hci tl send */
|
||||
bool (* _flow_off)(void); /* hci tl flow off */
|
||||
void (* _flow_on)(void); /* hci tl flow on */
|
||||
} esp_bt_hci_tl_t;
|
||||
|
@ -93,6 +93,13 @@ enum {
|
||||
ESP_BT_COEX_PHY_CODED_TX_RX_TIME_LIMIT_FORCE_ENABLE, /*!< Always Enable the limit */
|
||||
};
|
||||
|
||||
#define ESP_BT_HCI_TL_STATUS_OK (0) /*!< HCI_TL Tx/Rx operation status OK */
|
||||
|
||||
/**
|
||||
* @brief callback function for HCI Transport Layer send/receive operations
|
||||
*/
|
||||
typedef void (* esp_bt_hci_tl_callback_t) (void *arg, uint8_t status);
|
||||
|
||||
#ifdef CONFIG_BT_ENABLED
|
||||
|
||||
#define BT_CTRL_BLE_MAX_ACT_LIMIT 10 //Maximum BLE activity limitation
|
||||
@ -180,8 +187,8 @@ typedef struct {
|
||||
int (* _open)(void); /* hci tl open */
|
||||
void (* _close)(void); /* hci tl close */
|
||||
void (* _finish_transfers)(void); /* hci tl finish trasnfers */
|
||||
void (* _recv)(uint8_t *buf, uint32_t len, void (*callback) (void*, uint8_t), void* dummy); /* hci tl recv */
|
||||
void (* _send)(uint8_t *buf, uint32_t len, void (*callback) (void*, uint8_t), void* dummy); /* hci tl send */
|
||||
void (* _recv)(uint8_t *buf, uint32_t len, esp_bt_hci_tl_callback_t callback, void* arg); /* hci tl recv */
|
||||
void (* _send)(uint8_t *buf, uint32_t len, esp_bt_hci_tl_callback_t callback, void* arg); /* hci tl send */
|
||||
bool (* _flow_off)(void); /* hci tl flow off */
|
||||
void (* _flow_on)(void); /* hci tl flow on */
|
||||
} esp_bt_hci_tl_t;
|
||||
|
@ -20,12 +20,16 @@
|
||||
#include <stdio.h>
|
||||
#include "uhci_types.h"
|
||||
#include "soc/uhci_struct.h"
|
||||
#include "soc/gdma_struct.h"
|
||||
|
||||
#define UHCI_DMA_INDEX 0
|
||||
|
||||
#define UHCI_LL_GET_HW(num) (((num) == 0) ? (&UHCI0) : (NULL))
|
||||
|
||||
typedef enum {
|
||||
UHCI_RX_BREAK_CHR_EOF = 0x1,
|
||||
UHCI_RX_IDLE_EOF = 0x2,
|
||||
UHCI_RX_LEN_EOF = 0x4,
|
||||
UHCI_RX_EOF_MAX = 0x7,
|
||||
} uhci_rxeof_cfg_t;
|
||||
|
||||
static inline void uhci_ll_init(uhci_dev_t *hw)
|
||||
{
|
||||
typeof(hw->conf0) conf0_reg;
|
||||
@ -38,7 +42,8 @@ static inline void uhci_ll_init(uhci_dev_t *hw)
|
||||
|
||||
static inline void uhci_ll_attach_uart_port(uhci_dev_t *hw, int uart_num)
|
||||
{
|
||||
abort(); // TODO ESP32-C3 IDF-2117
|
||||
hw->conf0.uart0_ce = (uart_num == 0)? 1: 0;
|
||||
hw->conf0.uart1_ce = (uart_num == 1)? 1: 0;
|
||||
}
|
||||
|
||||
static inline void uhci_ll_set_seper_chr(uhci_dev_t *hw, uhci_seper_chr_t *seper_char)
|
||||
@ -90,20 +95,6 @@ static inline void uhci_ll_set_swflow_ctrl_sub_chr(uhci_dev_t *hw, uhci_swflow_c
|
||||
hw->escape_conf.val = escape_conf_reg.val;
|
||||
}
|
||||
|
||||
static inline void uhci_ll_dma_in_reset(uhci_dev_t *hw)
|
||||
{
|
||||
(void)hw;
|
||||
GDMA.channel[UHCI_DMA_INDEX].in.in_conf0.in_rst = 1;
|
||||
GDMA.channel[UHCI_DMA_INDEX].in.in_conf0.in_rst = 0;
|
||||
}
|
||||
|
||||
static inline void uhci_ll_dma_out_reset(uhci_dev_t *hw)
|
||||
{
|
||||
(void)hw;
|
||||
GDMA.channel[UHCI_DMA_INDEX].out.out_conf0.out_rst = 1;
|
||||
GDMA.channel[UHCI_DMA_INDEX].out.out_conf0.out_rst = 0;
|
||||
}
|
||||
|
||||
static inline void uhci_ll_enable_intr(uhci_dev_t *hw, uint32_t intr_mask)
|
||||
{
|
||||
hw->int_ena.val |= intr_mask;
|
||||
@ -124,41 +115,6 @@ static inline uint32_t uhci_ll_get_intr(uhci_dev_t *hw)
|
||||
return hw->int_st.val;
|
||||
}
|
||||
|
||||
static inline void uhci_ll_set_rx_dma(uhci_dev_t *hw, uint32_t addr)
|
||||
{
|
||||
(void)hw;
|
||||
GDMA.channel[UHCI_DMA_INDEX].in.in_link.addr = addr;
|
||||
}
|
||||
|
||||
static inline void uhci_ll_set_tx_dma(uhci_dev_t *hw, uint32_t addr)
|
||||
{
|
||||
(void)hw;
|
||||
GDMA.channel[UHCI_DMA_INDEX].out.out_link.addr = addr;
|
||||
}
|
||||
|
||||
static inline void uhci_ll_rx_dma_start(uhci_dev_t *hw)
|
||||
{
|
||||
(void)hw;
|
||||
GDMA.channel[UHCI_DMA_INDEX].in.in_link.start = 1;
|
||||
}
|
||||
|
||||
static inline void uhci_ll_tx_dma_start(uhci_dev_t *hw)
|
||||
{
|
||||
(void)hw;
|
||||
GDMA.channel[UHCI_DMA_INDEX].out.out_link.start = 1;
|
||||
}
|
||||
|
||||
static inline void uhci_ll_rx_dma_stop(uhci_dev_t *hw)
|
||||
{
|
||||
(void)hw;
|
||||
GDMA.channel[UHCI_DMA_INDEX].in.in_link.stop = 1;
|
||||
}
|
||||
|
||||
static inline void uhci_ll_tx_dma_stop(uhci_dev_t *hw)
|
||||
{
|
||||
(void)hw;
|
||||
GDMA.channel[UHCI_DMA_INDEX].out.out_link.stop = 1;
|
||||
}
|
||||
|
||||
static inline void uhci_ll_set_eof_mode(uhci_dev_t *hw, uint32_t eof_mode)
|
||||
{
|
||||
|
54
components/hal/esp32c3/include/hal/uhci_types.h
Normal file
54
components/hal/esp32c3/include/hal/uhci_types.h
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
|
||||
// Though the UHCI driver hasn't been published, some types are defined here
|
||||
// for users to develop over the HAL. See example: controller_hci_uart_esp32c3
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @brief UHCI escape sequence
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t seper_chr; /*!< escape sequence character */
|
||||
uint8_t sub_chr1; /*!< escape sequence sub-character 1 */
|
||||
uint8_t sub_chr2; /*!< escape sequence sub-character 2 */
|
||||
bool sub_chr_en; /*!< enable use of sub-chaacter of escape sequence */
|
||||
} uhci_seper_chr_t;
|
||||
|
||||
/**
|
||||
* @brief UHCI software flow control
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t xon_chr; /*!< character for XON */
|
||||
uint8_t xon_sub1; /*!< sub-character 1 for XON */
|
||||
uint8_t xon_sub2; /*!< sub-character 2 for XON */
|
||||
uint8_t xoff_chr; /*!< character 2 for XOFF */
|
||||
uint8_t xoff_sub1; /*!< sub-character 1 for XOFF */
|
||||
uint8_t xoff_sub2; /*!< sub-character 2 for XOFF */
|
||||
uint8_t flow_en; /*!< enable use of software flow control */
|
||||
} uhci_swflow_ctrl_sub_chr_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -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.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(controller_hci_uart_demo)
|
83
examples/bluetooth/hci/controller_hci_uart_esp32c3/README.md
Normal file
83
examples/bluetooth/hci/controller_hci_uart_esp32c3/README.md
Normal file
@ -0,0 +1,83 @@
|
||||
ESP-IDF UART HCI Controller
|
||||
=================================
|
||||
| Supported Targets | ESP32-C3 |
|
||||
| ----------------- | -------- |
|
||||
|
||||
This example demonstrates how to configure the Bluetooth Low Energy Controller's HCI (Host Controller Interface) to communicate over UART.
|
||||
|
||||
Using this example, BLE radio capabilities of ESP32-C3 chip, can be:
|
||||
|
||||
1. tested via standard HCI messages in Direct Test Mode
|
||||
|
||||
2. used with external Bluetooth host stack installed on PC, or other MCU.
|
||||
|
||||
This example uses UHCI, GDMA together with UART to implement the HCI UART transport.
|
||||
|
||||
This example uses LL/register access directly, because the UHCI driver hasn't been implemented yet.
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware Required
|
||||
|
||||
This example should be able to run on any commonly available ESP32-C3 development board. To connect UART to PC, another board such as ESP_Test Board or FT232 USB UART board is usually needed.
|
||||
|
||||
In this example, two UARTs are used:
|
||||
|
||||
- UART0 is used as normal output or by IDF monitor
|
||||
|
||||
- UART1 is used to convey HCI messages
|
||||
|
||||
|
||||
RTS and CTS lines of UART1 are required. GPIO4, GPIO5, GPIO6, GPIO7 are used as TxD, RxD, RTS, CTS PINs of UART1, respectively.
|
||||
|
||||
In a frequently-used scenario, if ESP_Test Board is used, connect the TX0, RX0, RTS0, CTS0 and GND of ESP_Test Board to ESP32-C3 UART1 PINs, and Attach ESP_Test board to the host PC.
|
||||
|
||||
### Configure the project
|
||||
|
||||
```
|
||||
idf.py menuconfig
|
||||
```
|
||||
|
||||
* Baudrate of UART1 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.
|
||||
|
||||
## Example Output
|
||||
|
||||
The example sets up the HCI UART transport and enable Bluetooth Controller, after started. UART1 PIN and baudrate settings is printed at serial output:
|
||||
|
||||
```
|
||||
I (296) gpio: GPIO[4]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
|
||||
I (296) gpio: GPIO[6]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
|
||||
I (306) gpio: GPIO[4]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
|
||||
I (316) gpio: GPIO[6]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
|
||||
I (326) BTDM_INIT: BT controller compile version [6ab3130]
|
||||
I (336) coexist: coexist rom version 8459080
|
||||
I (336) phy_init: phy_version 500,985899c,Apr 19 2021,16:05:08
|
||||
I (466) system_api: Base MAC address is not set
|
||||
I (466) system_api: read default base MAC address from EFUSE
|
||||
I (476) BTDM_INIT: Bluetooth MAC: 7c:df:a1:40:3f:16
|
||||
|
||||
I (476) UHCI: HCI messages can be communicated over UART1:
|
||||
--PINs: TxD 4, RxD 5, RTS 6, CTS 7
|
||||
--Baudrate: 921600
|
||||
```
|
||||
|
||||
After these output occurs, HCI messages can be commnunicated over UART1.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
## Example Breakdown
|
||||
|
@ -0,0 +1,2 @@
|
||||
idf_component_register(SRCS "uhci_uart_demo.c"
|
||||
INCLUDE_DIRS "")
|
@ -0,0 +1,10 @@
|
||||
menu "Example Configuration"
|
||||
|
||||
config EXAMPLE_HCI_UART_BAUDRATE
|
||||
int "UART Baudrate for HCI"
|
||||
range 115200 921600
|
||||
default 115200
|
||||
help
|
||||
UART Baudrate for HCI. Please use standard baudrate.
|
||||
|
||||
endmenu
|
@ -0,0 +1,280 @@
|
||||
/*
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/uart.h"
|
||||
#include "soc/lldesc.h"
|
||||
#include "esp_private/gdma.h"
|
||||
#include "hal/uhci_ll.h"
|
||||
#include "esp_bt.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *tag = "UHCI";
|
||||
|
||||
#define UART_HCI_NUM (1)
|
||||
|
||||
#define UART_RX_THRS (120)
|
||||
|
||||
#define GPIO_UART_TXD_OUT (4)
|
||||
#define GPIO_UART_RXD_IN (5)
|
||||
#define GPIO_UART_RTS_OUT (6)
|
||||
#define GPIO_UART_CTS_IN (7)
|
||||
|
||||
#define GPIO_OUTPUT_PIN_SEL ((1ULL<<GPIO_UART_TXD_OUT) | (1ULL<<GPIO_UART_RTS_OUT))
|
||||
#define GPIO_INPUT_PIN_SEL ((1ULL<<GPIO_UART_RXD_IN) | (1ULL<<GPIO_UART_CTS_IN))
|
||||
|
||||
// Operation functions for HCI UART Transport Layer
|
||||
static bool hci_uart_tl_init(void);
|
||||
static void hci_uart_tl_deinit(void);
|
||||
static void hci_uart_tl_recv_async(uint8_t *buf, uint32_t size, esp_bt_hci_tl_callback_t callback, void *arg);
|
||||
static void hci_uart_tl_send_async(uint8_t *buf, uint32_t size, esp_bt_hci_tl_callback_t callback, void *arg);
|
||||
static void hci_uart_tl_flow_on(void);
|
||||
static bool hci_uart_tl_flow_off(void);
|
||||
static void hci_uart_tl_finish_transfers(void);
|
||||
|
||||
struct uart_txrxchannel {
|
||||
esp_bt_hci_tl_callback_t callback;
|
||||
void *arg;
|
||||
lldesc_t link;
|
||||
};
|
||||
|
||||
struct uart_env_tag {
|
||||
struct uart_txrxchannel tx;
|
||||
struct uart_txrxchannel rx;
|
||||
};
|
||||
|
||||
struct uart_env_tag uart_env;
|
||||
|
||||
static volatile uhci_dev_t *s_uhci_hw = &UHCI0;
|
||||
static gdma_channel_handle_t s_rx_channel;
|
||||
static gdma_channel_handle_t s_tx_channel;
|
||||
|
||||
static esp_bt_hci_tl_t s_hci_uart_tl_funcs = {
|
||||
._magic = ESP_BT_HCI_TL_MAGIC_VALUE,
|
||||
._version = ESP_BT_HCI_TL_VERSION,
|
||||
._reserved = 0,
|
||||
._open = (void *)hci_uart_tl_init,
|
||||
._close = (void *)hci_uart_tl_deinit,
|
||||
._finish_transfers = (void *)hci_uart_tl_finish_transfers,
|
||||
._recv = (void *)hci_uart_tl_recv_async,
|
||||
._send = (void *)hci_uart_tl_send_async,
|
||||
._flow_on = (void *)hci_uart_tl_flow_on,
|
||||
._flow_off = (void *)hci_uart_tl_flow_off,
|
||||
};
|
||||
|
||||
static bool hci_uart_tl_init(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void hci_uart_tl_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
static IRAM_ATTR void hci_uart_tl_recv_async(uint8_t *buf, uint32_t size, esp_bt_hci_tl_callback_t callback, void *arg)
|
||||
{
|
||||
assert(buf != NULL);
|
||||
assert(size != 0);
|
||||
assert(callback != NULL);
|
||||
uart_env.rx.callback = callback;
|
||||
uart_env.rx.arg = arg;
|
||||
|
||||
memset(&uart_env.rx.link, 0, sizeof(lldesc_t));
|
||||
uart_env.rx.link.buf = buf;
|
||||
uart_env.rx.link.size = size;
|
||||
|
||||
s_uhci_hw->pkt_thres.thrs = size;
|
||||
|
||||
gdma_start(s_rx_channel, (intptr_t)(&uart_env.rx.link));
|
||||
}
|
||||
|
||||
static IRAM_ATTR void hci_uart_tl_send_async(uint8_t *buf, uint32_t size, esp_bt_hci_tl_callback_t callback, void *arg)
|
||||
{
|
||||
assert(buf != NULL);
|
||||
assert(size != 0);
|
||||
assert(callback != NULL);
|
||||
|
||||
uart_env.tx.callback = callback;
|
||||
uart_env.tx.arg = arg;
|
||||
|
||||
memset(&uart_env.tx.link, 0, sizeof(lldesc_t));
|
||||
uart_env.tx.link.length = size;
|
||||
uart_env.tx.link.buf = buf;
|
||||
uart_env.tx.link.eof = 1;
|
||||
|
||||
gdma_start(s_tx_channel, (intptr_t)(&uart_env.tx.link));
|
||||
}
|
||||
|
||||
static void hci_uart_tl_flow_on(void)
|
||||
{
|
||||
}
|
||||
|
||||
static bool hci_uart_tl_flow_off(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void hci_uart_tl_finish_transfers(void)
|
||||
{
|
||||
}
|
||||
|
||||
static IRAM_ATTR bool hci_uart_tl_rx_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data)
|
||||
{
|
||||
assert(dma_chan == s_rx_channel);
|
||||
assert(uart_env.rx.callback != NULL);
|
||||
esp_bt_hci_tl_callback_t callback = uart_env.rx.callback;
|
||||
void *arg = uart_env.rx.arg;
|
||||
|
||||
// clear callback pointer
|
||||
uart_env.rx.callback = NULL;
|
||||
uart_env.rx.arg = NULL;
|
||||
|
||||
// call handler
|
||||
callback(arg, ESP_BT_HCI_TL_STATUS_OK);
|
||||
|
||||
// send notification to Bluetooth Controller task
|
||||
esp_bt_h4tl_eif_io_event_notify(1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static IRAM_ATTR bool hci_uart_tl_tx_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data)
|
||||
{
|
||||
assert(dma_chan == s_tx_channel);
|
||||
assert(uart_env.tx.callback != NULL);
|
||||
esp_bt_hci_tl_callback_t callback = uart_env.tx.callback;
|
||||
void *arg = uart_env.tx.arg;
|
||||
|
||||
// clear callback pointer
|
||||
uart_env.tx.callback = NULL;
|
||||
uart_env.tx.arg = NULL;
|
||||
|
||||
// call handler
|
||||
callback(arg, ESP_BT_HCI_TL_STATUS_OK);
|
||||
|
||||
// send notification to Bluetooth Controller task
|
||||
esp_bt_h4tl_eif_io_event_notify(1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void uart_gpio_set(void)
|
||||
{
|
||||
gpio_config_t io_output_conf = {
|
||||
.intr_type = GPIO_PIN_INTR_DISABLE, //disable interrupt
|
||||
.mode = GPIO_MODE_OUTPUT, // output mode
|
||||
.pin_bit_mask = GPIO_OUTPUT_PIN_SEL, // bit mask of the output pins
|
||||
.pull_down_en = 0, // disable pull-down mode
|
||||
.pull_up_en = 0, // disable pull-up mode
|
||||
};
|
||||
gpio_config(&io_output_conf);
|
||||
|
||||
gpio_config_t io_input_conf = {
|
||||
.intr_type = GPIO_PIN_INTR_DISABLE, //disable interrupt
|
||||
.mode = GPIO_MODE_INPUT, // input mode
|
||||
.pin_bit_mask = GPIO_OUTPUT_PIN_SEL, // bit mask of the input pins
|
||||
.pull_down_en = 0, // disable pull-down mode
|
||||
.pull_up_en = 0, // disable pull-down mode
|
||||
};
|
||||
gpio_config(&io_input_conf);
|
||||
|
||||
uart_set_pin(UART_HCI_NUM, GPIO_UART_TXD_OUT, GPIO_UART_RXD_IN, GPIO_UART_RTS_OUT, GPIO_UART_CTS_IN);
|
||||
}
|
||||
|
||||
void uhci_uart_install(void)
|
||||
{
|
||||
periph_module_enable(PERIPH_UHCI0_MODULE);
|
||||
periph_module_reset(PERIPH_UHCI0_MODULE);
|
||||
|
||||
periph_module_enable(PERIPH_UART1_MODULE);
|
||||
periph_module_reset(PERIPH_UART1_MODULE);
|
||||
|
||||
uart_gpio_set();
|
||||
|
||||
// configure UART1
|
||||
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,
|
||||
.rx_flow_ctrl_thresh = UART_RX_THRS,
|
||||
.source_clk = UART_SCLK_APB,
|
||||
};
|
||||
ESP_ERROR_CHECK(uart_param_config(UART_HCI_NUM, &uart_config));
|
||||
|
||||
// install DMA driver
|
||||
gdma_channel_alloc_config_t tx_channel_config = {
|
||||
.flags.reserve_sibling = 1,
|
||||
.direction = GDMA_CHANNEL_DIRECTION_TX,
|
||||
};
|
||||
ESP_ERROR_CHECK(gdma_new_channel(&tx_channel_config, &s_tx_channel));
|
||||
gdma_channel_alloc_config_t rx_channel_config = {
|
||||
.direction = GDMA_CHANNEL_DIRECTION_RX,
|
||||
.sibling_chan = s_tx_channel,
|
||||
};
|
||||
ESP_ERROR_CHECK(gdma_new_channel(&rx_channel_config, &s_rx_channel));
|
||||
|
||||
gdma_connect(s_tx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_UART, 0));
|
||||
gdma_connect(s_rx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_UART, 0));
|
||||
|
||||
gdma_strategy_config_t strategy_config = {
|
||||
.auto_update_desc = false,
|
||||
.owner_check = false
|
||||
};
|
||||
gdma_apply_strategy(s_tx_channel, &strategy_config);
|
||||
gdma_apply_strategy(s_rx_channel, &strategy_config);
|
||||
|
||||
gdma_rx_event_callbacks_t rx_cbs = {
|
||||
.on_recv_eof = hci_uart_tl_rx_eof_callback
|
||||
};
|
||||
gdma_register_rx_event_callbacks(s_rx_channel, &rx_cbs, NULL);
|
||||
|
||||
gdma_tx_event_callbacks_t tx_cbs = {
|
||||
.on_trans_eof = hci_uart_tl_tx_eof_callback
|
||||
};
|
||||
gdma_register_tx_event_callbacks(s_tx_channel, &tx_cbs, NULL);
|
||||
|
||||
// configure UHCI
|
||||
uhci_ll_init(s_uhci_hw);
|
||||
uhci_ll_set_eof_mode(s_uhci_hw, UHCI_RX_LEN_EOF);
|
||||
// disable software flow control
|
||||
s_uhci_hw->escape_conf.val = 0;
|
||||
uhci_ll_attach_uart_port(s_uhci_hw, 1);
|
||||
}
|
||||
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
esp_err_t ret;
|
||||
|
||||
uhci_uart_install();
|
||||
|
||||
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
|
||||
bt_cfg.hci_tl_funcs = &s_hci_uart_tl_funcs;
|
||||
|
||||
ret = esp_bt_controller_init(&bt_cfg);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(tag, "Bluetooth Controller initialize failed: %s", esp_err_to_name(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(tag, "Bluetooth Controller initialize failed: %s", esp_err_to_name(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGI(tag, "HCI messages can be communicated over UART%d: \n"
|
||||
"--PINs: TxD %d, RxD %d, RTS %d, CTS %d\n"
|
||||
"--Baudrate: %d", UART_HCI_NUM,
|
||||
GPIO_UART_TXD_OUT, GPIO_UART_RXD_IN, GPIO_UART_RTS_OUT, GPIO_UART_CTS_IN,
|
||||
CONFIG_EXAMPLE_HCI_UART_BAUDRATE);
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
#
|
||||
# Automatically generated file. DO NOT EDIT.
|
||||
# Espressif IoT Development Framework (ESP-IDF) Project Configuration
|
||||
#
|
||||
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BT_CTRL_ESP32C3=y
|
||||
CONFIG_BT_CTRL_HCI_MODE_UART_H4=y
|
||||
CONFIG_BT_CTRL_HCI_TL=0
|
||||
CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP=n
|
||||
CONFIG_BT_CTRL_BLE_SCAN_DUPL=n
|
||||
# End of deprecated options
|
Loading…
x
Reference in New Issue
Block a user