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