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