1 /*
2 * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdio.h>
8 #include <string.h>
9 #include "freertos/FreeRTOS.h"
10 #include "freertos/queue.h"
11 #include "freertos/task.h"
12 #include "freertos/semphr.h"
13 #include "esp_log.h"
14 #include "driver/uart.h"
15 #include "esp_hci_transport.h"
16 #include "esp_hci_internal.h"
17 #include "common/hci_driver_h4.h"
18 #include "common/hci_driver_util.h"
19 #include "common/hci_driver_mem.h"
20 #include "hci_driver_uart.h"
21
22 static const char *TAG = "hci_uart";
23
24 #define CONFIG_BT_LE_HCI_RX_PROC_DATA_LEN (256)
25
26 typedef struct {
27 TaskHandle_t tx_task_handler;
28 TaskHandle_t rx_task_handler;
29 hci_driver_uart_params_config_t *hci_uart_params;
30 SemaphoreHandle_t tx_sem;
31 QueueHandle_t rx_event_queue;
32 uint8_t *rx_data;
33 struct hci_h4_sm *h4_sm;
34 hci_driver_forward_fn *forward_cb;
35 } hci_driver_uart_env_t;
36
37 static hci_driver_uart_env_t s_hci_driver_uart_env;
38 static struct hci_h4_sm s_hci_driver_uart_h4_sm;
39 static uint8_t s_hci_driver_uart_rx_data[CONFIG_BT_LE_HCI_RX_PROC_DATA_LEN];
40 static hci_driver_uart_params_config_t hci_driver_uart_params = BT_HCI_DRIVER_UART_CONFIG_DEFAULT();
41
42 static int
hci_driver_uart_tx(hci_driver_data_type_t data_type,uint8_t * data,uint32_t length,hci_driver_direction_t dir)43 hci_driver_uart_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length,
44 hci_driver_direction_t dir)
45 {
46 /* By now, this layer is only used by controller. */
47 assert(dir == HCI_DRIVER_DIR_C2H);
48 ESP_LOGD(TAG, "controller tx len:%d\n", length);
49
50 hci_driver_util_tx_list_enqueue(data_type, data, length);
51 xSemaphoreGive(s_hci_driver_uart_env.tx_sem);
52
53 return 0;
54 }
55
56 static int
hci_driver_uart_h4_frame_cb(uint8_t pkt_type,void * data)57 hci_driver_uart_h4_frame_cb(uint8_t pkt_type, void *data)
58 {
59 hci_driver_forward_fn *forward_cb;
60
61 forward_cb = s_hci_driver_uart_env.forward_cb;
62 if (!forward_cb) {
63 return -1;
64 }
65 ESP_LOGD(TAG, "h4 frame\n");
66 return forward_cb(pkt_type, data, 0, HCI_DRIVER_DIR_H2C);
67 }
68
69 static void
hci_driver_uart_tx_task(void * p)70 hci_driver_uart_tx_task(void *p)
71 {
72 void *data;
73 bool last_frame;
74 uint32_t tx_len;
75 uart_port_t port;
76
77 port = s_hci_driver_uart_env.hci_uart_params->hci_uart_port;
78 while (true) {
79 xSemaphoreTake(s_hci_driver_uart_env.tx_sem, portMAX_DELAY);
80 while (true) {
81 tx_len = hci_driver_util_tx_list_dequeue(0xffffff, &data, &last_frame);
82 if (tx_len == 0) {
83 break;
84 }
85 ESP_LOGD(TAG, "uart tx");
86 ESP_LOG_BUFFER_HEXDUMP(TAG, data, tx_len, ESP_LOG_DEBUG);
87 uart_write_bytes(port, data, tx_len);
88 }
89 }
90 }
91
92 static void
hci_driver_uart_rx_task(void * p)93 hci_driver_uart_rx_task(void *p)
94 {
95 void *data;
96 int read_len;
97 int ret;
98 uart_port_t port;
99 uart_event_t uart_event;
100
101 port = s_hci_driver_uart_env.hci_uart_params->hci_uart_port;
102 while (true) {
103 xQueueReceive(s_hci_driver_uart_env.rx_event_queue, &uart_event, portMAX_DELAY);
104 data = s_hci_driver_uart_env.rx_data;
105 while (true) {
106 read_len = uart_read_bytes(port, data, CONFIG_BT_LE_HCI_RX_PROC_DATA_LEN, 0);
107 if (read_len == 0) {
108 break;
109 }
110 ESP_LOGD(TAG, "uart rx");
111 ESP_LOG_BUFFER_HEXDUMP(TAG, data, read_len, ESP_LOG_DEBUG);
112 ret = hci_h4_sm_rx(s_hci_driver_uart_env.h4_sm, data, read_len);
113 if (ret < 0) {
114 r_ble_ll_hci_ev_hw_err(ESP_HCI_SYNC_LOSS_ERR);
115 }
116 }
117 }
118 }
119
120 static int
hci_driver_uart_task_create(void)121 hci_driver_uart_task_create(void)
122 {
123 /* !TODO: Set the core id by menuconfig */
124 xTaskCreatePinnedToCore(hci_driver_uart_tx_task, "hci_driver_uart_tx_task",
125 CONFIG_BT_LE_HCI_TRANS_TASK_STACK_SIZE, NULL,
126 ESP_TASK_BT_CONTROLLER_PRIO, &s_hci_driver_uart_env.tx_task_handler,
127 0);
128 assert(s_hci_driver_uart_env.tx_task_handler);
129
130 xTaskCreatePinnedToCore(hci_driver_uart_rx_task, "hci_driver_uart_rx_task",
131 CONFIG_BT_LE_HCI_TRANS_TASK_STACK_SIZE, NULL,
132 ESP_TASK_BT_CONTROLLER_PRIO, &s_hci_driver_uart_env.rx_task_handler,
133 0);
134 assert(s_hci_driver_uart_env.rx_task_handler);
135
136 ESP_LOGI(TAG, "hci transport task create successfully, prio:%d, stack size: %ld",
137 ESP_TASK_BT_CONTROLLER_PRIO, CONFIG_BT_LE_HCI_TRANS_TASK_STACK_SIZE);
138
139 return 0;
140 }
141
142 static void
hci_driver_uart_task_delete(void)143 hci_driver_uart_task_delete(void)
144 {
145 if (s_hci_driver_uart_env.tx_task_handler) {
146 vTaskDelete(s_hci_driver_uart_env.tx_task_handler);
147 s_hci_driver_uart_env.tx_task_handler = NULL;
148 }
149
150 if (s_hci_driver_uart_env.rx_task_handler) {
151 vTaskDelete(s_hci_driver_uart_env.rx_task_handler);
152 s_hci_driver_uart_env.rx_task_handler = NULL;
153 }
154 }
155
156 static void
hci_driver_uart_deinit(void)157 hci_driver_uart_deinit(void)
158 {
159 hci_driver_uart_task_delete();
160
161 ESP_ERROR_CHECK(uart_driver_delete(s_hci_driver_uart_env.hci_uart_params->hci_uart_port));
162
163 if (s_hci_driver_uart_env.tx_sem) {
164 vSemaphoreDelete(s_hci_driver_uart_env.tx_sem);
165 }
166
167 hci_driver_util_deinit();
168 memset(&s_hci_driver_uart_env, 0, sizeof(hci_driver_uart_env_t));
169 }
170
171 static int
hci_driver_uart_init(hci_driver_forward_fn * cb)172 hci_driver_uart_init(hci_driver_forward_fn *cb)
173 {
174 int rc;
175 memset(&s_hci_driver_uart_env, 0, sizeof(hci_driver_uart_env_t));
176
177 s_hci_driver_uart_env.h4_sm = &s_hci_driver_uart_h4_sm;
178 hci_h4_sm_init(s_hci_driver_uart_env.h4_sm, &s_hci_driver_mem_alloc, hci_driver_uart_h4_frame_cb);
179
180 rc = hci_driver_util_init();
181 if (rc) {
182 goto error;
183 }
184
185 s_hci_driver_uart_env.tx_sem = xSemaphoreCreateBinary();
186 if (!s_hci_driver_uart_env.tx_sem) {
187 goto error;
188 }
189
190 s_hci_driver_uart_env.rx_data = s_hci_driver_uart_rx_data;
191 s_hci_driver_uart_env.forward_cb = cb;
192 s_hci_driver_uart_env.hci_uart_params = &hci_driver_uart_params;
193 hci_driver_uart_config(&hci_driver_uart_params);
194 /* Currently, the queue size is set to 1. It will be considered as semaphore. */
195 ESP_ERROR_CHECK(uart_driver_install(s_hci_driver_uart_env.hci_uart_params->hci_uart_port,
196 CONFIG_BT_LE_HCI_UART_RX_BUFFER_SIZE,
197 CONFIG_BT_LE_HCI_UART_TX_BUFFER_SIZE,
198 1, &s_hci_driver_uart_env.rx_event_queue,
199 0));
200
201 rc = hci_driver_uart_task_create();
202 if (rc) {
203 goto error;
204 }
205
206 return 0;
207
208 error:
209 hci_driver_uart_deinit();
210 return rc;
211 }
212
213 int
hci_driver_uart_reconfig_pin(int tx_pin,int rx_pin,int cts_pin,int rts_pin)214 hci_driver_uart_reconfig_pin(int tx_pin, int rx_pin, int cts_pin, int rts_pin)
215 {
216 int rc;
217 hci_driver_uart_params_config_t *uart_param = s_hci_driver_uart_env.hci_uart_params;
218
219 hci_driver_uart_task_delete();
220 uart_param->hci_uart_tx_pin = tx_pin;
221 uart_param->hci_uart_rx_pin = rx_pin;
222 uart_param->hci_uart_rts_pin = rts_pin;
223 uart_param->hci_uart_cts_pin = cts_pin;
224 hci_driver_uart_config(uart_param);
225 /* Currently, the queue size is set to 1. It will be considered as semaphore. */
226 ESP_ERROR_CHECK(uart_driver_install(s_hci_driver_uart_env.hci_uart_params->hci_uart_port,
227 CONFIG_BT_LE_HCI_UART_RX_BUFFER_SIZE,
228 CONFIG_BT_LE_HCI_UART_TX_BUFFER_SIZE,
229 1, &s_hci_driver_uart_env.rx_event_queue,
230 0));
231 rc = hci_driver_uart_task_create();
232 if (rc) {
233 hci_driver_uart_task_delete();
234 return -2;
235 }
236
237 return 0;
238 }
239
240 hci_driver_ops_t hci_driver_uart_ops = {
241 .hci_driver_tx = hci_driver_uart_tx,
242 .hci_driver_init = hci_driver_uart_init,
243 .hci_driver_deinit = hci_driver_uart_deinit,
244 };
245