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