-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(ble): fixed ble_htp example ci build error
- Loading branch information
1 parent
cec91a1
commit 4569090
Showing
2 changed files
with
307 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#include <inttypes.h> | ||
#include "driver/uart.h" | ||
|
||
/** | ||
* Function prototype for UART driver to ask for more data to send. | ||
* Returns -1 if no more data is available for TX. | ||
* Driver must call this with interrupts disabled. | ||
*/ | ||
typedef int (*hci_uart_tx_char)(void *arg); | ||
|
||
/** | ||
* Function prototype for UART driver to report that transmission is | ||
* complete. This should be called when transmission of last byte is | ||
* finished. | ||
* Driver must call this with interrupts disabled. | ||
*/ | ||
typedef void (*hci_uart_tx_done)(void *arg); | ||
|
||
/** | ||
* Function prototype for UART driver to report incoming byte of data. | ||
* Returns -1 if data was dropped. | ||
* Driver must call this with interrupts disabled. | ||
*/ | ||
typedef int (*hci_uart_rx_char)(void *arg, uint8_t byte); | ||
|
||
|
||
/** | ||
* Initializes given uart. Mapping of logical UART number to physical | ||
* UART/GPIO pins is in BSP. | ||
*/ | ||
int hci_uart_init_cbs(int uart, hci_uart_tx_char tx_func, | ||
hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg); | ||
|
||
|
||
/** | ||
* Applies given configuration to UART. | ||
* | ||
* @param port_num The UART number to configure | ||
* @param speed The baudrate in bps to configure | ||
* @param databits The number of databits to send per byte | ||
* @param stopbits The number of stop bits to send | ||
* @param parity The UART parity | ||
* @param flow_ctl Flow control settings on the UART | ||
* | ||
* @return 0 on success, non-zero error code on failure | ||
*/ | ||
int hci_uart_config(int port_num, int32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, | ||
uart_parity_t parity, uart_hw_flowcontrol_t flow_ctl); | ||
|
||
/** | ||
* Close UART port. Can call hal_uart_config() with different settings after | ||
* calling this. | ||
* | ||
* @param port_num The UART number to close | ||
*/ | ||
int hci_uart_close(int port_num); | ||
|
||
/** | ||
* More data queued for transmission. UART driver will start asking for that | ||
* data. | ||
* | ||
* @param port_num The UART number to start TX on | ||
*/ | ||
void hci_uart_start_tx(int port_num); | ||
|
||
/** | ||
* Upper layers have consumed some data, and are now ready to receive more. | ||
* This is meaningful after uart_rx_char callback has returned -1 telling | ||
* that no more data can be accepted. | ||
* | ||
* @param port_num The UART number to begin RX on | ||
*/ | ||
void hci_uart_start_rx(int port_num); | ||
|
||
/** | ||
* @brief reconfig hci uart pin | ||
* | ||
* @param tx_pin The Tx pin | ||
* @param rx_pin The Rx pin | ||
* @param cts_pin The CTS pin | ||
* @param rts_pin The RTS pin | ||
* @return int 0 on success, non-zero error code on failure | ||
*/ | ||
int hci_uart_reconfig_pin(int tx_pin, int rx_pin, int cts_pin, int rts_pin); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <string.h> | ||
#include "freertos/FreeRTOS.h" | ||
#include "freertos/task.h" | ||
#include "freertos/queue.h" | ||
#include "driver/uart.h" | ||
#include "hci_uart.h" | ||
#include "esp_log.h" | ||
#include "esp_attr.h" | ||
|
||
#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART | ||
|
||
static const char *TAG = "hci_uart"; | ||
|
||
#define BUF_SIZE (1024) | ||
#define RD_BUF_SIZE (BUF_SIZE) | ||
|
||
#define HCI_UART_TX_PIN CONFIG_BT_LE_HCI_UART_TX_PIN | ||
#define HCI_UART_RX_PIN CONFIG_BT_LE_HCI_UART_RX_PIN | ||
|
||
|
||
#ifdef CONFIG_BT_LE_HCI_UART_FLOWCTRL | ||
#define HCI_UART_FLOWCTRL UART_HW_FLOWCTRL_CTS_RTS | ||
#define HCI_UART_RTS_PIN CONFIG_BT_LE_HCI_UART_RTS_PIN | ||
#define HCI_UART_CTS_PIN CONFIG_BT_LE_HCI_UART_CTS_PIN | ||
#else | ||
#define HCI_UART_FLOWCTRL UART_HW_FLOWCTRL_DISABLE | ||
#define HCI_UART_RTS_PIN (-1) | ||
#define HCI_UART_CTS_PIN (-1) | ||
#endif | ||
|
||
|
||
typedef struct { | ||
bool uart_opened; | ||
uart_port_t port; | ||
uart_config_t cfg; | ||
QueueHandle_t evt_queue; | ||
TaskHandle_t rx_task_handler; | ||
hci_uart_tx_char tx_char; | ||
hci_uart_tx_done tx_done; | ||
hci_uart_rx_char rx_char; | ||
void *u_func_arg; | ||
|
||
} hci_uart_t; | ||
|
||
static hci_uart_t hci_uart; | ||
|
||
static void IRAM_ATTR hci_uart_rx_task(void *pvParameters) | ||
{ | ||
uart_event_t event; | ||
uint8_t *dtmp = (uint8_t *) malloc(RD_BUF_SIZE); | ||
while (hci_uart.uart_opened) { | ||
//Waiting for UART event. | ||
if (xQueueReceive(hci_uart.evt_queue, (void * )&event, (TickType_t)portMAX_DELAY)) { | ||
bzero(dtmp, RD_BUF_SIZE); | ||
ESP_LOGD(TAG, "uart[%d] event:", hci_uart.port); | ||
switch (event.type) { | ||
//Event of UART receving data | ||
/*We'd better handler data event fast, there would be much more data events than | ||
other types of events. If we take too much time on data event, the queue might | ||
be full.*/ | ||
case UART_DATA: | ||
// ESP_LOGI(TAG, "[UART DATA]: %d", event.size); | ||
uart_read_bytes(hci_uart.port, dtmp, event.size, portMAX_DELAY); | ||
for (int i = 0 ; i < event.size; i++) { | ||
hci_uart.rx_char(hci_uart.u_func_arg, dtmp[i]); | ||
} | ||
break; | ||
//Event of HW FIFO overflow detected | ||
case UART_FIFO_OVF: | ||
ESP_LOGI(TAG, "hw fifo overflow"); | ||
// If fifo overflow happened, you should consider adding flow control for your application. | ||
// The ISR has already reset the rx FIFO, | ||
uart_flush_input(hci_uart.port); | ||
xQueueReset(hci_uart.evt_queue); | ||
break; | ||
//Event of UART ring buffer full | ||
case UART_BUFFER_FULL: | ||
ESP_LOGI(TAG, "ring buffer full"); | ||
// If buffer full happened, you should consider encreasing your buffer size | ||
uart_flush_input(hci_uart.port); | ||
xQueueReset(hci_uart.evt_queue); | ||
break; | ||
//Event of UART RX break detected | ||
case UART_BREAK: | ||
ESP_LOGI(TAG, "uart rx break"); | ||
break; | ||
//Event of UART parity check error | ||
case UART_PARITY_ERR: | ||
ESP_LOGI(TAG, "uart parity error"); | ||
break; | ||
//Event of UART frame error | ||
case UART_FRAME_ERR: | ||
ESP_LOGI(TAG, "uart frame error"); | ||
break; | ||
//Others | ||
default: | ||
ESP_LOGI(TAG, "uart event type: %d", event.type); | ||
break; | ||
} | ||
} | ||
} | ||
free(dtmp); | ||
dtmp = NULL; | ||
hci_uart.rx_task_handler = NULL; | ||
vTaskDelete(NULL); | ||
} | ||
|
||
int hci_uart_config(int port_num, int32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, | ||
uart_parity_t parity, uart_hw_flowcontrol_t flow_ctl) | ||
{ | ||
uart_config_t uart_cfg = { | ||
.baud_rate = baud_rate, | ||
.data_bits = data_bits, | ||
.parity = parity, | ||
.stop_bits = stop_bits, | ||
.flow_ctrl = HCI_UART_FLOWCTRL, | ||
.source_clk = UART_SCLK_DEFAULT, | ||
.rx_flow_ctrl_thresh = UART_FIFO_LEN - 1, | ||
}; | ||
hci_uart.port = port_num; | ||
hci_uart.cfg = uart_cfg; | ||
|
||
int intr_alloc_flags = 0; | ||
intr_alloc_flags = ESP_INTR_FLAG_IRAM; | ||
|
||
printf("set uart pin tx:%d, rx:%d.\n", HCI_UART_TX_PIN, HCI_UART_RX_PIN); | ||
printf("set rts:%d, cts:%d.\n", HCI_UART_RTS_PIN, HCI_UART_CTS_PIN); | ||
printf("set baud_rate:%d.\n", baud_rate); | ||
|
||
ESP_ERROR_CHECK(uart_driver_delete(port_num)); | ||
ESP_ERROR_CHECK(uart_driver_install(port_num, BUF_SIZE * 2, BUF_SIZE * 2, 20, &hci_uart.evt_queue, intr_alloc_flags)); | ||
ESP_ERROR_CHECK(uart_param_config(port_num, &hci_uart.cfg)); | ||
ESP_ERROR_CHECK(uart_set_pin(port_num, HCI_UART_TX_PIN, HCI_UART_RX_PIN, HCI_UART_RTS_PIN, HCI_UART_CTS_PIN)); | ||
|
||
hci_uart.uart_opened = true; | ||
|
||
//Create a task to handler UART event from ISR | ||
xTaskCreate(hci_uart_rx_task, "hci_uart_rx_task", 2048, NULL, 12, &hci_uart.rx_task_handler); | ||
return 0; | ||
} | ||
|
||
void IRAM_ATTR hci_uart_start_tx(int port_num) | ||
{ | ||
int data; | ||
uint8_t u8_data = 0; | ||
while (1) { | ||
data = hci_uart.tx_char(hci_uart.u_func_arg); | ||
if (data >= 0) { | ||
u8_data = data; | ||
uart_tx_chars(port_num, (char *)&u8_data, 1); | ||
} else { | ||
break; | ||
} | ||
} | ||
if (hci_uart.tx_done) { | ||
hci_uart.tx_done(hci_uart.u_func_arg); | ||
} | ||
} | ||
|
||
int hci_uart_init_cbs(int port_num, hci_uart_tx_char tx_func, | ||
hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg) | ||
{ | ||
hci_uart.tx_char = tx_func; | ||
hci_uart.rx_char = rx_func; | ||
hci_uart.tx_done = tx_done; | ||
hci_uart.u_func_arg = arg; | ||
return 0; | ||
} | ||
|
||
int hci_uart_close(int port_num) | ||
{ | ||
uart_event_t uart_event; | ||
uart_event.type = UART_BREAK; | ||
hci_uart.uart_opened = false; | ||
// Stop uart rx task | ||
if (hci_uart.rx_task_handler != NULL) { | ||
xQueueSend(hci_uart.evt_queue, (void *)&uart_event, 1000); | ||
ESP_LOGW(TAG, "Waiting for uart task finish..."); | ||
} | ||
while (hci_uart.rx_task_handler != NULL); | ||
|
||
uart_driver_delete(port_num); | ||
ESP_LOGI(TAG, "hci uart close success."); | ||
return 0; | ||
} | ||
|
||
int hci_uart_reconfig_pin(int tx_pin, int rx_pin, int cts_pin, int rts_pin) | ||
{ | ||
int port_num = hci_uart.port; | ||
int32_t baud_rate = hci_uart.cfg.baud_rate; | ||
uint8_t data_bits = hci_uart.cfg.data_bits; | ||
uint8_t stop_bits = hci_uart.cfg.stop_bits; | ||
uart_parity_t parity = hci_uart.cfg.parity; | ||
uart_hw_flowcontrol_t flow_ctl = hci_uart.cfg.flow_ctrl; | ||
hci_uart_close(port_num); | ||
hci_uart_config(port_num, baud_rate, data_bits, stop_bits, parity, flow_ctl); | ||
ESP_ERROR_CHECK(uart_set_pin(port_num, tx_pin, rx_pin, rts_pin, cts_pin)); | ||
return 0; | ||
} | ||
#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART |