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