1 /**
2 * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved.
3 *
4 */
5
6 #include <stdio.h>
7 #include <stdarg.h>
8 #include "trace_uart.h"
9 #include "bt_board.h"
10
11 extern uint8_t hci_tp_lgc_efuse[];
12
13 typedef struct _TraceUartBuffer
14 {
15 uint8_t *tx_buffer;
16 uint16_t tx_len;
17 uint8_t tx_busy;
18 UART_TX_CB tx_cb;
19
20 bool tx_switch;
21 GDMA_InitTypeDef UARTTxGdmaInitStruct;
22 } TRACE_UART_INFO;
23
24 TRACE_UART_INFO g_uart_obj;
25
26 #ifdef TRACE_UART_TX_IRQ
traceuart_stop_tx(TRACE_UART_INFO * trace_pointer)27 static inline void traceuart_stop_tx(TRACE_UART_INFO *trace_pointer)
28 {
29 if (trace_pointer->tx_busy)
30 {
31 trace_pointer->tx_busy = 0;
32 UART_INTConfig(TRACE_UART_DEV, RUART_IER_ETBEI, DISABLE);
33 }
34 }
35
transmit_log(TRACE_UART_INFO * trace_pointer)36 static inline void transmit_log(TRACE_UART_INFO *trace_pointer)
37 {
38 int count;
39 if (trace_pointer->tx_len == 0)
40 {
41 traceuart_stop_tx(trace_pointer);
42 if(trace_pointer->tx_cb)
43 trace_pointer->tx_cb();
44 return;
45 }
46
47 count = TRACE_COUNT;
48 do
49 {
50 UART_CharPut(TRACE_UART_DEV,*trace_pointer->tx_buffer);
51 trace_pointer->tx_buffer++;
52 trace_pointer->tx_len--;
53 }
54 while (--count > 0 && trace_pointer->tx_len > 0);
55 }
56
traceuart_irq(void * data)57 uint32_t traceuart_irq(void *data)
58 {
59 volatile uint8_t reg_iir;
60 uint8_t int_id;
61 uint32_t reg_val;
62 TRACE_UART_INFO *trace_pointer = (TRACE_UART_INFO *) data;
63
64 reg_iir = UART_IntStatus(TRACE_UART_DEV);
65 if ((reg_iir & RUART_IIR_INT_PEND) != 0)
66 {
67 /* No pending IRQ */
68 return 0;
69 }
70
71 int_id = (reg_iir & RUART_IIR_INT_ID) >> 1;
72
73 switch (int_id)
74 {
75 case RUART_TX_FIFO_EMPTY:
76 transmit_log(trace_pointer);
77 break;
78 case RUART_RECEIVE_LINE_STATUS:
79 reg_val = (UART_LineStatusGet(TRACE_UART_DEV));
80 platform_debug("traceuart_irq: LSR interrupt, reg_val=%x\r\n",reg_val);
81 break;
82 default:
83 platform_debug("traceuart_irq: Unknown interrupt type %x", int_id);
84 break;
85 }
86
87 return 0;
88 }
89 #endif
90
trace_uart_init(void)91 bool trace_uart_init(void)
92 {
93 if(!CHECK_SW(EFUSE_SW_TRACE_SWITCH))
94 {
95 //0
96 platform_debug("trace_uart_init: TRACE OPEN");
97 g_uart_obj.tx_switch = true;
98
99 //gloabal_init
100 g_uart_obj.tx_busy = 0;
101
102 Pinmux_Config(TRACE_UART_TX, PINMUX_FUNCTION_UART);
103 // Pinmux_Config(TRACE_UART_RX, PINMUX_FUNCTION_UART)
104
105 PAD_PullCtrl(TRACE_UART_TX, GPIO_PuPd_UP);
106 // PAD_PullCtrl(TRACE_UART_RX, GPIO_PuPd_UP);
107
108 UART_InitTypeDef UARTStruct;
109 UART_InitTypeDef *pUARTStruct = &UARTStruct;
110
111 UART_StructInit(pUARTStruct);
112 pUARTStruct->WordLen = RUART_WLS_8BITS;
113 pUARTStruct->StopBit = RUART_STOP_BIT_1;
114 pUARTStruct->Parity = RUART_PARITY_DISABLE;
115 pUARTStruct->ParityType = RUART_EVEN_PARITY;
116 pUARTStruct->StickParity = RUART_STICK_PARITY_DISABLE;
117
118 UART_Init(TRACE_UART_DEV, pUARTStruct);
119 UART_SetBaud(TRACE_UART_DEV, TRACE_UART_BAUDRATE);
120 UART_RxCmd(TRACE_UART_DEV, DISABLE);
121
122
123 #ifdef TRACE_UART_TX_IRQ
124 InterruptDis(TRACE_UART_IRQ);
125 InterruptUnRegister(TRACE_UART_IRQ);
126 InterruptRegister((IRQ_FUN)traceuart_irq,
127 TRACE_UART_IRQ, (uint32_t)&g_uart_obj,
128 TRACEUART_IRQ_PRIO);
129 InterruptEn(TRACE_UART_IRQ, TRACEUART_IRQ_PRIO);
130 #endif
131 }
132 else
133 {
134 //default 1 close
135 g_uart_obj.tx_switch = false;
136 }
137
138 return true;
139 }
140
trace_uart_deinit(void)141 bool trace_uart_deinit(void)
142 {
143
144 if(!CHECK_SW(EFUSE_SW_TRACE_SWITCH))
145 {
146 if (g_uart_obj.tx_switch == true) {
147 //has already close
148 UART_DeInit(TRACE_UART_DEV);
149 #ifdef TRACE_UART_TX_IRQ
150 InterruptDis(TRACE_UART_IRQ);
151 InterruptUnRegister(TRACE_UART_IRQ);
152 #endif
153 g_uart_obj.tx_switch = false;
154 return true;
155 }
156 else {
157 hci_board_debug("\r\n:trace_uart_deinit: no need\r\n");
158 return false;
159 }
160 }
161 return true;
162 }
163
164
165
166 #ifdef TRACE_UART_DMA
traceuart_dma_tx_complete(void * data)167 static uint32_t traceuart_dma_tx_complete(void *data)
168 {
169 TRACE_UART_INFO *t = (TRACE_UART_INFO *)data;
170 PGDMA_InitTypeDef GDMA_InitStruct;
171 uint8_t IsrTypeMap;
172
173 platform_debug("TRACE DMA Tx complete ISR");
174
175 GDMA_InitStruct = &t->UARTTxGdmaInitStruct;
176
177 GDMA_Cmd(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, DISABLE);
178 IsrTypeMap = GDMA_ClearINT(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum);
179 GDMA_ChnlFree(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum);
180 UART_TXDMACmd(TRACE_UART_DEV, DISABLE);
181 UART_RXDMACmd(TRACE_UART_DEV, DISABLE);
182 /* Wake task to continue tx */
183 t->tx_busy = 0;
184 if(t->tx_cb)
185 t->tx_cb();
186 return 0;
187 }
188 #endif
trace_uart_tx(uint8_t * pstr,uint16_t len,UART_TX_CB tx_cb)189 bool trace_uart_tx(uint8_t *pstr,uint16_t len, UART_TX_CB tx_cb)
190 {
191 if(g_uart_obj.tx_switch == false)
192 {
193 //printf("\r\n trace_uart_deinit has been called please call init \r\n");
194 if(tx_cb)
195 tx_cb();
196 return true;
197 }
198
199 #ifdef TRACE_UART_TX_WHILE
200 UART_SendData(TRACE_UART_DEV, pstr, len);
201 if(tx_cb)
202 tx_cb();
203 #else
204
205 TRACE_UART_INFO *p_uart_obj= &g_uart_obj;
206
207 if (!(p_uart_obj->tx_busy))
208 {
209 p_uart_obj->tx_busy = 1;
210 #ifdef TRACE_UART_TX_IRQ
211 p_uart_obj->tx_buffer = pstr;
212 p_uart_obj->tx_len = len;
213 p_uart_obj->tx_cb = tx_cb;
214 UART_INTConfig(TRACE_UART_DEV, RUART_IER_ETBEI, ENABLE);
215 #endif
216
217 #ifdef TRACE_UART_DMA
218 int ret;
219 UART_TXDMAConfig(TRACE_UART_DEV, 8);
220 UART_TXDMACmd(TRACE_UART_DEV, ENABLE);
221 ret = UART_TXGDMA_Init(TRACE_UART_INDEX, &p_uart_obj->UARTTxGdmaInitStruct,(void *) p_uart_obj, traceuart_dma_tx_complete,pstr,len);
222 NVIC_SetPriority(GDMA_GetIrqNum(0, p_uart_obj->UARTTxGdmaInitStruct.GDMA_ChNum), TRACEUART_DMA_PRIO);
223
224 if (!ret ) {
225 platform_debug("%s Error(%d)\n", __FUNCTION__, ret);
226 p_uart_obj->tx_busy = 0;
227 }
228
229 #endif
230 }
231 else
232 {
233 platform_debug("!!!TX not finished, can't send");
234 return false;
235 }
236
237 #endif
238 return true;
239 }
240
bt_trace_set_switch(bool flag)241 void bt_trace_set_switch(bool flag)
242 {
243 g_uart_obj.tx_switch = flag;
244 }
245
246
247