1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 */
4
5 #include <stdio.h>
6 #include <unistd.h>
7 #include <limits.h>
8 #include <poll.h>
9 #ifndef AOS_BOARD_HAAS700
10 #include <vfsdev/uart_dev.h>
11 #endif
12 #include "aos/hal/uart.h"
13 #include "aos/kernel.h"
14 #include "aos_hal_uart.h"
15
16 #ifdef CONFIG_UART_NUM
17 #define PLATFORM_UART_NUM CONFIG_UART_NUM
18 #else
19 #define PLATFORM_UART_NUM 4
20 #endif
21
22 static int uart_fd_table[PLATFORM_UART_NUM];
23
aos_hal_uart_init(uart_dev_t * uart)24 int32_t aos_hal_uart_init(uart_dev_t *uart)
25 {
26 return hal_uart_init(uart);
27 }
28
aos_hal_uart_send(uart_dev_t * uart,const void * data,uint32_t size,uint32_t timeout)29 int32_t aos_hal_uart_send(uart_dev_t *uart, const void *data, uint32_t size, uint32_t timeout)
30 {
31 return hal_uart_send(uart, data, size, timeout);
32 }
33
aos_hal_uart_recv(uart_dev_t * uart,void * data,uint32_t expect_size,uint32_t timeout)34 int32_t aos_hal_uart_recv(uart_dev_t *uart, void *data,
35 uint32_t expect_size, uint32_t timeout)
36 {
37 /* deprecated */
38 return -1;
39 }
40
aos_hal_uart_recv_poll(uart_dev_t * uart,void * data,uint32_t expect_size,uint32_t * recv_size)41 int32_t aos_hal_uart_recv_poll(uart_dev_t *uart, void *data, uint32_t expect_size, uint32_t *recv_size)
42 {
43 return hal_uart_recv_II(uart, data, expect_size, recv_size, 0);
44 }
45
aos_hal_uart_recv_II(uart_dev_t * uart,void * data,uint32_t expect_size,uint32_t * recv_size,uint32_t timeout)46 int32_t aos_hal_uart_recv_II(uart_dev_t *uart, void *data, uint32_t expect_size,
47 uint32_t *recv_size, uint32_t timeout)
48 {
49 return hal_uart_recv_II(uart, data, expect_size, recv_size, timeout);
50 }
51
aos_hal_uart_rx_sem_take(int uartid,int timeout)52 int aos_hal_uart_rx_sem_take(int uartid, int timeout)
53 {
54 #ifndef AOS_BOARD_HAAS700
55 return hal_uart_rx_sem_take(uartid, timeout);
56 #else
57 return -1;
58 #endif
59 }
60
aos_hal_uart_rx_sem_give(int port)61 int aos_hal_uart_rx_sem_give(int port)
62 {
63 #ifndef AOS_BOARD_HAAS700
64 return hal_uart_rx_sem_give(port);
65 #else
66 return -1;
67 #endif
68 }
69
70 typedef struct {
71 void (*callback)(int, void *, uint16_t, void *);
72 void *userdata;
73 uart_dev_t *uart;
74 int task_running;
75 int stop;
76 aos_mutex_t lock;
77 aos_sem_t sem;
78 aos_task_t task;
79 } uart_recv_notify_t;
80
81 static uart_recv_notify_t *uart_recv_notifiers[PLATFORM_UART_NUM];
82
uart_recv_handler(void * args)83 static void uart_recv_handler(void *args)
84 {
85 uart_recv_notify_t *notify = (uart_recv_notify_t *)args;
86 uart_dev_t *uart;
87 char recv_buffer[256];
88 uint32_t recv_size;
89 int ret;
90
91 if (!notify)
92 return;
93
94 uart = notify->uart;
95 while (1) {
96 aos_mutex_lock(¬ify->lock, AOS_WAIT_FOREVER);
97 if (notify->stop) {
98 aos_mutex_unlock(¬ify->lock);
99 break;
100 }
101 aos_mutex_unlock(¬ify->lock);
102
103 ret = aos_hal_uart_recv_II(uart, recv_buffer, sizeof(recv_buffer),
104 &recv_size, 100);
105 if (ret || recv_size <= 0)
106 continue;
107 if (notify->callback)
108 notify->callback(uart->port, recv_buffer, recv_size, notify->userdata);
109 }
110
111 aos_sem_signal(¬ify->sem);
112 }
113
114 #if 0
115 extern int32_t hal_uart_receive_register(int port, void(*cb)(int, void *), void *args);
116 static int uart_port_registered[7];
117 #endif
118
aos_hal_uart_callback(uart_dev_t * uart,void (* cb)(int,void *,uint16_t,void *),void * args)119 int32_t aos_hal_uart_callback(uart_dev_t *uart, void (*cb)(int, void *, uint16_t, void *), void *args)
120 {
121 #if 0
122 if (uart_port_registered[uart->port])
123 return 0;
124 hal_uart_receive_register(uart, cb, args);
125 uart_port_registered[uart->port] = 1;
126 #else
127 uart_recv_notify_t *notify = uart_recv_notifiers[uart->port];
128
129 if (!notify) {
130 notify = aos_malloc(sizeof(uart_recv_notify_t));
131 if (!notify)
132 return -1;
133 memset(notify, 0, sizeof(uart_recv_notify_t));
134 aos_mutex_new(¬ify->lock);
135 aos_sem_new(¬ify->sem, 0);
136 uart_recv_notifiers[uart->port] = notify;
137 }
138
139 notify->callback = cb;
140 notify->userdata = args;
141 notify->uart = uart;
142
143 if (!notify->task_running) {
144 if (aos_task_new_ext(¬ify->task, "amp_uart_recv",
145 uart_recv_handler, notify, 2048, 32))
146 return -1;
147 notify->task_running = 1;
148 }
149 #endif
150 return 0;
151 }
152
aos_hal_uart_finalize(uart_dev_t * uart)153 int32_t aos_hal_uart_finalize(uart_dev_t *uart)
154 {
155 uart_recv_notify_t *notify = uart_recv_notifiers[uart->port];
156 if (notify) {
157 if (notify->task_running) {
158 aos_mutex_lock(¬ify->lock, AOS_WAIT_FOREVER);
159 notify->stop = 1;
160 aos_mutex_unlock(¬ify->lock);
161 aos_sem_wait(¬ify->sem, 3000);
162 }
163 aos_mutex_free(¬ify->lock);
164 aos_sem_free(¬ify->sem);
165 aos_free(notify);
166 uart_recv_notifiers[uart->port] = NULL;
167 }
168
169 //close(uart_fd_table[uart->port]);
170 hal_uart_finalize(uart);
171 uart_fd_table[uart->port] = -1;
172
173 return 0;
174 }
175