1 /*
2
3 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
4 */
5
6 #include "cmsis.h"
7 #include "cmsis_os.h"
8 #define BES_HAL_DEBUG 0
9 #include "aos/kernel.h"
10 #include "k_api.h"
11 #include "app_hal.h"
12 #include "aos/errno.h"
13 #include "aos/hal/uart.h"
14 #include "ulog/ulog.h"
15 #include "hal_uart.h"
16 #include "hal_trace.h"
17 #include "plat_types.h"
18
19 #define UART_FIFO_MAX_BUFFER 2048
20 #define UART_DMA_RING_BUFFER_SIZE 256// mast be 2^n
21
22 static __SRAMBSS unsigned char _hal_uart_buf[UART_DMA_RING_BUFFER_SIZE];
23 static __SRAMBSS unsigned char _hal_uart1_buf[UART_DMA_RING_BUFFER_SIZE];
24 static __SRAMBSS unsigned char _hal_uart2_buf[UART_DMA_RING_BUFFER_SIZE];
25
26 typedef struct
27 {
28 uint32_t init_flag;
29 uint8_t *uart_buffer;
30 uint8_t *rx_ringbuf;
31 int32_t rxring_size;
32 int32_t rxbuf_in;
33 int32_t rxbuf_out;
34 ksem_t rx_sem;
35 ksem_t tx_sem;
36 ksem_t rx_irq_bottom_sem;
37 kmutex_t rx_cb_mutex;
38 uart_rx_cb rx_cb;
39 uart_dev_t *rx_cb_arg;
40 ktask_t *rx_irq_bottom_task;
41 void (*uart_dma_rx_handler)(uint32_t xfer_size, int dma_error, union HAL_UART_IRQ_T status);
42 void (*uart_dma_tx_handler)(uint32_t xfer_size, int dma_error);
43 }uart_ctx_obj_t;
44
45 static uart_ctx_obj_t uart_ctx[3] = {0};
46
47 struct HAL_UART_CFG_T low_uart_cfg = { // used for tgdb cli console
48 .parity = HAL_UART_PARITY_NONE,
49 .stop = HAL_UART_STOP_BITS_1,
50 .data = HAL_UART_DATA_BITS_8,
51 .flow = HAL_UART_FLOW_CONTROL_NONE,
52 .tx_level = HAL_UART_FIFO_LEVEL_7_8,
53 .rx_level = HAL_UART_FIFO_LEVEL_1_8,
54 .baud = 0,
55 .dma_rx = false,
56 .dma_tx = false,
57 .dma_rx_stop_on_err = false,
58 };
59
hal_set_uart_iomux(uint32_t uart_id)60 static void hal_set_uart_iomux(uint32_t uart_id)
61 {
62 if (uart_id == HAL_UART_ID_0) {
63 hal_iomux_set_uart0();
64 } else if (uart_id == HAL_UART_ID_1) {
65 hal_iomux_set_uart1();
66 } else {
67 hal_iomux_set_uart2();
68 }
69 }
70
hal_uart_rx_start(uint32_t uart_id)71 static void hal_uart_rx_start(uint32_t uart_id)
72 {
73 struct HAL_DMA_DESC_T dma_desc_rx;
74 unsigned int desc_cnt = 1;
75 union HAL_UART_IRQ_T mask;
76
77 mask.reg = 0;
78 mask.BE = 0;
79 mask.FE = 0;
80 mask.OE = 0;
81 mask.PE = 0;
82 mask.RT = 1;
83
84 hal_uart_dma_recv_mask(uart_id, uart_ctx[uart_id].uart_buffer, UART_DMA_RING_BUFFER_SIZE, &dma_desc_rx, &desc_cnt, &mask);
85
86 }
87
_get_uart_ringbuf_freesize(uint32_t uart_id)88 static int32_t _get_uart_ringbuf_freesize(uint32_t uart_id)
89 {
90 int32_t size = 0;
91
92 /*if uart haven't init free size is zero*/
93 if (uart_ctx[uart_id].init_flag == 0) {
94 return 0;
95 }
96
97 /*now input index equals output index means fifo empty*/
98 if (uart_ctx[uart_id].rxbuf_in == uart_ctx[uart_id].rxbuf_out) {
99 size = uart_ctx[uart_id].rxring_size;
100 } else if (uart_ctx[uart_id].rxbuf_in > uart_ctx[uart_id].rxbuf_out) {
101 size = uart_ctx[uart_id].rxring_size - uart_ctx[uart_id].rxbuf_in + uart_ctx[uart_id].rxbuf_out;
102 } else {
103 size = uart_ctx[uart_id].rxbuf_out - uart_ctx[uart_id].rxbuf_in;
104 }
105
106 return size;
107 }
108
_get_uart_ringbuf_available_read_size(uint32_t uart_id)109 static int32_t _get_uart_ringbuf_available_read_size(uint32_t uart_id)
110 {
111 uint32_t size = 0;
112
113 /*if uart haven't init free size is zero*/
114 if (uart_ctx[uart_id].init_flag == 0) {
115 return 0;
116 }
117 size = uart_ctx[uart_id].rxring_size - _get_uart_ringbuf_freesize(uart_id);
118
119 return size;
120 }
121
122 /*return value is push in data size */
_uart_ringbuffer_push(uint32_t uart_id,uint8_t * buf,int32_t len)123 static int32_t _uart_ringbuffer_push(uint32_t uart_id, uint8_t *buf, int32_t len)
124 {
125 int32_t free_size = 0;
126 int32_t write_size = 0;
127 int32_t spilt_len = 0;
128
129 if (uart_id > HAL_UART_ID_2 || uart_ctx[uart_id].init_flag == 0) {
130 return 0;
131 }
132
133 free_size = _get_uart_ringbuf_freesize(uart_id);
134
135 /*get real read_size */
136 if (free_size > len) {
137 write_size = len;
138 } else {
139 write_size = free_size;
140 }
141
142 if (write_size != 0 ) {
143 spilt_len = uart_ctx[uart_id].rxring_size - uart_ctx[uart_id].rxbuf_in;
144 if (spilt_len >= write_size) {
145 memcpy(uart_ctx[uart_id].rx_ringbuf + uart_ctx[uart_id].rxbuf_in, buf, write_size);
146 } else {
147 memcpy(uart_ctx[uart_id].rx_ringbuf + uart_ctx[uart_id].rxbuf_in, buf, spilt_len);
148 memcpy(uart_ctx[uart_id].rx_ringbuf, buf + spilt_len, write_size - spilt_len);
149 }
150 uart_ctx[uart_id].rxbuf_in = (uart_ctx[uart_id].rxbuf_in + write_size) % uart_ctx[uart_id].rxring_size;
151 }
152
153 return write_size;
154 }
155
156 /*return value is pop out data size */
_uart_ringbuffer_pop(uint32_t uart_id,uint8_t * buf,int32_t len)157 static int32_t _uart_ringbuffer_pop(uint32_t uart_id, uint8_t *buf, int32_t len)
158 {
159 int32_t available_size = 0;
160 int32_t read_size = 0;
161 int32_t spilt_len = 0;
162
163 if (uart_id > HAL_UART_ID_2 || uart_ctx[uart_id].init_flag == 0) {
164 return 0;
165 }
166
167 available_size = _get_uart_ringbuf_available_read_size(uart_id);
168
169 /*get real read_size */
170 if (available_size > len) {
171 read_size = len;
172 } else {
173 read_size = available_size;
174 }
175
176 spilt_len = uart_ctx[uart_id].rxring_size - uart_ctx[uart_id].rxbuf_out;
177 if (spilt_len >= read_size) {
178 memcpy(buf, uart_ctx[uart_id].rx_ringbuf + uart_ctx[uart_id].rxbuf_out, read_size);
179 } else {
180 memcpy(buf, uart_ctx[uart_id].rx_ringbuf + uart_ctx[uart_id].rxbuf_out, spilt_len);
181 memcpy(buf + spilt_len, uart_ctx[uart_id].rx_ringbuf, read_size - spilt_len);
182 }
183
184 uart_ctx[uart_id].rxbuf_out = (uart_ctx[uart_id].rxbuf_out + read_size) % uart_ctx[uart_id].rxring_size;
185
186 return read_size;
187 }
188
189 extern void panicNmiInputFilter(uint8_t ch);
_uart_dma_rx_handler(uint32_t xfer_size,int dma_error,union HAL_UART_IRQ_T status)190 static void _uart_dma_rx_handler(uint32_t xfer_size, int dma_error, union HAL_UART_IRQ_T status)
191 {
192 uint32_t len = 0;
193 uint32_t uartid = 0;
194
195 len = _uart_ringbuffer_push(uartid, uart_ctx[uartid].uart_buffer, xfer_size);
196 if (len < xfer_size) {
197 printf("%s ringbuf is full have %d need %d\r", __FUNCTION__, len, xfer_size);
198 return;
199 }
200
201 memset(uart_ctx[uartid].uart_buffer, 0, UART_DMA_RING_BUFFER_SIZE);
202 krhino_sem_give(&(uart_ctx[uartid].rx_sem));
203 krhino_sem_give(&(uart_ctx[uartid].rx_irq_bottom_sem));
204 hal_uart_rx_start(uartid);
205 }
206
_uart1_dma_rx_handler(uint32_t xfer_size,int dma_error,union HAL_UART_IRQ_T status)207 static void _uart1_dma_rx_handler(uint32_t xfer_size, int dma_error, union HAL_UART_IRQ_T status)
208 {
209 uint32_t len = 0;
210 uint32_t uartid = 1;
211
212 len = _uart_ringbuffer_push(uartid, uart_ctx[uartid].uart_buffer, xfer_size);
213 if (len < xfer_size) {
214 printf("%s ringbuf is full have %d need %d\r", __FUNCTION__, len, xfer_size);
215 return;
216 }
217
218 memset(uart_ctx[uartid].uart_buffer, 0, UART_DMA_RING_BUFFER_SIZE);
219 krhino_sem_give(&(uart_ctx[uartid].rx_sem));
220 krhino_sem_give(&(uart_ctx[uartid].rx_irq_bottom_sem));
221
222 hal_uart_rx_start(uartid);
223
224 }
225
_uart1_dma_tx_handler(uint32_t xfer_size,int dma_error)226 static void _uart1_dma_tx_handler(uint32_t xfer_size, int dma_error)
227 {
228 krhino_sem_give(&(uart_ctx[1].tx_sem));
229 }
230
231 /*uart2*/
_uart2_dma_rx_handler(uint32_t xfer_size,int dma_error,union HAL_UART_IRQ_T status)232 static void _uart2_dma_rx_handler(uint32_t xfer_size, int dma_error, union HAL_UART_IRQ_T status)
233 {
234 uint32_t len = 0;
235 uint32_t uartid = 2;
236
237 len = _uart_ringbuffer_push(uartid, uart_ctx[uartid].uart_buffer, xfer_size);
238 if (len < xfer_size) {
239 printf("%s ringbuf is full have %d need %d\r", __FUNCTION__, len, xfer_size);
240 return;
241 }
242
243 memset(uart_ctx[uartid].uart_buffer, 0, UART_DMA_RING_BUFFER_SIZE);
244
245 krhino_sem_give(&(uart_ctx[uartid].rx_sem));
246 krhino_sem_give(&(uart_ctx[uartid].rx_irq_bottom_sem));
247
248 hal_uart_rx_start(uartid);
249
250 }
251
_uart2_dma_tx_handler(uint32_t xfer_size,int dma_error)252 static void _uart2_dma_tx_handler(uint32_t xfer_size, int dma_error)
253 {
254 krhino_sem_give(&(uart_ctx[2].tx_sem));
255 }
256
rx_irq_bottom(void * arg)257 static void rx_irq_bottom(void *arg)
258 {
259 uart_ctx_obj_t *uart_ctx = arg;
260
261 while (1) {
262 krhino_sem_take(&uart_ctx->rx_irq_bottom_sem, RHINO_WAIT_FOREVER);
263 krhino_mutex_lock(&uart_ctx->rx_cb_mutex, RHINO_WAIT_FOREVER);
264 if (uart_ctx->rx_cb)
265 uart_ctx->rx_cb(uart_ctx->rx_cb_arg);
266 krhino_mutex_unlock(&uart_ctx->rx_cb_mutex);
267 }
268 }
269
270 static int panic_uart_open = 0;
271 extern int32_t g_cli_direct_read;
hal_panic_uart_open(void)272 int32_t hal_panic_uart_open(void)
273 {
274 enum HAL_UART_ID_T uart_id = hal_trace_get_id();
275 TRACE_FLUSH();
276 hal_uart_close(uart_id);
277 low_uart_cfg.baud = hal_trace_get_baudrate();
278 hal_uart_open(uart_id, &low_uart_cfg);
279 panic_uart_open = 1;
280 g_cli_direct_read = 1;
281
282 return 0;
283 }
284 /**
285
286 * Initialises a UART interface
287 *
288 *
289 * @param[in] uart the interface which should be initialised
290 *
291 * @return 0 : on success, EIO : if an error occurred with any step
292 */
hal_uart_init(uart_dev_t * uart)293 int32_t hal_uart_init(uart_dev_t *uart)
294 {
295 int32_t ret = 0;
296 uint32_t trace_port = hal_trace_get_id();
297 enum HAL_UART_ID_T uart_id;
298 struct HAL_UART_CFG_T uart_cfg = {0};
299
300 if(NULL == uart || uart->port > HAL_UART_ID_2) {
301 return EIO;
302 }
303
304 uart_id = uart->port;
305
306 if (uart_ctx[uart_id].init_flag) {
307 /*have already inited*/
308 return EIO;
309 }
310
311 if (uart_id == 0) {
312 uart_ctx[uart_id].uart_dma_rx_handler = _uart_dma_rx_handler;
313 uart_ctx[uart_id].uart_buffer = _hal_uart_buf;
314 }
315 if (uart_id == HAL_UART_ID_1) {
316 uart_ctx[uart_id].uart_dma_rx_handler = _uart1_dma_rx_handler;
317 uart_ctx[uart_id].uart_dma_tx_handler = _uart1_dma_tx_handler;
318 uart_ctx[uart_id].uart_buffer = _hal_uart1_buf;
319 }
320 if (uart_id == HAL_UART_ID_2) {
321 uart_ctx[uart_id].uart_dma_rx_handler = _uart2_dma_rx_handler;
322 uart_ctx[uart_id].uart_dma_tx_handler = _uart2_dma_tx_handler;
323 uart_ctx[uart_id].uart_buffer = _hal_uart2_buf;
324 }
325 memset(uart_ctx[uart_id].uart_buffer, 0, UART_DMA_RING_BUFFER_SIZE);
326
327 uart_cfg.baud = uart->config.baud_rate;
328 uart_cfg.parity = uart->config.parity;
329 uart_cfg.stop = uart->config.stop_bits;
330 uart_cfg.data = uart->config.data_width;
331 uart_cfg.flow = uart->config.flow_control;
332 uart_cfg.tx_level = HAL_UART_FIFO_LEVEL_1_2;
333 uart_cfg.rx_level = HAL_UART_FIFO_LEVEL_1_2;
334 uart_cfg.dma_rx = true;
335 uart_cfg.dma_tx = true;
336 uart_cfg.dma_rx_stop_on_err = false;
337
338 /*means it have already opened*/
339 if (uart_id == trace_port) {
340 hal_uart_close(uart_id);
341 ret = hal_uart_open(uart_id, &uart_cfg);
342 } else {
343 ret = hal_uart_open(uart_id, &uart_cfg);
344 }
345 if (ret) {
346 printf("%s %d trace port %d uart %d open fail ret %d\r\n", __FILE__, __LINE__, trace_port, uart_id, ret);
347 return EIO;
348 }
349 hal_set_uart_iomux(uart_id);
350
351 /*rx fifo buffer, for now fix length 2048*/
352 uart_ctx[uart_id].rx_ringbuf = aos_malloc(UART_FIFO_MAX_BUFFER);
353 if (NULL == uart_ctx[uart_id].rx_ringbuf) {
354 printf("%s %d uart %d fail to malloc rx fifo buffer\r\n", __FILE__, __LINE__, uart_id);
355 return EIO;
356 }
357 uart_ctx[uart_id].rxring_size = UART_FIFO_MAX_BUFFER;
358 uart_ctx[uart_id].rxbuf_in = 0;
359 uart_ctx[uart_id].rxbuf_out = 0;
360 memset(uart_ctx[uart_id].rx_ringbuf, 0, UART_FIFO_MAX_BUFFER);
361
362 ret = krhino_sem_create(&uart_ctx[uart_id].rx_sem, "aos", 0);
363 if (ret != RHINO_SUCCESS) {
364 aos_free(uart_ctx[uart_id].rx_ringbuf);
365 return EIO;
366 }
367
368 ret = krhino_sem_create(&uart_ctx[uart_id].tx_sem, "aos", 0);
369 if (ret != RHINO_SUCCESS) {
370 aos_free(uart_ctx[uart_id].rx_ringbuf);
371 krhino_sem_del(&uart_ctx[uart_id].rx_sem);
372 return EIO;
373 }
374
375 ret = krhino_sem_create(&uart_ctx[uart_id].rx_irq_bottom_sem, "aos", 0);
376 if (ret != RHINO_SUCCESS) {
377 aos_free(uart_ctx[uart_id].rx_ringbuf);
378 krhino_sem_del(&uart_ctx[uart_id].tx_sem);
379 krhino_sem_del(&uart_ctx[uart_id].rx_sem);
380 return EIO;
381 }
382
383 krhino_mutex_create(&uart_ctx[uart_id].rx_cb_mutex, "uart_rx_cb");
384 uart_ctx[uart_id].rx_cb = NULL;
385 uart_ctx[uart_id].rx_cb_arg = NULL;
386 ret = krhino_task_dyn_create(&uart_ctx[uart_id].rx_irq_bottom_task,
387 "uart_rx_irq_bottom", &uart_ctx[uart_id],
388 20, 0, 1024, rx_irq_bottom, 1);
389 if (ret != RHINO_SUCCESS) {
390 aos_free(uart_ctx[uart_id].rx_ringbuf);
391 krhino_sem_del(&uart_ctx[uart_id].tx_sem);
392 krhino_sem_del(&uart_ctx[uart_id].rx_sem);
393 krhino_sem_del(&uart_ctx[uart_id].rx_irq_bottom_sem);
394 krhino_mutex_del(&uart_ctx[uart_id].rx_cb_mutex);
395 return EIO;
396 }
397
398 uart_ctx[uart_id].init_flag = 1;
399
400 hal_uart_irq_set_dma_handler(uart_id, uart_ctx[uart_id].uart_dma_rx_handler,
401 uart_ctx[uart_id].uart_dma_tx_handler, NULL);
402
403 hal_uart_rx_start(uart_id);
404
405 return 0;
406 }
407
408 /**
409
410 * Transmit data on a UART interface
411 *
412
413 * @param[in] uart the UART interface
414
415 * @param[in] data pointer to the start of data
416
417 * @param[in] size number of bytes to transmit
418
419 * @param[in] timeout timeout in milisecond, set this value to HAL_WAIT_FOREVER
420
421 * if you want to wait forever
422 *
423
424 * @return 0 : on success, EIO : if an error occurred with any step
425 */
hal_uart_send(uart_dev_t * uart,const void * data,uint32_t size,uint32_t timeout)426 int32_t hal_uart_send(uart_dev_t *uart, const void *data, uint32_t size, uint32_t timeout)
427 {
428 int32_t ret = EIO;
429 uint8_t uart_id;
430
431 if (NULL == uart || NULL == data || 0 == size) {
432 printf("%s %d Invalid input \r\n", __FILE__, __LINE__);
433 return ret;
434 }
435
436 uart_id = uart->port;
437
438 if (uart_id > HAL_UART_ID_2) {
439 printf("%s %d Invalid input \r\n", __FILE__, __LINE__);
440 return ret;
441 }
442
443 if (uart_ctx[uart_id].init_flag == 0) {
444 printf("%s %d uart %d haven't init yet \r\n", __FILE__, __LINE__, uart_id);
445 return ret;
446 }
447
448 if (uart_id == hal_trace_get_id()) {
449 if (panic_uart_open) {
450 for (int i = 0; i < size; i++)
451 hal_uart_blocked_putc(uart_id, *((char *)data + i));
452 } else {
453 hal_trace_output_block(data, size);
454 }
455 } else {
456 hal_uart_dma_send_sync_cache(uart_id, data, size, NULL, NULL);
457 krhino_sem_take(&uart_ctx[uart_id].tx_sem, krhino_ms_to_ticks(timeout));
458 }
459
460 return 0;
461 }
462
463 /**
464
465 * Receive data on a UART interface
466 *
467 * @param[in] uart the UART interface
468 * @param[out] data pointer to the buffer which will store incoming data
469 * @param[in] expect_size number of bytes to receive
470 * @param[in] timeout timeout in milisecond, set this value to HAL_WAIT_FOREVER
471 * if you want to wait forever
472 *
473 * @return 0 : on success, EIO : if an error occurred with any step
474 */
hal_uart_recv(uart_dev_t * uart,void * data,uint32_t expect_size,uint32_t timeout)475 int32_t hal_uart_recv(uart_dev_t *uart, void *data, uint32_t expect_size, uint32_t timeout)
476 {
477 printf("%s %d is a stub function \r\n", __FILE__, __LINE__);
478 return EIO;
479 }
480
481 /**
482
483 * Receive data on a UART interface
484 *
485
486 * @param[in] uart the UART interface
487
488 * @param[out] data pointer to the buffer which will store incoming data
489
490 * @param[in] expect_size number of bytes to receive
491
492 * @param[out] recv_size number of bytes received
493
494 * @param[in] timeout timeout in milisecond, set this value to HAL_WAIT_FOREVER
495
496 * if you want to wait forever
497 *
498
499 * @return 0 : on success, EIO : if an error occurred with any step
500 */
hal_uart_recv_II(uart_dev_t * uart,void * data,uint32_t expect_size,uint32_t * recv_size,uint32_t timeout)501 int32_t hal_uart_recv_II(uart_dev_t *uart, void *data, uint32_t expect_size,
502 uint32_t *recv_size, uint32_t timeout)
503 {
504 int32_t ret = EIO;
505 uint8_t uart_id = 0;
506 tick_t begin_time =0;
507 tick_t now_time = 0;
508 uint32_t fifo_pop_len = 0;
509 uint32_t recved_len = 0;
510 uint32_t expect_len = expect_size;
511
512 if (NULL == uart || NULL == data || expect_size == 0) {
513 printf("%s %d Invalid input \r\n", __FILE__, __LINE__);
514 return ret;
515 }
516
517 uart_id = uart->port;
518
519 if (uart_id > HAL_UART_ID_2) {
520 printf("%s %d Invalid input \r\n", __FILE__, __LINE__);
521 return ret;
522 }
523
524 if (uart_ctx[uart_id].init_flag == 0) {
525 printf("%s %d uart %d haven't init yet \r\n", __FILE__, __LINE__, uart_id);
526 return ret;
527 }
528
529 begin_time = krhino_sys_tick_get();
530 do
531 {
532 fifo_pop_len = _uart_ringbuffer_pop(uart_id, (uint8_t *)data + recved_len, expect_len);
533 recved_len += fifo_pop_len;
534 expect_len -= fifo_pop_len;
535
536 if (recved_len >= expect_size) {
537 break;
538 }
539
540 /*if reaches here, it means need to wait for more data come*/
541 krhino_sem_take(&uart_ctx[uart_id].rx_sem, krhino_ms_to_ticks(timeout));
542 /*time out break*/
543 now_time = krhino_sys_tick_get();
544 if((uint32_t)(now_time - begin_time) >= timeout){
545 break;
546 }
547
548 } while (1);
549
550 /*haven't get any data from fifo */
551 if (recved_len == 0) {
552 return EIO;
553 }
554
555 if (recv_size != NULL) {
556 *recv_size = recved_len;
557 }
558
559 return 0;
560 }
561
562 /**
563
564 * release sem for uart rx port
565 *
566
567 * @param[in] uartid index of uart
568 *
569
570 * @return 0 : on success, Others : if an error occurred with any step
571 */
hal_uart_rx_sem_give(int uartid)572 kstat_t hal_uart_rx_sem_give(int uartid)
573 {
574 return krhino_sem_give(&(uart_ctx[uartid].rx_sem));
575 }
576
577 /**
578
579 * take sem for uart rx port
580 *
581
582 * @param[in] uartid index of uart
583
584 * @param[in] timeout timeout in milisecond, set this value to HAL_WAIT_FOREVER
585
586 * if you want to wait forever
587 *
588
589 * @return 0 : on success, Others : if an error occurred with any step
590 */
hal_uart_rx_sem_take(int uartid,int timeout)591 kstat_t hal_uart_rx_sem_take(int uartid, int timeout)
592 {
593 return krhino_sem_take(&uart_ctx[uartid].rx_sem, krhino_ms_to_ticks(timeout));
594 }
595
596 /**
597
598 * Deinitialises a UART interface
599 *
600
601 * @param[in] uart the interface which should be deinitialised
602 *
603
604 * @return 0 : on success, EIO : if an error occurred with any step
605 */
hal_uart_finalize(uart_dev_t * uart)606 int32_t hal_uart_finalize(uart_dev_t *uart)
607 {
608 int32_t ret = EIO;
609 uint8_t uart_id;
610
611 if (NULL == uart) {
612 printf("%s %d Invalid input \r\n", __FILE__, __LINE__);
613 return ret;
614 }
615
616 uart_id = uart->port;
617
618 if (uart_id > HAL_UART_ID_2) {
619 printf("%s %d Invalid input \r\n", __FILE__, __LINE__);
620 return ret;
621 }
622
623 if (uart_ctx[uart_id].init_flag == 0) {
624 return 0;
625 }
626
627 if (uart_id == hal_trace_get_id()) {
628 //hal_uart_close(uart->port);
629 printf("do nothings since we need uart!\n");
630 return 0;
631 }
632
633 hal_uart_close(uart->port);
634 aos_free(uart_ctx[uart_id].rx_ringbuf);
635 krhino_sem_del(&uart_ctx[uart_id].rx_sem);
636 krhino_sem_del(&uart_ctx[uart_id].tx_sem);
637 krhino_task_dyn_del(uart_ctx[uart_id].rx_irq_bottom_task);
638 uart_ctx[uart_id].rx_irq_bottom_task = NULL;
639 krhino_sem_del(&uart_ctx[uart_id].rx_irq_bottom_sem);
640 krhino_mutex_del(&uart_ctx[uart_id].rx_cb_mutex);
641 uart_ctx[uart_id].rx_cb = NULL;
642 uart_ctx[uart_id].rx_cb_arg = NULL;
643 memset(&uart_ctx[uart_id], 0, sizeof(uart_ctx_obj_t));
644
645 ret = 0;
646
647 return ret;
648 }
649
hal_uart_recv_cb_reg(uart_dev_t * uart,uart_rx_cb cb)650 int32_t hal_uart_recv_cb_reg(uart_dev_t *uart, uart_rx_cb cb)
651 {
652 int id;
653
654 if (!uart || uart->port > HAL_UART_ID_2)
655 return -1;
656
657 id = uart->port;
658 krhino_mutex_lock(&uart_ctx[id].rx_cb_mutex, RHINO_WAIT_FOREVER);
659 uart_ctx[id].rx_cb = cb;
660 uart_ctx[id].rx_cb_arg = cb ? uart : NULL;
661 krhino_mutex_unlock(&uart_ctx[id].rx_cb_mutex);
662
663 return 0;
664 }
665