1 /**
2 * Copyright (c) 2017, Realsil Semiconductor Corporation. All rights reserved.
3 *
4 */
5
6 #include <stdio.h>
7 #include <string.h>
8
9 #include "ameba_soc.h"
10
11 #include "os_sched.h"
12 #include "os_pool.h"
13 #include "os_sync.h"
14 #include "os_mem.h"
15
16 #include "trace_app.h"
17
18 #include "hci_uart.h"
19 #include "bt_board.h"
20
21 #define HCI_UART_RX_BUF_SIZE 0x2000 /* RX buffer size 8K */
22 #define HCI_UART_RX_ENABLE_COUNT (HCI_UART_RX_BUF_SIZE - 2 * (1021 + 5)) /* Enable RX */
23 #define HCI_UART_RX_DISABLE_COUNT (HCI_UART_RX_BUF_SIZE - 1021 - 5 - 10) /* Disable RX */
24 typedef struct
25 {
26 UART_InitTypeDef UART_InitStruct;
27 IRQn_Type irqn;
28 uint32_t ier;
29
30 //tx
31 uint32_t tx_len;
32 uint8_t *tx_buf_cur;
33 uint32_t tx_len_cur;
34 P_UART_TX_CB tx_cb;
35
36
37 //rx
38 bool rx_disabled;
39 uint16_t rx_read_idx;
40 uint16_t rx_write_idx;
41 uint8_t rx_buffer[HCI_UART_RX_BUF_SIZE];
42 void* rx_timer_handle;
43 P_UART_RX_CB rx_ind;
44
45 bool hci_uart_bridge_flag;
46 }T_HCI_UART;
47
48 //===========
49 T_HCI_UART *hci_uart_obj;
50
51 #define TX_TRASMIT_COUNT 16
52 #define hci_board_debug printf
53
54 #define HCI_UART_IDX 1 //(only 0, 1, 3)
55
56 /*BT CTS PA0 ----- RTS_PIN*/
57 /*BT TX PA2 ----- RX_PIN*/
58 /*BT RX PA4 ----- TX_PIN*/
59 #if (HCI_UART_IDX == 0)
60 #define HCI_UART_OUT
61 #define HCI_UART_DEV UART0_DEV
62 #define HCI_UART_IRQ UART0_IRQ
63 #if 1
64 #define HCI_TX_PIN _PA_18
65 #define HCI_RX_PIN _PA_19
66 //#define HCI_CTS_PIN _PA_17
67 //#define HCI_RTS_PIN _PA_16 //BT_LOG
68 #else
69 #define HCI_TX_PIN _PA_21
70 #define HCI_RX_PIN _PA_22
71 //#define HCI_CTS_PIN _PA_24
72 #define HCI_RTS_PIN _PA_23
73 #endif
74
75 #elif (HCI_UART_IDX == 3)
76 #define HCI_UART_OUT
77 #define HCI_UART_DEV UART3_DEV
78 #define HCI_UART_IRQ UARTLP_IRQ
79 #define HCI_TX_PIN _PA_26
80 #define HCI_RX_PIN _PA_25
81 //#define HCI_CTS_PIN _PA_25
82 #define HCI_RTS_PIN _PA_27
83 #else
84 #define HCI_UART_DEV UART1_DEV
85 #define HCI_UART_IRQ UART1_IRQ
86 #endif
87
88 #define HCIUART_IRQ_PRIO 10
89
90
91 //========================================HCI UART BRIDGE=================
set_hci_uart_out(bool flag)92 void set_hci_uart_out(bool flag)
93 {
94 T_HCI_UART *p_uart_obj = hci_uart_obj;
95 if(p_uart_obj != NULL)
96 {
97 p_uart_obj->hci_uart_bridge_flag = flag;
98 }
99 else
100 {
101 hci_board_debug("set_hci_uart_out: hci_uart_obj is NULL\r\n");
102 }
103 }
104
hci_uart_tx_bridge(uint8_t rc)105 bool hci_uart_tx_bridge(uint8_t rc)
106 {
107 UART_CharPut(HCI_UART_DEV, rc);
108 return true;
109 }
110
hci_uart_rx_bridge(uint8_t rc)111 bool hci_uart_rx_bridge(uint8_t rc)
112 {
113 //extern void bt_uart_tx(uint8_t rc);
114 //bt_uart_tx(rc);
115 return true;
116 }
hci_rx_empty()117 uint8_t hci_rx_empty()
118 {
119 uint16_t tmpRead = hci_uart_obj->rx_read_idx;
120 uint16_t tmpWrite = hci_uart_obj->rx_write_idx;
121 return (tmpRead == tmpWrite);
122 }
123
hci_rx_data_len()124 uint16_t hci_rx_data_len()
125 {
126 return (hci_uart_obj->rx_write_idx + HCI_UART_RX_BUF_SIZE - hci_uart_obj->rx_read_idx) % HCI_UART_RX_BUF_SIZE;
127 }
hci_rx_space_len()128 uint16_t hci_rx_space_len()
129 {
130 return (hci_uart_obj->rx_read_idx + HCI_UART_RX_BUF_SIZE - hci_uart_obj->rx_write_idx - 1) % HCI_UART_RX_BUF_SIZE;
131 }
132 //========================================HCI UART BRIDGE==================
133
hci_uart_set_baudrate(uint32_t baudrate)134 void hci_uart_set_baudrate(uint32_t baudrate)
135 {
136 hci_board_debug("Set baudrate to %d\r\n", baudrate);
137 UART_SetBaud(HCI_UART_DEV, baudrate);
138 }
139
hci_uart_rx_disable(T_HCI_UART * hci_adapter)140 void hci_uart_rx_disable(T_HCI_UART *hci_adapter)
141 {
142 /* We disable received data available and rx timeout interrupt, then
143 * the rx data will stay in UART FIFO, and RTS will be pulled high if
144 * the watermark is higher than rx trigger level. */
145 hci_board_debug("hci_uart_rx_disable\r\n");
146 UART_INTConfig(HCI_UART_DEV, RUART_IER_ERBI | RUART_IER_ETOI, DISABLE);
147 hci_adapter->rx_disabled = true;
148 }
149
hci_uart_rx_enable(T_HCI_UART * hci_adapter)150 void hci_uart_rx_enable(T_HCI_UART *hci_adapter)
151 {
152 hci_board_debug("hci_uart_rx_enable\r\n");
153 UART_INTConfig(HCI_UART_DEV, RUART_IER_ERBI | RUART_IER_ETOI, ENABLE);
154 hci_adapter->rx_disabled = false;
155 }
156
hciuart_stop_tx(T_HCI_UART * hci_adapter)157 static inline void hciuart_stop_tx(T_HCI_UART *hci_adapter)
158 {
159 if (hci_adapter->ier & RUART_IER_ETBEI)
160 {
161 hci_adapter->ier &= ~RUART_IER_ETBEI;
162 UART_INTConfig(HCI_UART_DEV, RUART_IER_ETBEI, DISABLE);
163 }
164 }
165
166
transmit_chars(T_HCI_UART * hci_adapter)167 static inline void transmit_chars(T_HCI_UART *hci_adapter)
168 {
169 int count;
170
171 if(hci_adapter == NULL)
172 {
173 hci_board_debug("transmit_chars: hci_adapter is NULL\r\n");
174 return;
175 }
176
177 if (hci_adapter->tx_len_cur == 0)
178 {
179 hciuart_stop_tx(hci_adapter);
180 if (hci_adapter->tx_cb)
181 {
182 hci_adapter->tx_cb();
183 }
184 return;
185 }
186
187 count = TX_TRASMIT_COUNT;
188 do
189 {
190 UART_CharPut(HCI_UART_DEV, *(hci_adapter->tx_buf_cur));
191 hci_adapter->tx_buf_cur++;
192 hci_adapter->tx_len_cur--;
193 }
194 while (--count > 0 && hci_adapter->tx_len_cur > 0);
195 }
196
uart_insert_char(T_HCI_UART * hci_adapter,uint8_t ch)197 static inline void uart_insert_char(T_HCI_UART *hci_adapter, uint8_t ch)
198 {
199
200 /* Should neve happen */
201 if (hci_rx_space_len()==0)
202 {
203 hci_board_debug("uart_insert_char: rx buffer full\r\n");
204 return;
205 }
206
207 // if(rltk_wlan_is_mp())
208 {
209 if(hci_adapter->hci_uart_bridge_flag == true)
210 {
211 hci_uart_rx_bridge(ch);
212 return;
213 }
214 }
215 hci_adapter->rx_buffer[hci_adapter->rx_write_idx++] = ch;
216 hci_adapter->rx_write_idx %= HCI_UART_RX_BUF_SIZE;
217
218
219 if (hci_rx_data_len() >= HCI_UART_RX_DISABLE_COUNT && hci_adapter->rx_disabled == false)
220 {
221 hci_board_debug("uart_insert_char: rx disable, data len %d\r\n", hci_rx_data_len());
222 hci_uart_rx_disable(hci_adapter);
223 }
224 }
225
receive_chars(T_HCI_UART * hci_adapter,int ind)226 static inline void receive_chars(T_HCI_UART *hci_adapter, int ind)
227 {
228 int max_count = 16;
229 u8 byte;
230
231 if(hci_adapter == NULL)
232 {
233 UART_CharGet(HCI_UART_DEV, &byte);
234 hci_board_debug("receive_chars: hci_adapter is NULL, ind:%x, data:%x\r\n", ind, byte);
235 return;
236 }
237 /* start timer*/
238 do
239 {
240 if (UART_Readable(HCI_UART_DEV))
241 {
242 UART_CharGet(HCI_UART_DEV, &byte);
243 uart_insert_char(hci_adapter, byte);
244 }
245 else
246 {
247 break;
248 }
249 }
250 while (--max_count > 0);
251
252 /* HCI_PRINT_INFO1("receive_chars: rx_len %u", hci_adapter->rx_len); */
253 /* FIXME: There is too many rx indication events ? */
254 if (ind && hci_adapter->rx_ind)
255 {
256 hci_adapter->rx_ind();
257
258 }
259 }
260
hciuart_irq(void * data)261 u32 hciuart_irq(void *data)
262 {
263 volatile u8 reg_iir;
264 u8 int_id;
265 u32 reg_val;
266 T_HCI_UART *hci_adapter = (T_HCI_UART *) data;
267
268 reg_iir = UART_IntStatus(HCI_UART_DEV);
269 if ((reg_iir & RUART_IIR_INT_PEND) != 0)
270 {
271 /* No pending IRQ */
272 return 0;
273 }
274
275 int_id = (reg_iir & RUART_IIR_INT_ID) >> 1;
276
277 switch (int_id)
278 {
279 case RUART_LP_RX_MONITOR_DONE:
280 reg_val = UART_RxMonitorSatusGet(HCI_UART_DEV);
281 /* if(UART0_DEV == hci_adapter->UARTx){
282 * DUart0MonitorDone = 1;
283 * } else {
284 * DUart1MonitorDone = 1;
285 * } */
286 hci_board_debug("hciuart_irq: monitor done\r\n");
287 break;
288 case RUART_MODEM_STATUS:
289 reg_val = UART_ModemStatusGet(HCI_UART_DEV);
290 break;
291 case RUART_TX_FIFO_EMPTY:
292 transmit_chars(hci_adapter);
293 break;
294 case RUART_RECEIVER_DATA_AVAILABLE:
295 receive_chars(hci_adapter, 1);
296 break;
297 case RUART_TIME_OUT_INDICATION:
298 receive_chars(hci_adapter, 1);
299 break;
300 case RUART_RECEIVE_LINE_STATUS:
301 reg_val = (UART_LineStatusGet(HCI_UART_DEV));
302 hci_board_debug("hciuart_irq: LSR %08x interrupt\r\n", reg_val);
303 if (reg_val & RUART_LINE_STATUS_ERR_OVERRUN)
304 {
305 hci_board_debug("hciuart_irq: LSR over run interrupt\r\n");
306 }
307
308 if (reg_val & RUART_LINE_STATUS_ERR_PARITY)
309 {
310 hci_board_debug("hciuart_irq: LSR parity error interrupt\r\n");
311 }
312
313 if (reg_val & RUART_LINE_STATUS_ERR_FRAMING)
314 {
315 hci_board_debug("hciuart_irq: LSR frame error(stop bit error) interrupt\r\n");
316 }
317
318 if (reg_val & RUART_LINE_STATUS_ERR_BREAK)
319 {
320 hci_board_debug("hciuart_irq: LSR break error interrupt\r\n");
321 }
322
323 /* if (reg_val & RUART_LINE_STATUS_REG_THRE)
324 * transmit_chars(hci_adapter);
325 */
326 break;
327
328 default:
329 hci_board_debug("hciuart_irq: Unknown interrupt type %u\r\n", int_id);
330 break;
331 }
332
333 return 0;
334 }
335
hci_uart_tx(uint8_t * p_buf,uint16_t len,P_UART_TX_CB tx_cb)336 bool hci_uart_tx(uint8_t *p_buf, uint16_t len, P_UART_TX_CB tx_cb)
337 {
338
339 #if 0
340 UART_SendData(HCI_UART_DEV, p_buf, len);
341 if (tx_cb)
342 tx_cb();
343 return true;
344 #else
345
346 T_HCI_UART *uart_obj = hci_uart_obj;
347
348 uart_obj->tx_len = len;
349 uart_obj->tx_cb = tx_cb;
350
351
352 uart_obj->tx_buf_cur = p_buf;
353 uart_obj->tx_len_cur = len;
354
355 if (!(uart_obj->ier & RUART_IER_ETBEI))
356 {
357 uart_obj->ier |= RUART_IER_ETBEI;
358 UART_INTConfig(HCI_UART_DEV, RUART_IER_ETBEI, ENABLE);
359 }
360 else
361 {
362 hci_board_debug("hci_uart_tx: Transmitter FIFO empty interrupt has been enabled\r\n");
363 return false;
364 }
365 #endif
366 return true;
367 }
368
hci_uart_malloc(void)369 bool hci_uart_malloc(void)
370 {
371 if(hci_uart_obj == NULL)
372 {
373 hci_uart_obj = os_mem_zalloc(RAM_TYPE_DATA_ON, sizeof(T_HCI_UART)); //reopen not need init uart
374
375 if(!hci_uart_obj)
376 {
377 hci_board_debug("hci_uart_malloc: need %d, left %d\r\n", sizeof(T_HCI_UART), os_mem_peek(RAM_TYPE_DATA_ON));
378 return false;
379 }
380 else
381 {
382 //ok
383 }
384 }
385 else
386 {
387 hci_board_debug("hci_uart_malloc: rx_buffer not free\r\n");
388 return false;
389 }
390 return true;
391 }
392
hci_uart_free(void)393 bool hci_uart_free(void)
394 {
395 if(hci_uart_obj == NULL)
396 {
397 hci_board_debug("hci_uart_free: hci_uart_obj = NULL, no need free\r\n");
398 return true;
399 }
400 else
401 {
402 os_mem_free(hci_uart_obj);
403 hci_uart_obj = NULL;
404 }
405 return true;
406 }
407
hci_uart_set_rx_ind(P_UART_RX_CB rx_ind)408 void hci_uart_set_rx_ind(P_UART_RX_CB rx_ind)
409 {
410 hci_uart_obj->rx_ind = rx_ind;
411 }
412
hci_uart_init(P_UART_RX_CB rx_ind)413 bool hci_uart_init(P_UART_RX_CB rx_ind)
414 {
415 if(!hci_uart_malloc())
416 {
417 return false;
418 }
419
420 //malloc
421 #ifdef HCI_UART_OUT
422 //PINMUX THE PIN
423 Pinmux_Config(HCI_TX_PIN, PINMUX_FUNCTION_UART);
424 Pinmux_Config(HCI_RX_PIN, PINMUX_FUNCTION_UART);
425 Pinmux_Config(HCI_RTS_PIN, PINMUX_FUNCTION_UART_RTSCTS);
426 Pinmux_Config(HCI_CTS_PIN, PINMUX_FUNCTION_UART_RTSCTS);
427
428 PAD_PullCtrl(HCI_TX_PIN, GPIO_PuPd_UP);
429 PAD_PullCtrl(HCI_RX_PIN, GPIO_PuPd_NOPULL);
430 #else
431 #endif
432 UART_InitTypeDef *pUARTStruct;
433 pUARTStruct = &hci_uart_obj->UART_InitStruct;
434
435 UART_StructInit(pUARTStruct);
436 pUARTStruct->WordLen = RUART_WLS_8BITS;
437 pUARTStruct->StopBit = RUART_STOP_BIT_1;
438 pUARTStruct->Parity = RUART_PARITY_DISABLE;
439 pUARTStruct->ParityType = RUART_EVEN_PARITY;
440 pUARTStruct->StickParity = RUART_STICK_PARITY_DISABLE;
441
442 pUARTStruct->RxFifoTrigLevel = UART_RX_FIFOTRIG_LEVEL_14BYTES;
443 /* UART auto-flow control
444 * When the data in UART FIFO reaches rx level, RTS will be pulled high */
445 pUARTStruct->FlowControl = ENABLE;
446
447 UART_Init(HCI_UART_DEV, pUARTStruct);
448 UART_SetBaud(HCI_UART_DEV, 115200);
449
450 InterruptDis(HCI_UART_IRQ);
451 InterruptUnRegister(HCI_UART_IRQ);
452 InterruptRegister((IRQ_FUN)hciuart_irq, HCI_UART_IRQ, (uint32_t)hci_uart_obj, HCIUART_IRQ_PRIO);
453 InterruptEn(HCI_UART_IRQ, HCIUART_IRQ_PRIO);
454
455 hci_uart_obj->ier = RUART_IER_ERBI | RUART_IER_ETOI | RUART_IER_ELSI;
456 UART_INTConfig(HCI_UART_DEV, RUART_IER_ERBI | RUART_IER_ETOI | RUART_IER_ELSI, ENABLE);
457
458 UART_RxCmd(HCI_UART_DEV, ENABLE);
459
460 hci_uart_obj->rx_ind = rx_ind;
461 return true;
462 }
463
hci_uart_deinit(void)464 bool hci_uart_deinit(void)
465 {
466 //hardware deinit
467 UART_DeInit(HCI_UART_DEV);
468 InterruptDis(HCI_UART_IRQ);
469 InterruptUnRegister(HCI_UART_IRQ);
470 #ifdef UART_TIMER
471
472 #endif
473
474 #ifdef HCI_UART_DMA
475
476 #endif
477 hci_uart_free();
478 return true;
479 //free
480 }
481
482
hci_uart_recv(uint8_t * p_buf,uint16_t size)483 uint16_t hci_uart_recv(uint8_t *p_buf, uint16_t size)
484 {
485 uint16_t rx_len;
486
487 T_HCI_UART *p_uart_obj = hci_uart_obj;
488 //hci_board_debug("hci_uart_recv: write:%d, read:%d, rx_len:%d, need:%d, space_len:%d\r\n", p_uart_obj->rx_write_idx, p_uart_obj->rx_read_idx, hci_rx_data_len(), size, hci_rx_space_len());
489
490 if(p_uart_obj == NULL)
491 {
492 hci_board_debug("hci_uart_recv: the p_uart_obj is NULL\r\n");
493 return 0;
494 }
495 if(hci_rx_empty())
496 {
497 //rx empty
498 return 0;
499 }
500 rx_len = hci_rx_data_len();
501
502 if (rx_len > size)
503 {
504 rx_len = size;
505 }
506
507 if (rx_len > HCI_UART_RX_BUF_SIZE - p_uart_obj->rx_read_idx) /* index overflow */
508 {
509 rx_len = HCI_UART_RX_BUF_SIZE - p_uart_obj->rx_read_idx;
510 }
511
512 if (rx_len)
513 {
514 memcpy(p_buf, &(p_uart_obj->rx_buffer[p_uart_obj->rx_read_idx]), rx_len);
515
516 p_uart_obj->rx_read_idx += rx_len;
517 p_uart_obj->rx_read_idx %= HCI_UART_RX_BUF_SIZE;
518
519 if (p_uart_obj->rx_disabled == true) /* flow control */
520 {
521 if (hci_rx_data_len() < HCI_UART_RX_ENABLE_COUNT)
522 {
523 hci_board_debug("hci_uart_recv: rx enable, data len %d\r\n", hci_rx_data_len());
524 hci_uart_rx_enable(p_uart_obj);
525 }
526 }
527 }
528
529 return rx_len;
530 }
531
532
533