1 /*
2 * Copyright (c) 2022 Winner Microelectronics Co., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 /**
17 * @file wm_uart.c
18 *
19 * @brief uart Driver Module
20 *
21 * @author dave
22 *
23 * Copyright (c) 2015 Winner Microelectronics Co., Ltd.
24 */
25
26 #include "wm_regs.h"
27 #include "wm_debug.h"
28 #include "wm_irq.h"
29 #include "wm_config.h"
30 #include "wm_mem.h"
31 #include "wm_dma.h"
32 #include "wm_cpu.h"
33 #include "wm_uart.h"
34
35 #if TLS_CONFIG_UART
36
37 #define RX_CACHE_LIMIT 128
38 #define STEP_SIZE (HR_UART1_BASE_ADDR - HR_UART0_BASE_ADDR)
39 #define BUFLEN 2
40
41 extern void tls_irq_priority(u8 vec_no, u32 prio);
42 void tls_uart_tx_callback_register(u16 uart_no, s16(*tx_callback) (struct tls_uart_port *port));
43
44 const u32 baud_rates[] = { 2000000, 1500000, 1250000, 1000000, 921600, 460800,
45 230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1800, 1200, 600 };
46 struct tls_uart_port uart_port[TLS_UART_MAX];
47 static u8 uart_rx_byte_cb_flag[TLS_UART_MAX] = {0};
48
tls_uart_tx_enable(struct tls_uart_port * port)49 static void tls_uart_tx_enable(struct tls_uart_port *port)
50 {
51 u32 ucon;
52
53 ucon = port->regs->UR_LC;
54 ucon |= ULCON_TX_EN;
55 port->regs->UR_LC = ucon;
56 }
57
58 /**
59 * @brief This function is used to continue transfer data.
60 * @param[in] port: is the uart port.
61 * @retval
62 */
tls_uart_tx_chars(struct tls_uart_port * port)63 static void tls_uart_tx_chars(struct tls_uart_port *port)
64 {
65 struct dl_list *pending_list = &port->tx_msg_pending_list;
66 tls_uart_tx_msg_t *tx_msg = NULL;
67 int tx_count;
68 u32 cpu_sr;
69
70 /* send some chars */
71 tx_count = 32;
72 cpu_sr = tls_os_set_critical();
73 if (!dl_list_empty(pending_list)) {
74 tx_msg = dl_list_first(pending_list, tls_uart_tx_msg_t, list);
75 while (tx_count-- > 0 && tx_msg->offset < tx_msg->buflen) {
76 /* ���tx fifo�Ƿ����� */
77 if ((port->regs->UR_FIFOS & UFS_TX_FIFO_CNT_MASK) == port->tx_fifofull) {
78 break;
79 }
80 port->regs->UR_TXW = tx_msg->buf[tx_msg->offset];
81 tx_msg->offset++;
82 port->icount.tx++;
83 }
84
85 if (tx_msg->offset >= tx_msg->buflen) {
86 dl_list_del(&tx_msg->list);
87 dl_list_add_tail(&port->tx_msg_to_be_freed_list, &tx_msg->list);
88 tls_os_release_critical(cpu_sr);
89
90 if (port->tx_sent_callback)
91 port->tx_sent_callback(port);
92
93 if (port->tx_callback)
94 port->tx_callback(port);
95 } else {
96 tls_os_release_critical(cpu_sr);
97 }
98 } else {
99 tls_os_release_critical(cpu_sr);
100 }
101 }
102
UartRegInit(int uart_no)103 static void UartRegInit(int uart_no)
104 {
105 u32 bd;
106 u32 apbclk;
107 tls_sys_clk sysclk;
108
109 tls_sys_clk_get(&sysclk);
110 apbclk = sysclk.apbclk * 1000000;
111
112 if (TLS_UART_0 == uart_no) {
113 bd = (apbclk / (16 * 115200) - 1) | (((apbclk % (115200 * 16)) * 16 / (115200 * 16)) << 16);
114 tls_reg_write32(HR_UART0_BAUD_RATE_CTRL, bd);
115 /* Line control register : Normal,No parity,1 stop,8 bits, only use tx */
116 tls_reg_write32(HR_UART0_LINE_CTRL, ULCON_WL8 | ULCON_TX_EN);
117
118 /* disable auto flow control */
119 tls_reg_write32(HR_UART0_FLOW_CTRL, 0);
120 /* disable dma */
121 tls_reg_write32(HR_UART0_DMA_CTRL, 0);
122 /* one byte tx */
123 tls_reg_write32(HR_UART0_FIFO_CTRL, 0);
124 /* disable interrupt */
125 tls_reg_write32(HR_UART0_INT_MASK, 0xFF);
126 } else {
127 /* 4 byte tx, 8 bytes rx */
128 tls_reg_write32(HR_UART0_FIFO_CTRL + uart_no*STEP_SIZE, (0x01 << 2) | (0x02 << 4));
129 /* enable rx timeout, disable rx dma, disable tx dma */
130 tls_reg_write32(HR_UART0_DMA_CTRL + uart_no*STEP_SIZE, (8 << 3) | (1 << 2));
131 /* enable rx/timeout interrupt */
132 tls_reg_write32(HR_UART0_INT_MASK + uart_no*STEP_SIZE, ~(3 << 2));
133 }
134 }
135
tls_uart_check_baudrate(u32 baudrate)136 int tls_uart_check_baudrate(u32 baudrate)
137 {
138 int i;
139
140 for (i = 0; i < sizeof(baud_rates) / sizeof(u32); i++) {
141 if (baudrate == baud_rates[i])
142 return 1;
143 }
144 /* not found match baudrate */
145 return -1;
146 }
147
tls_uart_get_baud_rate(struct tls_uart_port * port)148 u32 tls_uart_get_baud_rate(struct tls_uart_port * port)
149 {
150 if ((port != NULL) && (port->regs != NULL))
151 return port->opts.baudrate;
152 else
153 return 0;
154 }
155
tls_uart_set_baud_rate_inside(struct tls_uart_port * port,u32 baudrate)156 static int tls_uart_set_baud_rate_inside(struct tls_uart_port *port, u32 baudrate)
157 {
158 int index;
159 u32 value;
160 u32 apbclk;
161 tls_sys_clk sysclk;
162
163 index = tls_uart_check_baudrate(baudrate);
164 if (index < 0) {
165 return WM_FAILED;
166 }
167 tls_sys_clk_get(&sysclk);
168 apbclk = sysclk.apbclk * 1000000;
169 value = (apbclk / (16 * baudrate) - 1) |
170 (((apbclk % (baudrate * 16)) * 16 / (baudrate * 16)) << 16);
171 port->regs->UR_BD = value;
172
173 port->opts.baudrate = baudrate;
174
175 return WM_SUCCESS;
176 }
177
tls_uart_set_parity_inside(struct tls_uart_port * port,TLS_UART_PMODE_T paritytype)178 static int tls_uart_set_parity_inside(struct tls_uart_port *port, TLS_UART_PMODE_T paritytype)
179 {
180 if (port == NULL)
181 return WM_FAILED;
182
183 port->opts.paritytype = paritytype;
184
185 if (paritytype == TLS_UART_PMODE_DISABLED)
186 port->regs->UR_LC &= ~ULCON_PMD_EN;
187 else if (paritytype == TLS_UART_PMODE_EVEN) {
188 port->regs->UR_LC &= ~ULCON_PMD_MASK;
189 port->regs->UR_LC |= ULCON_PMD_EVEN;
190 } else if (paritytype == TLS_UART_PMODE_ODD) {
191 port->regs->UR_LC &= ~ULCON_PMD_MASK;
192 port->regs->UR_LC |= ULCON_PMD_ODD;
193 } else
194 return WM_FAILED;
195
196 return WM_SUCCESS;
197 }
198
tls_uart_set_data_bits(struct tls_uart_port * port,TLS_UART_CHSIZE_T charlength)199 static int tls_uart_set_data_bits(struct tls_uart_port *port, TLS_UART_CHSIZE_T charlength)
200 {
201 if (!port)
202 return WM_FAILED;
203
204 port->opts.charlength = charlength;
205
206 port->regs->UR_LC &= ~ULCON_WL_MASK;
207
208 if (charlength == TLS_UART_CHSIZE_5BIT)
209 port->regs->UR_LC |= ULCON_WL5;
210 else if (charlength == TLS_UART_CHSIZE_6BIT)
211 port->regs->UR_LC |= ULCON_WL6;
212 else if (charlength == TLS_UART_CHSIZE_7BIT)
213 port->regs->UR_LC |= ULCON_WL7;
214 else if (charlength == TLS_UART_CHSIZE_8BIT)
215 port->regs->UR_LC |= ULCON_WL8;
216 else
217 return WM_FAILED;
218
219 return WM_SUCCESS;
220 }
221
tls_uart_set_stop_bits_inside(struct tls_uart_port * port,TLS_UART_STOPBITS_T stopbits)222 static int tls_uart_set_stop_bits_inside(struct tls_uart_port *port, TLS_UART_STOPBITS_T stopbits)
223 {
224 if (!port)
225 return WM_FAILED;
226
227 port->opts.stopbits = stopbits;
228
229 if (stopbits == TLS_UART_TWO_STOPBITS)
230 port->regs->UR_LC |= ULCON_STOP_2;
231 else
232 port->regs->UR_LC &= ~ULCON_STOP_2;
233
234 return WM_SUCCESS;
235 }
236
tls_uart_set_flow_ctrl(struct tls_uart_port * port,TLS_UART_FLOW_CTRL_MODE_T flow_ctrl)237 static TLS_UART_STATUS_T tls_uart_set_flow_ctrl(struct tls_uart_port * port, TLS_UART_FLOW_CTRL_MODE_T flow_ctrl)
238 {
239 TLS_UART_STATUS_T status = TLS_UART_STATUS_OK;
240
241 if (!port)
242 return TLS_UART_STATUS_ERROR;
243 switch (flow_ctrl) {
244 case TLS_UART_FLOW_CTRL_NONE:
245 port->regs->UR_FC = 0;
246 break;
247 case TLS_UART_FLOW_CTRL_HARDWARE:
248 if (TLS_UART_FLOW_CTRL_HARDWARE == port->opts.flow_ctrl) {
249 port->regs->UR_FC = (1UL << 0) | (6UL << 2);
250 }
251 break;
252 default:
253 return TLS_UART_STATUS_ERROR;
254 }
255
256 return status;
257 }
258
tls_uart_set_fc_status(int uart_no,TLS_UART_FLOW_CTRL_MODE_T status)259 void tls_uart_set_fc_status(int uart_no, TLS_UART_FLOW_CTRL_MODE_T status)
260 {
261 struct tls_uart_port *port;
262
263 port = &uart_port[uart_no];
264 port->fcStatus = status;
265 tls_uart_set_flow_ctrl(port, status);
266 // ���ر�����ʱ������tx�Ѿ�ֹͣ����Ҫ�ٴ�tx
267 if (port->opts.flow_ctrl == TLS_UART_FLOW_CTRL_HARDWARE && status == 0 && port->hw_stopped) {
268 tls_uart_tx_enable(port);
269 tls_uart_tx_chars(port);
270 port->hw_stopped = 0;
271 }
272 }
273
tls_uart_rx_disable(struct tls_uart_port * port)274 void tls_uart_rx_disable(struct tls_uart_port *port)
275 {
276 u32 ucon;
277
278 ucon = port->regs->UR_LC;
279 ucon &= ~ULCON_RX_EN;
280 port->regs->UR_LC = ucon;
281 }
282
tls_uart_rx_enable(struct tls_uart_port * port)283 void tls_uart_rx_enable(struct tls_uart_port *port)
284 {
285 port->regs->UR_LC |= ULCON_RX_EN;
286 }
287
tls_uart_tx_disable(struct tls_uart_port * port)288 static void tls_uart_tx_disable(struct tls_uart_port *port)
289 {
290 u32 ucon;
291
292 ucon = port->regs->UR_LC;
293 ucon &= ~ULCON_TX_EN;
294 port->regs->UR_LC = ucon;
295 }
296
tls_uart_config(struct tls_uart_port * port,struct tls_uart_options * opts)297 static int tls_uart_config(struct tls_uart_port *port, struct tls_uart_options *opts)
298 {
299 if (port == NULL || opts == NULL)
300 return WM_FAILED;
301
302 tls_uart_set_baud_rate_inside(port, opts->baudrate);
303 tls_uart_set_parity_inside(port, opts->paritytype);
304 tls_uart_set_data_bits(port, opts->charlength);
305 tls_uart_set_stop_bits_inside(port, opts->stopbits);
306 port->opts.flow_ctrl = opts->flow_ctrl;
307 tls_uart_set_flow_ctrl(port, opts->flow_ctrl);
308
309 {
310 /* clear interrupt */
311 port->regs->UR_INTS = 0xFFFFFFFF;
312 /* enable interupt */
313 port->regs->UR_INTM = 0x0;
314 port->regs->UR_DMAC = (4UL << UDMA_RX_FIFO_TIMEOUT_SHIFT) | UDMA_RX_FIFO_TIMEOUT;
315 }
316
317 /* config FIFO control */
318 port->regs->UR_FIFOC = UFC_TX_FIFO_LVL_16_BYTE | UFC_RX_FIFO_LVL_16_BYTE |
319 UFC_TX_FIFO_RESET | UFC_RX_FIFO_RESET;
320 port->regs->UR_LC &= ~(ULCON_TX_EN | ULCON_RX_EN);
321 port->regs->UR_LC |= ULCON_RX_EN | ULCON_TX_EN;
322
323 return WM_SUCCESS;
324 }
325
326 /**
327 * @brief handle a change of clear-to-send state
328 * @param[in] port: uart_port structure for the open port
329 * @param[in] status: new clear to send status, nonzero if active
330 */
uart_handle_cts_change(struct tls_uart_port * port,unsigned int status)331 static void uart_handle_cts_change(struct tls_uart_port *port, unsigned int status)
332 {
333 if (((port->fcStatus == 1)
334 && (port->opts.flow_ctrl == TLS_UART_FLOW_CTRL_HARDWARE))
335 && (port->uart_no == TLS_UART_1)) {
336 if (port->hw_stopped) {
337 if (status) {
338 port->hw_stopped = 0;
339 tls_uart_tx_enable(port);
340 tls_uart_tx_chars(port);
341 }
342 } else {
343 if (!status) {
344 port->hw_stopped = 1;
345 tls_uart_tx_disable(port);
346 }
347 }
348 }
349 }
350
uart_tx_finish_callback(void * arg)351 static void uart_tx_finish_callback(void *arg)
352 {
353 if (arg) {
354 tls_mem_free(arg);
355 }
356 }
357
tls_uart_tx_remain_len(struct tls_uart_port * port)358 int tls_uart_tx_remain_len(struct tls_uart_port *port)
359 {
360 tls_uart_tx_msg_t *tx_msg = NULL;
361 u16 buf_len = 0;
362 u32 cpu_sr;
363 cpu_sr = tls_os_set_critical();
364 dl_list_for_each(tx_msg, &port->tx_msg_pending_list, tls_uart_tx_msg_t, list) {
365 buf_len += tx_msg->buflen;
366 }
367 tls_os_release_critical(cpu_sr);
368 return TLS_UART_TX_BUF_SIZE - buf_len;
369 }
370
371 /**
372 * @brief This function is used to fill tx buffer.
373 * @param[in] port: is the uart port.
374 * @param[in] buf: is the user buffer.
375 * @param[in] count: is the user data length
376 * @retval
377 */
tls_uart_fill_buf(struct tls_uart_port * port,char * buf,u32 count)378 int tls_uart_fill_buf(struct tls_uart_port *port, char *buf, u32 count)
379 {
380 tls_uart_tx_msg_t *uart_tx_msg;
381 int ret = 0;
382 u32 cpu_sr;
383
384 uart_tx_msg = tls_mem_alloc(sizeof(tls_uart_tx_msg_t));
385 if (uart_tx_msg == NULL) {
386 TLS_DBGPRT_ERR("mem err\n");
387 return -1;
388 }
389 dl_list_init(&uart_tx_msg->list);
390 uart_tx_msg->buf = tls_mem_alloc(count);
391 if (uart_tx_msg->buf == NULL) {
392 tls_mem_free(uart_tx_msg);
393 TLS_DBGPRT_ERR("mem err 1 count=%d\n", count);
394 return -1;
395 }
396 memcpy_s(uart_tx_msg->buf, sizeof(uart_tx_msg->buf), buf, count);
397 uart_tx_msg->buflen = count;
398 uart_tx_msg->offset = 0;
399 uart_tx_msg->finish_callback = uart_tx_finish_callback;
400 uart_tx_msg->callback_arg = uart_tx_msg->buf;
401 cpu_sr = tls_os_set_critical();
402 dl_list_add_tail(&port->tx_msg_pending_list, &uart_tx_msg->list);
403 tls_os_release_critical(cpu_sr);
404 return ret;
405 }
406
407 /**
408 * @brief free the data buffer has been transmitted.
409 * @param[in] port: is the uart port.
410 * @retval
411 */
tls_uart_free_tx_sent_data(struct tls_uart_port * port)412 s16 tls_uart_free_tx_sent_data(struct tls_uart_port *port)
413 {
414 tls_uart_tx_msg_t *tx_msg = NULL;
415 u32 cpu_sr = tls_os_set_critical();
416 while (!dl_list_empty(&port->tx_msg_to_be_freed_list)) {
417 tx_msg = dl_list_first(&port->tx_msg_to_be_freed_list, tls_uart_tx_msg_t, list);
418 dl_list_del(&tx_msg->list);
419 tls_os_release_critical(cpu_sr);
420 if (tx_msg->buf != NULL) {
421 if (tx_msg->finish_callback)
422 tx_msg->finish_callback(tx_msg->callback_arg);
423 tls_mem_free(tx_msg);
424 }
425 cpu_sr = tls_os_set_critical();
426 }
427 tls_os_release_critical(cpu_sr);
428 return 0;
429 }
430
431 /**
432 * @brief This function is used to start transfer data.
433 * @param[in] port: is the uart port.
434 * @retval
435 */
tls_uart_tx_chars_start(struct tls_uart_port * port)436 void tls_uart_tx_chars_start(struct tls_uart_port *port)
437 {
438 struct dl_list *pending_list = &port->tx_msg_pending_list;
439 tls_uart_tx_msg_t *tx_msg = NULL;
440 int tx_count;
441 u32 cpu_sr;
442
443 /* send some chars */
444 tx_count = 32;
445 cpu_sr = tls_os_set_critical();
446 if (!dl_list_empty(pending_list)) {
447 tx_msg = dl_list_first(pending_list, tls_uart_tx_msg_t, list);
448 while (tx_count-- > 0 && tx_msg->offset < tx_msg->buflen) {
449 /* ���tx fifo�Ƿ����� */
450 if ((port->regs->UR_FIFOS & UFS_TX_FIFO_CNT_MASK) ==
451 port->tx_fifofull) {
452 break;
453 }
454 port->regs->UR_TXW = tx_msg->buf[tx_msg->offset];
455 tx_msg->offset++;
456 port->icount.tx++;
457 }
458
459 if (tx_msg->offset >= tx_msg->buflen) {
460 dl_list_del(&tx_msg->list);
461 dl_list_add_tail(&port->tx_msg_to_be_freed_list, &tx_msg->list);
462 tls_os_release_critical(cpu_sr);
463
464 if (port->tx_sent_callback)
465 port->tx_sent_callback(port);
466
467 if (port->tx_callback)
468 port->tx_callback(port);
469 } else {
470 tls_os_release_critical(cpu_sr);
471 }
472 } else {
473 tls_os_release_critical(cpu_sr);
474 }
475 }
476
tls_set_uart_rx_status(int uart_no,int status)477 void tls_set_uart_rx_status(int uart_no, int status)
478 {
479 u32 cpu_sr;
480
481 if (TLS_UART_1 == uart_no) {
482 struct tls_uart_port *port = &uart_port[1];
483 if ((TLS_UART_RX_DISABLE == port->rxstatus
484 && TLS_UART_RX_DISABLE == status)
485 || (TLS_UART_RX_ENABLE == port->rxstatus
486 && TLS_UART_RX_ENABLE == status))
487 return;
488
489 if (TLS_UART_RX_DISABLE == status) {
490 if ((TLS_UART_FLOW_CTRL_HARDWARE == port->opts.flow_ctrl)
491 && (TLS_UART_FLOW_CTRL_HARDWARE == port->fcStatus)) {
492 cpu_sr = tls_os_set_critical();
493 // ��rxfifo trigger level interrupt��overrun error
494 port->regs->UR_INTM |= ((0x1 << 2) | (0x01 << 8));
495 port->rxstatus = TLS_UART_RX_DISABLE;
496 tls_os_release_critical(cpu_sr);
497 }
498 } else {
499 cpu_sr = tls_os_set_critical();
500 uart_port[1].regs->UR_INTM &= ~((0x1 << 2) | (0x01 << 8));
501 port->rxstatus = TLS_UART_RX_ENABLE;
502 tls_os_release_critical(cpu_sr);
503 }
504 }
505 }
506
UART0_IRQHandler(void)507 ATTRIBUTE_ISR void UART0_IRQHandler(void)
508 {
509 struct tls_uart_port *port = &uart_port[0];
510 struct tls_uart_circ_buf *recv = &port->recv;
511 u8 rx_byte_cb_flag = uart_rx_byte_cb_flag[0];
512 u32 intr_src;
513 u32 rx_fifocnt;
514 u32 fifos;
515 u8 ch;
516 u32 rxlen = 0;
517 csi_kernel_intrpt_enter();
518
519 /* check interrupt status */
520 intr_src = port->regs->UR_INTS;
521 port->regs->UR_INTS = intr_src;
522
523 if ((intr_src & UART_RX_INT_FLAG) && ((port->regs->UR_INTM & UIS_RX_FIFO) == 0)) {
524 rx_fifocnt = (port->regs->UR_FIFOS >> 6) & 0x3F;
525 while (rx_fifocnt-- > 0) {
526 ch = (u8) port->regs->UR_RXW;
527 if (intr_src & UART_RX_ERR_INT_FLAG) {
528 port->regs->UR_INTS |= UART_RX_ERR_INT_FLAG;
529 TLS_DBGPRT_INFO("\nrx err=%x,c=%d,ch=%x\n", intr_src, rx_fifocnt, ch);
530 /* not insert to buffer */
531 continue;
532 }
533 if (CIRC_SPACE(recv->head, recv->tail, TLS_UART_RX_BUF_SIZE) <= 2) {
534 TLS_DBGPRT_INFO("\nrx buf overrun int_src=%x\n", intr_src);
535 if (TLS_UART_FLOW_CTRL_HARDWARE == port->fcStatus) {
536 tls_set_uart_rx_status(port->uart_no, TLS_UART_RX_DISABLE);
537 rx_fifocnt = 0; // �����Ӳ�����أ��رս��գ������һ���ַ��Ž�����buffer��
538 } else
539 break;
540 }
541
542 /* insert the character into the buffer */
543 recv->buf[recv->head] = ch;
544 recv->head = (recv->head + 1) & (TLS_UART_RX_BUF_SIZE - 1);
545 rxlen++;
546 if (port->rx_callback != NULL && rx_byte_cb_flag) {
547 port->rx_callback(1, port->priv_data);
548 }
549 }
550 if (port->rx_callback != NULL && !rx_byte_cb_flag) {
551 port->rx_callback(rxlen, port->priv_data);
552 }
553 }
554
555 if (intr_src & UART_TX_INT_FLAG) {
556 tls_uart_tx_chars(port);
557 }
558
559 if (intr_src & UIS_CTS_CHNG) {
560 fifos = port->regs->UR_FIFOS;
561 uart_handle_cts_change(port, fifos & UFS_CST_STS);
562 }
563 csi_kernel_intrpt_exit();
564 }
565
tls_uart_push(int index,u8 * data,int length)566 void tls_uart_push(int index, u8* data, int length)
567 {
568 int i = 0;
569 struct tls_uart_port *port = &uart_port[1];
570 struct tls_uart_circ_buf *recv = &port->recv;
571 while (i<length) {
572 recv->buf[recv->head] = data[i];
573 recv->head = (recv->head + 1) & (TLS_UART_RX_BUF_SIZE - 1);
574 i++;
575 }
576 }
577
UART1_IRQHandler(void)578 ATTRIBUTE_ISR void UART1_IRQHandler(void)
579 {
580 struct tls_uart_port *port = &uart_port[1];
581 struct tls_uart_circ_buf *recv = &port->recv;
582 u8 rx_byte_cb_flag = uart_rx_byte_cb_flag[1];
583 u32 intr_src;
584 u32 rx_fifocnt;
585 u32 fifos;
586 u8 ch = 0;
587 u8 escapefifocnt = 0;
588 u32 rxlen = 0;
589 csi_kernel_intrpt_enter();
590
591 intr_src = port->regs->UR_INTS;
592 port->regs->UR_INTS = intr_src;
593
594 if (intr_src & UIS_OVERRUN) {
595 port->regs->UR_INTS |= UIS_OVERRUN;
596 if (port->tx_dma_on) {
597 tls_reg_write32((int)&port->regs->UR_DMAC, (tls_reg_read32((int)&port->regs->UR_DMAC) & ~0x01));
598 tls_reg_write32((int)&port->regs->UR_DMAC, (tls_reg_read32((int)&port->regs->UR_DMAC) | 0x01));
599 }
600 }
601 if ((intr_src & UART_RX_INT_FLAG) && ((port->regs->UR_INTM & UIS_RX_FIFO) == 0)) {
602 rx_fifocnt = (port->regs->UR_FIFOS >> 6) & 0x3F;
603 escapefifocnt = rx_fifocnt;
604 port->plus_char_cnt = 0;
605 rxlen = rx_fifocnt;
606
607 if (CIRC_SPACE(recv->head, recv->tail, TLS_UART_RX_BUF_SIZE) <= RX_CACHE_LIMIT) {
608 recv->tail = (recv->tail + RX_CACHE_LIMIT) & (TLS_UART_RX_BUF_SIZE - 1);
609 }
610
611 while (rx_fifocnt-- > 0) {
612 ch = (u8) port->regs->UR_RXW;
613 if (intr_src & UART_RX_ERR_INT_FLAG) {
614 port->regs->UR_INTS |= UART_RX_ERR_INT_FLAG;
615 TLS_DBGPRT_INFO("\nrx err=%x,c=%d,ch=%x\n", intr_src, rx_fifocnt, ch);
616 continue;
617 }
618 recv->buf[recv->head] = ch;
619 recv->head = (recv->head + 1) & (TLS_UART_RX_BUF_SIZE - 1);
620 }
621
622 if (escapefifocnt == 3 && ch == '+') {
623 switch (recv->head-1) {
624 case 0:
625 if (recv->buf[TLS_UART_RX_BUF_SIZE-1]=='+' && recv->buf[TLS_UART_RX_BUF_SIZE-2]=='+')
626 port->plus_char_cnt = 3;
627 break;
628 case 1:
629 if (recv->buf[0]=='+' && recv->buf[TLS_UART_RX_BUF_SIZE-1]=='+')
630 port->plus_char_cnt = 3;
631 break;
632 default:
633 if (recv->buf[recv->head-2]=='+' && recv->buf[recv->head-3]=='+')
634 port->plus_char_cnt = 3;
635 break;
636 }
637 if (port->rx_callback != NULL && rx_byte_cb_flag) {
638 port->rx_callback(1, port->priv_data);
639 }
640 }
641 if (port->rx_callback!=NULL && !rx_byte_cb_flag) {
642 port->rx_callback(rxlen, port->priv_data);
643 }
644 }
645 if (intr_src & UART_TX_INT_FLAG) {
646 tls_uart_tx_chars(port);
647 }
648 if (intr_src & UIS_CTS_CHNG) {
649 fifos = port->regs->UR_FIFOS;
650 uart_handle_cts_change(port, fifos & UFS_CST_STS);
651 }
652 csi_kernel_intrpt_exit();
653 }
654
findOutIntUart(void)655 static int findOutIntUart(void)
656 {
657 int i;
658 u32 regValue;
659
660 for (i=TLS_UART_2; i< TLS_UART_MAX; i++) {
661 regValue = tls_reg_read32(HR_UART0_INT_SRC + i*STEP_SIZE);
662 regValue &= 0x1FF;
663 if (regValue)
664 break;
665 }
666 return i;
667 }
668
UART2_4_IRQHandler(void)669 ATTRIBUTE_ISR void UART2_4_IRQHandler(void)
670 {
671 int intUartNum = findOutIntUart();
672 struct tls_uart_port *port = &uart_port[intUartNum];
673 struct tls_uart_circ_buf *recv = &port->recv;
674 u8 rx_byte_cb_flag = uart_rx_byte_cb_flag[intUartNum];
675 u32 intr_src;
676 u32 rx_fifocnt;
677 u32 fifos;
678 u8 escapefifocnt = 0;
679 u32 rxlen = 0;
680 u8 ch;
681 csi_kernel_intrpt_enter();
682
683 intr_src = port->regs->UR_INTS;
684
685 if (intr_src & UIS_OVERRUN) {
686 port->regs->UR_INTS |= UIS_OVERRUN;
687 if (port->tx_dma_on) {
688 tls_reg_write32((int)&port->regs->UR_DMAC, (tls_reg_read32((int)&port->regs->UR_DMAC) & ~0x01));
689 tls_reg_write32((int)&port->regs->UR_DMAC, (tls_reg_read32((int)&port->regs->UR_DMAC) | 0x01));
690 }
691 }
692 if ((intr_src & UART_RX_INT_FLAG) && ((port->regs->UR_INTM & UIS_RX_FIFO) == 0)) {
693 rx_fifocnt = (port->regs->UR_FIFOS >> 6) & 0x3F;
694 escapefifocnt = rx_fifocnt;
695 port->plus_char_cnt = 0;
696 rxlen = rx_fifocnt;
697
698 if (CIRC_SPACE(recv->head, recv->tail, TLS_UART_RX_BUF_SIZE) <= RX_CACHE_LIMIT) {
699 recv->tail = (recv->tail + RX_CACHE_LIMIT) & (TLS_UART_RX_BUF_SIZE - 1);
700 }
701
702 while (rx_fifocnt-- > 0) {
703 ch = (u8) port->regs->UR_RXW;
704 if (intr_src & UART_RX_ERR_INT_FLAG) {
705 port->regs->UR_INTS |= UART_RX_ERR_INT_FLAG;
706 TLS_DBGPRT_INFO("\nrx err=%x,c=%d,ch=%x\n", intr_src, rx_fifocnt, ch);
707 continue;
708 }
709 recv->buf[recv->head] = ch;
710 recv->head = (recv->head + 1) & (TLS_UART_RX_BUF_SIZE - 1);
711 }
712
713 if (escapefifocnt==3 && ch=='+') {
714 switch (recv->head-1) {
715 case 0:
716 if (recv->buf[TLS_UART_RX_BUF_SIZE-1]=='+' && recv->buf[TLS_UART_RX_BUF_SIZE-2]=='+')
717 port->plus_char_cnt = 3;
718 break;
719 case 1:
720 if (recv->buf[0]=='+' && recv->buf[TLS_UART_RX_BUF_SIZE-1]=='+')
721 port->plus_char_cnt = 3;
722 break;
723 default:
724 if (recv->buf[recv->head-2]=='+' && recv->buf[recv->head-3]=='+')
725 port->plus_char_cnt = 3;
726 break;
727 }
728 if (port->rx_callback != NULL && rx_byte_cb_flag) {
729 port->rx_callback(1, port->priv_data);
730 }
731 }
732 if (port->rx_callback!=NULL && !rx_byte_cb_flag) {
733 port->rx_callback(rxlen, port->priv_data);
734 }
735 }
736
737 if (intr_src & UART_TX_INT_FLAG) {
738 tls_uart_tx_chars(port);
739 }
740
741 if (intr_src & UIS_CTS_CHNG) {
742 fifos = port->regs->UR_FIFOS;
743 uart_handle_cts_change(port, fifos & UFS_CST_STS);
744 }
745 port->regs->UR_INTS = intr_src;
746 csi_kernel_intrpt_exit();
747 }
748
749 /**
750 * @brief This function is used to initial uart port.
751 *
752 * @param[in] uart_no: is the uart number.
753 * - \ref TLS_UART_0 TLS_UART_1 TLS_UART_2 TLS_UART_3 TLS_UART_4 TLS_UART5
754 * @param[in] opts: is the uart setting options,if this param is NULL,this function will use the default options.
755 * @param[in] modeChoose:; choose uart2 mode or 7816 mode when uart_no is TLS_UART_2,
756 * 0 for uart2 mode and 1 for 7816 mode.
757 *
758 * @retval
759 * - \ref WM_SUCCESS
760 * - \ref WM_FAILED
761 *
762 * @note When the system is initialized, the function has been called, so users can not call the function.
763 */
tls_uart_port_init(u16 uart_no,tls_uart_options_t * opts,u8 modeChoose)764 int tls_uart_port_init(u16 uart_no, tls_uart_options_t * opts, u8 modeChoose)
765 {
766 struct tls_uart_port *port;
767 int ret;
768 tls_uart_options_t opt;
769 if (TLS_UART_MAX <= uart_no) {
770 return WM_FAILED;
771 }
772
773 switch (uart_no) {
774 case TLS_UART_0:
775 case TLS_UART_1:
776 tls_irq_disable((UART0_IRQn+uart_no));
777 break;
778 case TLS_UART_2:
779 case TLS_UART_3:
780 case TLS_UART_4:
781 case TLS_UART_5:
782 tls_irq_disable(UART24_IRQn);
783 break;
784 }
785
786 UartRegInit(uart_no);
787 if (uart_port[uart_no].recv.buf) {
788 tls_mem_free((void *)uart_port[uart_no].recv.buf);
789 uart_port[uart_no].recv.buf = NULL;
790 }
791 memset_s(&uart_port[uart_no], sizeof(uart_port), 0, sizeof(struct tls_uart_port));
792 port = &uart_port[uart_no];
793 port->regs = (TLS_UART_REGS_T *)(HR_UART0_BASE_ADDR + uart_no*STEP_SIZE);
794 if (uart_no==TLS_UART_2) {
795 (modeChoose == 1)?(port->regs->UR_LC |= (1 << 24)):(port->regs->UR_LC &= ~(0x1000000));
796 }
797 port->uart_no = uart_no;
798
799 if (opts == NULL) {
800 opt.baudrate = UART_BAUDRATE_B115200;
801 opt.charlength = TLS_UART_CHSIZE_8BIT;
802 opt.flow_ctrl = TLS_UART_FLOW_CTRL_NONE;
803 opt.paritytype = TLS_UART_PMODE_DISABLED;
804 opt.stopbits = TLS_UART_ONE_STOPBITS;
805 ret = tls_uart_config(port, &opt);
806 } else {
807 ret = tls_uart_config(port, opts);
808 }
809
810 if (ret != WM_SUCCESS)
811 return WM_FAILED;
812 port->rxstatus = TLS_UART_RX_ENABLE;
813 switch (uart_no) {
814 case TLS_UART_0:
815 case TLS_UART_1:
816 port->uart_irq_no = (UART0_IRQn+uart_no);
817 break;
818 case TLS_UART_2:
819 case TLS_UART_3:
820 case TLS_UART_4:
821 case TLS_UART_5:
822 port->uart_irq_no = UART24_IRQn;
823 break;
824 }
825
826 if (port->recv.buf == NULL) {
827 char *bufrx = tls_mem_alloc(TLS_UART_RX_BUF_SIZE);
828 if (!bufrx)
829 return WM_FAILED;
830 memset_s(bufrx, sizeof(bufrx), 0, TLS_UART_RX_BUF_SIZE);
831 port->recv.buf = (u8 *) bufrx;
832 }
833 port->recv.head = 0;
834 port->recv.tail = 0;
835 port->tx_fifofull = 16;
836 dl_list_init(&port->tx_msg_pending_list);
837 dl_list_init(&port->tx_msg_to_be_freed_list);
838 tls_uart_tx_callback_register(uart_no, tls_uart_free_tx_sent_data);
839
840 tls_irq_enable(port->uart_irq_no); /* enable uart interrupt */
841 return WM_SUCCESS;
842 }
843
844 /**
845 * @brief This function is used to register uart rx interrupt.
846 *
847 * @param[in] uart_no: is the uart numer.
848 * @param[in] callback: is the uart rx interrupt call back function.
849 *
850 * @retval
851 *
852 * @note This function should be called after the fucntion tls_uart_port_init() or it won't work.
853 */
tls_uart_rx_callback_register(u16 uart_no,s16 (* rx_callback)(u16 len,void * user_data),void * priv_data)854 void tls_uart_rx_callback_register(u16 uart_no, s16(*rx_callback) (u16 len, void* user_data), void *priv_data)
855 {
856 uart_port[uart_no].rx_callback = rx_callback;
857 uart_port[uart_no].priv_data = priv_data;
858 }
859
tls_uart_rx_byte_callback_flag(u16 uart_no,u8 flag)860 void tls_uart_rx_byte_callback_flag(u16 uart_no, u8 flag)
861 {
862 uart_rx_byte_cb_flag[uart_no] = flag;
863 }
864
865 /**
866 * @brief This function is used to register uart tx interrupt.
867 *
868 * @param[in] uart_no: is the uart numer.
869 * @param[in] callback: is the uart tx interrupt call back function.
870 *
871 * @retval
872 */
tls_uart_tx_callback_register(u16 uart_no,s16 (* tx_callback)(struct tls_uart_port * port))873 void tls_uart_tx_callback_register(u16 uart_no, s16(*tx_callback) (struct tls_uart_port *port))
874 {
875 uart_port[uart_no].tx_callback = tx_callback;
876 }
tls_uart_tx_sent_callback_register(u16 uart_no,s16 (* tx_callback)(struct tls_uart_port * port))877 void tls_uart_tx_sent_callback_register(u16 uart_no, s16(*tx_callback) (struct tls_uart_port *port))
878 {
879 uart_port[uart_no].tx_sent_callback = tx_callback;
880 }
881
tls_uart_try_read(u16 uart_no,int32_t read_size)882 int tls_uart_try_read(u16 uart_no, int32_t read_size)
883 {
884 int data_cnt = 0;
885 struct tls_uart_port *port = &uart_port[uart_no];
886 struct tls_uart_circ_buf *recv = &port->recv;
887
888 data_cnt = CIRC_CNT(recv->head, recv->tail, TLS_UART_RX_BUF_SIZE);
889 if (data_cnt >= read_size) {
890 return read_size;
891 } else {
892 return 0;
893 }
894 }
895
896 /**
897 * @brief This function is used to copy circular buffer data to user buffer.
898 * @param[in] uart_no: is the uart numer.
899 * @param[in] buf: is the user buffer.
900 * @param[in] readsize: is the user read size.
901 * @retval
902 */
tls_uart_read(u16 uart_no,u8 * buf,u16 readsize)903 int tls_uart_read(u16 uart_no, u8 * buf, u16 readsize)
904 {
905 int data_cnt, buflen;
906 struct tls_uart_port *port = NULL;
907 struct tls_uart_circ_buf *recv;
908
909 if (buf == NULL || readsize < 1) {
910 return WM_FAILED;
911 }
912
913 port = &uart_port[uart_no];
914 recv = &port->recv;
915 data_cnt = CIRC_CNT(recv->head, recv->tail, TLS_UART_RX_BUF_SIZE);
916 (data_cnt >= readsize)?(buflen = readsize):(buflen = data_cnt);
917 if ((recv->tail + buflen) > TLS_UART_RX_BUF_SIZE) {
918 int bufcopylen = (TLS_UART_RX_BUF_SIZE - recv->tail);
919 MEMCPY(buf, (void *)(recv->buf + recv->tail), bufcopylen);
920 MEMCPY(buf + bufcopylen, (void *)recv->buf, buflen - bufcopylen);
921 } else {
922 MEMCPY(buf, (void *)(recv->buf + recv->tail), buflen);
923 }
924 recv->tail = (recv->tail + buflen) & (TLS_UART_RX_BUF_SIZE - 1);
925 return buflen;
926 }
927
928 /**
929 * @brief This function is used to transfer data throuth DMA.
930 *
931 * @param[in] buf is a buf for saving user data
932 * @param[in] writesize is the user data length
933 * @param[in] cmpl_callback function point,when the transfer is completed, the function will be called.
934 *
935 * @retval WM_SUCCESS success
936 * @retval WM_FAILED failed
937 *
938 * @note Only uart1 support DMA transfer.
939 */
tls_uart_dma_write_complte_callback(void * parg)940 static void tls_uart_dma_write_complte_callback(void *parg)
941 {
942 u32 dma_uart_ch = (u32)parg;
943 u16 uart_no = (dma_uart_ch&0x00FFFF00)>>8;
944 u8 dma_ch = dma_uart_ch&0xFF;
945 struct tls_uart_port *port = &uart_port[uart_no];
946
947 tls_dma_free(dma_ch);
948 port->tx_dma_on = FALSE;
949
950 if (port->tx_sent_callback) {
951 port->tx_sent_callback((void*)uart_no);
952 }
953 }
tls_uart_dma_write(char * buf,u16 writesize,void (* cmpl_callback)(void * p),u16 uart_no)954 int tls_uart_dma_write(char *buf, u16 writesize, void (*cmpl_callback) (void *p), u16 uart_no)
955 {
956 unsigned char dmaCh = 0;
957 struct tls_dma_descriptor DmaDesc;
958 struct tls_uart_port *port = &uart_port[uart_no];
959
960 if (buf == NULL || writesize < 1 || writesize >= 4096) {
961 TLS_DBGPRT_ERR("param err\n");
962 return WM_FAILED;
963 }
964 if (port->tx_dma_on) {
965 TLS_DBGPRT_ERR("transmiting,wait\n");
966 return WM_FAILED;
967 }
968
969 /* Request DMA Channel */
970 dmaCh = tls_dma_request(0xFF, TLS_DMA_FLAGS_CHANNEL_SEL(TLS_DMA_SEL_UART_TX) | TLS_DMA_FLAGS_HARD_MODE);
971 if (dmaCh == 0xFF) {
972 TLS_DBGPRT_ERR("dma request err\n");
973 return WM_FAILED;
974 }
975 tls_reg_write32(HR_DMA_CHNL_SEL, uart_no);
976 tls_reg_write32((int)&port->regs->UR_DMAC, (tls_reg_read32((int)&port->regs->UR_DMAC) & ~0x01));
977
978 port->tx_sent_callback = (s16(*) (struct tls_uart_port *))cmpl_callback;
979 tls_dma_irq_register(dmaCh, tls_uart_dma_write_complte_callback, \
980 (void *)(u32)(dmaCh|(uart_no<<8)), TLS_DMA_IRQ_TRANSFER_DONE);
981
982 /* Enable uart TX DMA */
983 port->tx_dma_on = TRUE;
984 tls_reg_write32((int)&port->regs->UR_DMAC, (tls_reg_read32((int)&port->regs->UR_DMAC) | 0x01));
985 DmaDesc.src_addr = (int) buf;
986 DmaDesc.dest_addr = (int)&port->regs->UR_TXW;
987 DmaDesc.dma_ctrl = TLS_DMA_DESC_CTRL_SRC_ADD_INC | TLS_DMA_DESC_CTRL_DATA_SIZE_BYTE | (writesize << 7);
988 DmaDesc.valid = TLS_DMA_DESC_VALID;
989 DmaDesc.next = NULL;
990 tls_dma_start(dmaCh, &DmaDesc, 0);
991
992 return WM_SUCCESS;
993 }
994
995 /**
996 * @brief This function is used to transfer data asynchronous.
997 *
998 * @param[in] uart_no is the uart number
999 * @param[in] buf is a buf for saving user data.
1000 * @param[in] writesize is the data length
1001 *
1002 * @retval WM_SUCCESS success
1003 * @retval WM_FAILED failed
1004 *
1005 * @note The function only start transmission, fill buffer in the callback function.
1006 */
tls_uart_write_async(u16 uart_no,char * buf,u16 writesize)1007 int tls_uart_write_async(u16 uart_no, char *buf, u16 writesize)
1008 {
1009 struct tls_uart_port *port = NULL;
1010 int ret;
1011
1012 if (buf == NULL || writesize < 1) {
1013 TLS_DBGPRT_ERR("param err\n");
1014 return WM_FAILED;
1015 }
1016
1017 port = &uart_port[uart_no];
1018 ret = tls_uart_fill_buf(port, buf, writesize);
1019 if (ret == 0) {
1020 tls_uart_tx_chars_start(port);
1021 }
1022
1023 return ret;
1024 }
1025
1026 /**
1027 * @brief get the data length has been transmitted.
1028 *
1029 * @param[in] uart_no is the uart number
1030 *
1031 * @retval the length has been transmitted
1032 *
1033 */
tls_uart_tx_length(u16 uart_no)1034 int tls_uart_tx_length(u16 uart_no)
1035 {
1036 struct tls_uart_port *port = &uart_port[uart_no];
1037
1038 return port->icount.tx;
1039 }
1040
1041 /**
1042 * @brief This function is used to transfer data synchronous.
1043 *
1044 * @param[in] uart_no is the uart number
1045 * @param[in] buf is a buf for saving user data.
1046 * @param[in] writesize is the data length
1047 *
1048 * @retval WM_SUCCESS success
1049 * @retval WM_FAILED failed
1050 *
1051 * @note The function only start transmission, fill buffer in the callback function.
1052 */
tls_uart_write(u16 uart_no,char * buf,u16 writesize)1053 int tls_uart_write(u16 uart_no, char *buf, u16 writesize)
1054 {
1055 return tls_uart_write_async(uart_no, buf, writesize);
1056 }
1057
1058 /**
1059 * @brief This function is used to set uart parity.
1060 *
1061 * @param[in] paritytype is a parity type defined in TLS_UART_PMODE_T
1062 *
1063 * @retval WM_SUCCESS success
1064 * @retval WM_FAILED failed
1065 *
1066 */
tls_uart_set_parity(u16 uart_no,TLS_UART_PMODE_T paritytype)1067 int tls_uart_set_parity(u16 uart_no, TLS_UART_PMODE_T paritytype)
1068 {
1069 return tls_uart_set_parity_inside(&uart_port[uart_no], paritytype);
1070 }
1071
1072 /**
1073 * @brief This function is used to set uart baudrate.
1074 *
1075 * @param[in] uart_no is the uart number
1076 * @param[in] baudrate is the baudrate user want used,the unit is HZ.
1077 *
1078 * @retval WM_SUCCESS success
1079 * @retval WM_FAILED failed
1080 *
1081 */
tls_uart_set_baud_rate(u16 uart_no,u32 baudrate)1082 int tls_uart_set_baud_rate(u16 uart_no, u32 baudrate)
1083 {
1084 return tls_uart_set_baud_rate_inside(&uart_port[uart_no], baudrate);
1085 }
1086
1087 /**
1088 * @brief This function is used to set uart stop bits.
1089 *
1090 * @param[in] uart_no is the uart number
1091 * @param[in] stopbits is a stop bit type defined in TLS_UART_STOPBITS_T.
1092 *
1093 * @retval WM_SUCCESS success
1094 * @retval WM_FAILED failed
1095 *
1096 */
tls_uart_set_stop_bits(u16 uart_no,TLS_UART_STOPBITS_T stopbits)1097 int tls_uart_set_stop_bits(u16 uart_no, TLS_UART_STOPBITS_T stopbits)
1098 {
1099 return tls_uart_set_stop_bits_inside(&uart_port[uart_no], stopbits);
1100 }
1101
tls_uart_dma_off(u16 uart_no)1102 int tls_uart_dma_off(u16 uart_no)
1103 {
1104 uart_port[uart_no].tx_dma_on = FALSE;
1105 return WM_SUCCESS;
1106 }
1107
HiLogWriteInternal(const char * buffer,size_t bufLen)1108 int HiLogWriteInternal(const char *buffer, size_t bufLen)
1109 {
1110 if (!buffer) {
1111 return -1;
1112 }
1113
1114 if (bufLen < BUFLEN) {
1115 return 0;
1116 }
1117
1118 if (buffer[bufLen - BUFLEN] != '\n') {
1119 *((char *)buffer + bufLen - 1) = '\n';
1120 }
1121
1122 return 0;
1123 }
1124
1125 #endif
1126 // TLS_CONFIG_UART