1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 */
4
5 #include <stdint.h>
6 #include <errno.h>
7 #include <execinfo.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <sys/select.h>
11 #include <termios.h>
12 #include <unistd.h>
13 #include <semaphore.h>
14 #include <pthread.h>
15 #include <signal.h>
16 #include <sys/time.h>
17 #include <time.h>
18
19 #include "aos_hal_uart.h"
20
aos_hal_uart_callback(uart_dev_t * uart,void (* cb)(int,void *,uint16_t,void *),void * args)21 int32_t aos_hal_uart_callback(uart_dev_t *uart, void (*cb)(int, void *, uint16_t, void *), void *args)
22 {
23 return 0;
24 }
25
26 typedef unsigned char UINT8; /* Unsigned 8 bit quantity */
27 typedef signed char INT8; /* Signed 8 bit quantity */
28 typedef unsigned short UINT16; /* Unsigned 16 bit quantity */
29 typedef signed short INT16; /* Signed 16 bit quantity */
30 typedef uint32_t UINT32; /* Unsigned 32 bit quantity */
31 typedef int32_t INT32; /* Signed 32 bit quantity */
32
33 static struct termios term_orig;
34
35 #define MAX_UART_NUM 1
36
37 enum _uart_status_e {
38 _UART_STATUS_CLOSED = 0,
39 _UART_STATUS_OPENED,
40 };
41
42 typedef struct {
43 uint8_t uart;
44 uint8_t status;
45 pthread_t threaid;
46 pthread_mutex_t mutex;
47 } _uart_drv_t;
48
49 static _uart_drv_t _uart_drv[MAX_UART_NUM];
50
51 extern int32_t uart_read_byte(uint8_t *rx_byte);
52 extern void uart_write_byte(uint8_t byte);
53 extern uint8_t uart_is_tx_fifo_empty(void);
54 extern uint8_t uart_is_tx_fifo_full(void);
55 extern void uart_set_tx_stop_end_int(uint8_t set);
56
exit_cleanup(void)57 static void exit_cleanup(void)
58 {
59 tcsetattr(0, TCSANOW, &term_orig);
60 }
61
aos_hal_uart_init(uart_dev_t * uart)62 int32_t aos_hal_uart_init(uart_dev_t *uart)
63 {
64 setvbuf(stdout, NULL, _IONBF, 0);
65 int err_num;
66 _uart_drv_t *pdrv = &_uart_drv[0];
67 struct termios term_vi;
68
69 if (pdrv->status == _UART_STATUS_CLOSED) {
70 pdrv->status = _UART_STATUS_OPENED;
71 tcgetattr(0, &term_orig);
72 term_vi = term_orig;
73 term_vi.c_lflag &= (~ICANON & ~ECHO); // leave ISIG ON- allow intr's
74 term_vi.c_iflag &= (~IXON & ~ICRNL);
75 tcsetattr(0, TCSANOW, &term_vi);
76 atexit(exit_cleanup);
77
78 err_num = pthread_mutex_init(&pdrv->mutex, NULL);
79 if (0 != err_num) {
80 perror("create mutex failed\n");
81 return -1;
82 }
83 } else {
84 return -1;
85 }
86 return 0;
87 }
88
aos_hal_uart_finalize(uart_dev_t * uart)89 int32_t aos_hal_uart_finalize(uart_dev_t *uart)
90 {
91 _uart_drv_t *pdrv = &_uart_drv[uart->port];
92
93 pthread_mutex_destroy(&pdrv->mutex);
94 pdrv->status = _UART_STATUS_CLOSED;
95 tcsetattr(0, TCSANOW, &term_orig);
96 return 0;
97 }
98
aos_hal_uart_send(uart_dev_t * uart,const void * data,uint32_t size,uint32_t timeout)99 int32_t aos_hal_uart_send(uart_dev_t *uart, const void *data, uint32_t size, uint32_t timeout)
100 {
101 uint32_t i = 0;
102 _uart_drv_t *pdrv = &_uart_drv[uart->port];
103
104 pthread_mutex_lock(&pdrv->mutex);
105
106 for (i = 0; i < size; i++) {
107 putchar(((uint8_t *)data)[i]);
108 }
109
110 pthread_mutex_unlock(&pdrv->mutex);
111
112 return 0;
113 }
114
115 int aaa = 0;
aos_hal_uart_recv_poll(uart_dev_t * uart,void * data,uint32_t expect_size,uint32_t * recv_size)116 int32_t aos_hal_uart_recv_poll(uart_dev_t *uart, void *data, uint32_t expect_size, uint32_t *recv_size)
117 {
118 fd_set fdset;
119 int ret;
120 char nbuf;
121 char *read_buf = data;
122 (void *)uart;
123
124 if (data == NULL || recv_size == NULL) {
125 return -1;
126 }
127 *recv_size = 0;
128
129 /* Obtain the size of the packet and put it into the "len"
130 variable. */
131 int readlen = read(0, &nbuf, 1);
132 if (readlen > 0) {
133 *(char *)data = nbuf;
134 *recv_size = 1;
135 return 0;
136 }
137
138 return -1;
139 }
140
aos_hal_uart_recv_II(uart_dev_t * uart,void * data,uint32_t expect_size,uint32_t * recv_size,uint32_t timeout)141 int32_t aos_hal_uart_recv_II(uart_dev_t *uart, void *data, uint32_t expect_size, uint32_t *recv_size, uint32_t timeout)
142 {
143 fd_set fdset;
144 int ret;
145 char nbuf;
146 char *read_buf = data;
147 struct timeval st;
148 time_t t_begin, t_now;
149
150 (void *)uart;
151
152 t_begin = clock();
153
154 if (data == NULL || recv_size == NULL) {
155 return -1;
156 }
157 *recv_size = 0;
158
159 while (1) {
160 t_now = clock();
161 if (difftime(t_now, t_begin) > timeout) {
162 break;
163 }
164 usleep(10);
165 FD_ZERO(&fdset);
166 FD_SET(0, &fdset);
167
168 /* Wait for a packet to arrive. */
169 st.tv_sec = 0;
170 st.tv_usec = 100;
171 ret = select(1, &fdset, NULL, NULL, &st);
172 if (ret == 1) {
173 /* Obtain the size of the packet and put it into the "len"
174 variable. */
175 int readlen = read(0, &nbuf, 1);
176 if (readlen < 0) {
177 perror("cli read eror");
178 continue;
179 }
180
181 /* Handle incoming packet. */
182 read_buf[*recv_size] = nbuf;
183 *recv_size += 1;
184 if (*recv_size >= expect_size) {
185 break;
186 }
187 }
188 }
189 return 0;
190 }
191