blob: d706aaee74f729dbd35541864e1a1b2cd6ce752d [file] [log] [blame]
b.liu68a94c92025-05-24 12:53:41 +08001#include <stdio.h>
2#include <stdlib.h>
3#include <fcntl.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6#include <string.h>
7#include <errno.h>
8#include <termios.h>
9#include <unistd.h>
10#include <stdint.h>
11#include <sys/ioctl.h>
12#include <dlfcn.h>
13
hong.liucd370792025-05-28 06:29:19 -070014#include "gsw_uart_interface.h"
b.liu68a94c92025-05-24 12:53:41 +080015
hong.liud2417072025-06-27 07:10:37 -070016#define MODEM_CONNECT_MCU_PORT "/dev/ttyS1"
17
zw.wangbd342b92025-07-21 11:24:16 +080018#include "gsw_log_interface.h"
l.yang6a42e4d2025-05-28 01:04:20 -070019#define GSW_UART "[HAL][GSW_UART]"
20
21
hong.liucd370792025-05-28 06:29:19 -070022typedef enum
23{
24 GSW_HAL_BAUDRATE_1200=1200,
25 GSW_HAL_BAUDRATE_1800=1800,
26 GSW_HAL_BAUDRATE_4800=4800,
27 GSW_HAL_BAUDRATE_9600=9600,
28 GSW_HAL_BAUDRATE_19200=19200,
29 GSW_HAL_BAUDRATE_38400=38400,
30 GSW_HAL_BAUDRATE_57600=57600,
31 GSW_HAL_BAUDRATE_115200=115200,
32 GSW_HAL_BAUDRATE_230400=230400,
33 GSW_HAL_BAUDRATE_460800=460800,
34 GSW_HAL_BAUDRATE_500000=500000,
35 GSW_HAL_BAUDRATE_576000=576000,
36 GSW_HAL_BAUDRATE_921600=921600
37}gsw_hal_uart_baudrate;
38
zw.wangbd342b92025-07-21 11:24:16 +080039static inline int handle()
b.liu68a94c92025-05-24 12:53:41 +080040{
b.liu68a94c92025-05-24 12:53:41 +080041 return GSW_HAL_SUCCESS;
42}
43
b.liu68a94c92025-05-24 12:53:41 +080044int32_t gsw_uart_open_ex(int8_t *port, gsw_hal_uart_baudrate baudrate, uint32_t bits, int8_t parity, uint32_t stop)
45{
46 if (handle())
hong.liucd370792025-05-28 06:29:19 -070047 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +080048 int fd = -1;
49 if((fd = open((const char *)port, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0)
50 {
zw.wangbd342b92025-07-21 11:24:16 +080051 LOGE(GSW_UART,"open %s failed - %d", port, errno);
b.liu68a94c92025-05-24 12:53:41 +080052 return -1;
53 }
zw.wangbd342b92025-07-21 11:24:16 +080054 LOGD(GSW_UART,"Open %s success.", port);
b.liu68a94c92025-05-24 12:53:41 +080055
56 /* set newtio */
57 struct termios newtio;
58 memset(&newtio, 0, sizeof(newtio));
59 if (tcflush(fd, TCIOFLUSH) < 0) {
zw.wangbd342b92025-07-21 11:24:16 +080060 LOGE(GSW_UART,"Could not flush uart port");
b.liu68a94c92025-05-24 12:53:41 +080061 return -1;
62 }
63
64 newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
65 newtio.c_cc[VMIN] = 0; /* blocking read until 5 chars received */
66
67 /* c_iflag 输入模式 */
68 newtio.c_iflag &= ~(ICRNL | INLCR);
69 newtio.c_iflag &= ~(IXON | IXOFF | IXANY);
70
71 // /* c_lflag 本地模式 */
72 newtio.c_cflag &= ~ INPCK;
73 newtio.c_cflag |= (CLOCAL | CREAD);
74
75 // /* c_lflag 本地模式 */
76 newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
77 /* c_oflag 输出模式 */
78 newtio.c_oflag &= ~ OPOST;
79 newtio.c_oflag &= ~(ONLCR | OCRNL);
80
81 /* c_cflag 控制模式 */
82 newtio.c_cflag &= ~ CSIZE;
83 newtio.c_cflag |= CS8;
84 newtio.c_cflag &= ~ CSTOPB;
85 newtio.c_cflag &= ~ PARENB;
86
87
88 switch(baudrate)
89 {
90 case GSW_HAL_BAUDRATE_1200:
91 cfsetospeed(&newtio, B1200);
92 cfsetispeed(&newtio, B1200);
93 break;
94 case GSW_HAL_BAUDRATE_1800:
95 cfsetospeed(&newtio, B1800);
96 cfsetispeed(&newtio, B1800);
97 break;
98 case GSW_HAL_BAUDRATE_4800:
99 cfsetospeed(&newtio, B4800);
100 cfsetispeed(&newtio, B4800);
101 break;
102 case GSW_HAL_BAUDRATE_9600:
103 cfsetospeed(&newtio, B9600);
104 cfsetispeed(&newtio, B9600);
105 break;
106 case GSW_HAL_BAUDRATE_19200:
107 cfsetospeed(&newtio, B19200);
108 cfsetispeed(&newtio, B19200);
109 break;
110 case GSW_HAL_BAUDRATE_38400:
111 cfsetospeed(&newtio, B38400);
112 cfsetispeed(&newtio, B38400);
113 break;
114 case GSW_HAL_BAUDRATE_57600:
115 cfsetospeed(&newtio, B57600);
116 cfsetispeed(&newtio, B57600);
117 break;
118 case GSW_HAL_BAUDRATE_115200:
119 cfsetospeed(&newtio, B115200);
120 cfsetispeed(&newtio, B115200);
121 break;
122 case GSW_HAL_BAUDRATE_230400:
123 cfsetospeed(&newtio, B230400);
124 cfsetispeed(&newtio, B230400);
125 break;
126 case GSW_HAL_BAUDRATE_460800:
127 cfsetospeed(&newtio, B460800);
128 cfsetispeed(&newtio, B460800);
129 break;
130 case GSW_HAL_BAUDRATE_500000:
131 cfsetospeed(&newtio, B500000);
132 cfsetispeed(&newtio, B500000);
133 break;
134 case GSW_HAL_BAUDRATE_576000:
135 cfsetospeed(&newtio, B576000);
136 cfsetispeed(&newtio, B576000);
137 break;
138 case GSW_HAL_BAUDRATE_921600:
139 cfsetospeed(&newtio, B921600);
140 cfsetispeed(&newtio, B921600);
141 break;
142 default:
143 cfsetospeed(&newtio, B115200);
144 cfsetispeed(&newtio, B115200);
145 break;
146 }
147
148 switch(bits)
149 {
hong.liucd370792025-05-28 06:29:19 -0700150 case 5:
b.liu68a94c92025-05-24 12:53:41 +0800151 newtio.c_cflag &= ~CSIZE;
152 newtio.c_cflag |= CS5;
153 break;
hong.liucd370792025-05-28 06:29:19 -0700154 case 6:
b.liu68a94c92025-05-24 12:53:41 +0800155 newtio.c_cflag &= ~CSIZE;
156 newtio.c_cflag |= CS6;
157 break;
hong.liucd370792025-05-28 06:29:19 -0700158 case 7:
b.liu68a94c92025-05-24 12:53:41 +0800159 newtio.c_cflag &= ~CSIZE;
160 newtio.c_cflag |= CS7;
161 break;
hong.liucd370792025-05-28 06:29:19 -0700162 case 8:
b.liu68a94c92025-05-24 12:53:41 +0800163 newtio.c_cflag &= ~CSIZE;
164 newtio.c_cflag |= CS8;
165 break;
166 default:
zw.wangbd342b92025-07-21 11:24:16 +0800167 LOGD(GSW_UART,"No set databit.");
b.liu68a94c92025-05-24 12:53:41 +0800168 break;
169 }
170
171 if(stop == 2) {
172 newtio.c_cflag |= CSTOPB;
173 } else {
174 newtio.c_cflag &= ~CSTOPB;
175 }
176
177 switch (parity)
178 {
hong.liucd370792025-05-28 06:29:19 -0700179 case 'O':
180 case 'o':// 奇校验
b.liu68a94c92025-05-24 12:53:41 +0800181 newtio.c_cflag |= PARENB;
182 newtio.c_cflag |= PARODD;
183 break;
hong.liucd370792025-05-28 06:29:19 -0700184 case 'E':
185 case 'e':// 偶校验
b.liu68a94c92025-05-24 12:53:41 +0800186 newtio.c_cflag |= PARENB;
187 newtio.c_cflag &= ~PARODD;
188 break;
hong.liucd370792025-05-28 06:29:19 -0700189 case 'N':
190 case 'n':// 无奇偶校验
b.liu68a94c92025-05-24 12:53:41 +0800191 newtio.c_cflag &= ~PARENB;
192 break;
193 default:
zw.wangbd342b92025-07-21 11:24:16 +0800194 LOGD(GSW_UART,"No set parity.");
b.liu68a94c92025-05-24 12:53:41 +0800195 break;
196 }
197
198 if (tcsetattr(fd, TCSANOW, &newtio) < 0) {
zw.wangbd342b92025-07-21 11:24:16 +0800199 LOGE(GSW_UART,"Can't set port setting");
b.liu68a94c92025-05-24 12:53:41 +0800200 return -1;
201 }
202
203 return fd;
204}
205
hong.liud2417072025-06-27 07:10:37 -0700206void gsw_uart_flush(int32_t fd)
b.liu68a94c92025-05-24 12:53:41 +0800207{
zw.wang10b141c2025-06-19 11:18:30 +0800208 if (handle())
209 return;
b.liu68a94c92025-05-24 12:53:41 +0800210 if (tcflush(fd, TCIOFLUSH) < 0)
211 {
zw.wangbd342b92025-07-21 11:24:16 +0800212 LOGE(GSW_UART,"flush fail\n");
hong.liucd370792025-05-28 06:29:19 -0700213 //return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800214 }
hong.liucd370792025-05-28 06:29:19 -0700215 else
zw.wangbd342b92025-07-21 11:24:16 +0800216 LOGD(GSW_UART,"flush success\n");
hong.liucd370792025-05-28 06:29:19 -0700217 //return GSW_HAL_SUCCESS;
b.liu68a94c92025-05-24 12:53:41 +0800218}
219
hong.liucd370792025-05-28 06:29:19 -0700220int gsw_uart_read(int fd, unsigned char *buffer, int len, int timeout_ms)
b.liu68a94c92025-05-24 12:53:41 +0800221{
222 if (handle())
hong.liucd370792025-05-28 06:29:19 -0700223 return GSW_HAL_NORMAL_FAIL;
224 if(len <= 0 || timeout_ms < -1)
225 {
zw.wangbd342b92025-07-21 11:24:16 +0800226 LOGE(GSW_UART,"timeout_ms = %d, len = %d; timeout_ms needs to be greater than -1 and len needs to be greater than 0!\n",timeout_ms, len);
hong.liucd370792025-05-28 06:29:19 -0700227 return GSW_HAL_NORMAL_FAIL;
228 }
b.liu68a94c92025-05-24 12:53:41 +0800229 int flags = fcntl(fd, F_GETFL); // 获取当前状态标志
230 if (flags == -1)
231 {
232 perror("fcntl get");
hong.liucd370792025-05-28 06:29:19 -0700233 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800234 }
235
236 struct termios newtio;
237 if (tcgetattr(fd, &newtio) < 0) {
238 perror("tcgetattr failed");
239 return -1;
240 }
241 if (timeout_ms == 0)
242 {
243 flags |= O_NONBLOCK; // 设置非阻塞标志
244 fcntl(fd, F_SETFL, flags);
245 newtio.c_cc[VMIN] = 0;
246 newtio.c_cc[VTIME] = 0;
247 }
hong.liucd370792025-05-28 06:29:19 -0700248 else if (timeout_ms == -1)
b.liu68a94c92025-05-24 12:53:41 +0800249 {
250 flags &= ~O_NONBLOCK; // 清除非阻塞标志
251 fcntl(fd, F_SETFL, flags);
252 newtio.c_cc[VMIN] = 1;
hong.liucd370792025-05-28 06:29:19 -0700253 newtio.c_cc[VTIME] = 0;
b.liu68a94c92025-05-24 12:53:41 +0800254 }
255 else
256 {
257 flags &= ~O_NONBLOCK; // 清除非阻塞标志
258 fcntl(fd, F_SETFL, flags);
259 newtio.c_cc[VMIN] = 0;
260 newtio.c_cc[VTIME] = timeout_ms/100;
261 }
262 if(timeout_ms != 0)
zw.wangbd342b92025-07-21 11:24:16 +0800263 LOGI(GSW_UART,"%s :VMIN = %d ;VTIME = %d\n",__func__,newtio.c_cc[VMIN],newtio.c_cc[VTIME]);
b.liu68a94c92025-05-24 12:53:41 +0800264 if (tcsetattr(fd, TCSANOW, &newtio) != 0)
265 {
266 perror("tcsetattr");
267 return -1;
268 }
269 //gsw_uart_flush(fd);
270 int data_len = read(fd, buffer, len);
271 if (data_len < 0)
272 {
273 if(errno == EAGAIN || errno == EWOULDBLOCK)
274 return 0;
275 else
hong.liucd370792025-05-28 06:29:19 -0700276 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800277 }
278 return data_len;
279}
280
281
hong.liucd370792025-05-28 06:29:19 -0700282int gsw_uart_write(int fd, const unsigned char *buffer, int len)
b.liu68a94c92025-05-24 12:53:41 +0800283{
284 //gsw_uart_flush(fd);
285 if (write(fd, buffer, len) < 0)
286 {
hong.liucd370792025-05-28 06:29:19 -0700287 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800288 }
289 return GSW_HAL_SUCCESS;
290}
291
292int32_t gsw_uart_ioctl(int32_t fd, uint32_t cmd, void *pvalue)
293{
294 if (handle())
hong.liucd370792025-05-28 06:29:19 -0700295 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800296 if (fd < 0 || pvalue == NULL)
297 {
zw.wangbd342b92025-07-21 11:24:16 +0800298 LOGE(GSW_UART,"Invalid file descriptor");
hong.liucd370792025-05-28 06:29:19 -0700299 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800300 }
301 if (ioctl(fd, cmd, pvalue) < 0)
302 {
zw.wangbd342b92025-07-21 11:24:16 +0800303 LOGE(GSW_UART,"Could not set DCB,error:%d, %s\n",errno, strerror(errno));
hong.liucd370792025-05-28 06:29:19 -0700304 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800305 }
306 return GSW_HAL_SUCCESS;
307}
308
hong.liucd370792025-05-28 06:29:19 -0700309void gsw_uart_close(int fd)
b.liu68a94c92025-05-24 12:53:41 +0800310{
zw.wang10b141c2025-06-19 11:18:30 +0800311 if (handle())
312 return;
b.liu68a94c92025-05-24 12:53:41 +0800313 if (fd <= 0)
zw.wangbd342b92025-07-21 11:24:16 +0800314 LOGE(GSW_UART,"fd = %d fail\n",fd);
hong.liucd370792025-05-28 06:29:19 -0700315 //return GSW_HAL_NORMAL_FAIL;
316 else
317 {
318 //gsw_uart_flush(fd);
319 int ret = close(fd);
320 if(ret < 0)
321 {
zw.wangbd342b92025-07-21 11:24:16 +0800322 LOGE(GSW_UART,"close fail ret = %d\n",ret);
hong.liucd370792025-05-28 06:29:19 -0700323 }
324 else
325 {
zw.wangbd342b92025-07-21 11:24:16 +0800326 LOGI(GSW_UART,"close success ret = %d\n",ret);
hong.liucd370792025-05-28 06:29:19 -0700327 }
328 }
329
330 //return GSW_HAL_SUCCESS;
b.liu68a94c92025-05-24 12:53:41 +0800331}
332
hong.liud2417072025-06-27 07:10:37 -0700333int gsw_uart_open(unsigned int baudrate, unsigned int bits, char parity, unsigned int stop)
334{
335 return gsw_uart_open_ex((int8_t *)MODEM_CONNECT_MCU_PORT, (gsw_hal_uart_baudrate)baudrate, bits, parity, stop);
336}