blob: e09aefd701c4d915ff3fd528e2f0d0c61a4b1ca4 [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
b.liu68a94c92025-05-24 12:53:41 +080018#ifndef LOG_ERR_LEVEL
19#define LOG_ERR_LEVEL 3 /* error conditions */
20#endif
21#ifndef LOG_WARN_LEVEL
22#define LOG_WARN_LEVEL 4 /* warning conditions */
23#endif
24#ifndef LOG_INFO_LEVEL
25#define LOG_INFO_LEVEL 6 /* informational */
26#endif
27#ifndef LOG_DEBUG_LEVEL
28#define LOG_DEBUG_LEVEL 7 /* debug-level messages */
29#endif
30#ifndef LOG_VERBOSE_LEVEL
31#define LOG_VERBOSE_LEVEL 8
32#endif
33
l.yang6a42e4d2025-05-28 01:04:20 -070034#define GSW_UART "[HAL][GSW_UART]"
35
36
b.liu68a94c92025-05-24 12:53:41 +080037#define LOGV(fmt, args ...) \
38 do{ \
39 char *file_ptr_1001 = __FILE__; \
40 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
41 char line_1001[10] = {0}; \
42 sprintf(line_1001, "%d", __LINE__); \
43 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
44 if(*ptr_1001 == '/') \
45 break; \
46 ptr_1001--; \
47 } \
l.yang6a42e4d2025-05-28 01:04:20 -070048 fun_ptr_log(LOG_VERBOSE_LEVEL, "%s#%s: "GSW_UART"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080049 } while(0)
50
51#define LOGI(fmt, args...) \
52 do{ \
53 char *file_ptr_1001 = __FILE__; \
54 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
55 char line_1001[10] = {0}; \
56 sprintf(line_1001, "%d", __LINE__); \
57 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
58 if(*ptr_1001 == '/') \
59 break; \
60 ptr_1001--; \
61 } \
l.yang6a42e4d2025-05-28 01:04:20 -070062 fun_ptr_log(LOG_INFO_LEVEL, "%s#%s: "GSW_UART"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080063 } while(0)
64
65#define LOGD(fmt, args...) \
66 do{ \
67 char *file_ptr_1001 = __FILE__; \
68 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
69 char line_1001[10] = {0}; \
70 sprintf(line_1001, "%d", __LINE__); \
71 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
72 if(*ptr_1001 == '/') \
73 break; \
74 ptr_1001--; \
75 } \
l.yang6a42e4d2025-05-28 01:04:20 -070076 fun_ptr_log(LOG_DEBUG_LEVEL, "%s#%s: "GSW_UART"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080077 } while(0)
78
79#define LOGW(fmt, args...) \
80 do{ \
81 char *file_ptr_1001 = __FILE__; \
82 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
83 char line_1001[10] = {0}; \
84 sprintf(line_1001, "%d", __LINE__); \
85 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
86 if(*ptr_1001 == '/') \
87 break; \
88 ptr_1001--; \
89 } \
l.yang6a42e4d2025-05-28 01:04:20 -070090 fun_ptr_log(LOG_WARN_LEVEL, "%s#%s: "GSW_UART"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080091 } while(0)
92
93#define LOGE(fmt, args...) \
94 do{ \
95 char *file_ptr_1001 = __FILE__; \
96 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
97 char line_1001[10] = {0}; \
98 sprintf(line_1001, "%d", __LINE__); \
99 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
100 if(*ptr_1001 == '/') \
101 break; \
102 ptr_1001--; \
103 } \
l.yang6a42e4d2025-05-28 01:04:20 -0700104 fun_ptr_log(LOG_ERR_LEVEL, "%s#%s: "GSW_UART"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +0800105 } while(0)
106
107typedef void (*mbtk_log)(int level, const char *format,...);
108static mbtk_log fun_ptr_log = NULL;
109void *dlHandle_uart = NULL;
110char *lynqLib_uart = "/lib/libmbtk_lib.so";
111
hong.liucd370792025-05-28 06:29:19 -0700112typedef enum
113{
114 GSW_HAL_BAUDRATE_1200=1200,
115 GSW_HAL_BAUDRATE_1800=1800,
116 GSW_HAL_BAUDRATE_4800=4800,
117 GSW_HAL_BAUDRATE_9600=9600,
118 GSW_HAL_BAUDRATE_19200=19200,
119 GSW_HAL_BAUDRATE_38400=38400,
120 GSW_HAL_BAUDRATE_57600=57600,
121 GSW_HAL_BAUDRATE_115200=115200,
122 GSW_HAL_BAUDRATE_230400=230400,
123 GSW_HAL_BAUDRATE_460800=460800,
124 GSW_HAL_BAUDRATE_500000=500000,
125 GSW_HAL_BAUDRATE_576000=576000,
126 GSW_HAL_BAUDRATE_921600=921600
127}gsw_hal_uart_baudrate;
128
b.liu68a94c92025-05-24 12:53:41 +0800129static int handle()
130{
131 if(dlHandle_uart == NULL || fun_ptr_log == NULL)
132 {
133 dlHandle_uart = dlopen(lynqLib_uart, RTLD_NOW);
134 fun_ptr_log = (mbtk_log)dlsym(dlHandle_uart, "mbtk_log");
135 if(fun_ptr_log == NULL || dlHandle_uart == NULL)
136 {
hong.liucd370792025-05-28 06:29:19 -0700137 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800138 }
139 }
140 return GSW_HAL_SUCCESS;
141}
142
b.liu68a94c92025-05-24 12:53:41 +0800143int32_t gsw_uart_open_ex(int8_t *port, gsw_hal_uart_baudrate baudrate, uint32_t bits, int8_t parity, uint32_t stop)
144{
145 if (handle())
hong.liucd370792025-05-28 06:29:19 -0700146 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800147 int fd = -1;
148 if((fd = open((const char *)port, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0)
149 {
150 LOGE("open %s failed - %d", port, errno);
151 return -1;
152 }
153 LOGD("Open %s success.", port);
154
155 /* set newtio */
156 struct termios newtio;
157 memset(&newtio, 0, sizeof(newtio));
158 if (tcflush(fd, TCIOFLUSH) < 0) {
159 LOGE("Could not flush uart port");
160 return -1;
161 }
162
163 newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
164 newtio.c_cc[VMIN] = 0; /* blocking read until 5 chars received */
165
166 /* c_iflag 输入模式 */
167 newtio.c_iflag &= ~(ICRNL | INLCR);
168 newtio.c_iflag &= ~(IXON | IXOFF | IXANY);
169
170 // /* c_lflag 本地模式 */
171 newtio.c_cflag &= ~ INPCK;
172 newtio.c_cflag |= (CLOCAL | CREAD);
173
174 // /* c_lflag 本地模式 */
175 newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
176 /* c_oflag 输出模式 */
177 newtio.c_oflag &= ~ OPOST;
178 newtio.c_oflag &= ~(ONLCR | OCRNL);
179
180 /* c_cflag 控制模式 */
181 newtio.c_cflag &= ~ CSIZE;
182 newtio.c_cflag |= CS8;
183 newtio.c_cflag &= ~ CSTOPB;
184 newtio.c_cflag &= ~ PARENB;
185
186
187 switch(baudrate)
188 {
189 case GSW_HAL_BAUDRATE_1200:
190 cfsetospeed(&newtio, B1200);
191 cfsetispeed(&newtio, B1200);
192 break;
193 case GSW_HAL_BAUDRATE_1800:
194 cfsetospeed(&newtio, B1800);
195 cfsetispeed(&newtio, B1800);
196 break;
197 case GSW_HAL_BAUDRATE_4800:
198 cfsetospeed(&newtio, B4800);
199 cfsetispeed(&newtio, B4800);
200 break;
201 case GSW_HAL_BAUDRATE_9600:
202 cfsetospeed(&newtio, B9600);
203 cfsetispeed(&newtio, B9600);
204 break;
205 case GSW_HAL_BAUDRATE_19200:
206 cfsetospeed(&newtio, B19200);
207 cfsetispeed(&newtio, B19200);
208 break;
209 case GSW_HAL_BAUDRATE_38400:
210 cfsetospeed(&newtio, B38400);
211 cfsetispeed(&newtio, B38400);
212 break;
213 case GSW_HAL_BAUDRATE_57600:
214 cfsetospeed(&newtio, B57600);
215 cfsetispeed(&newtio, B57600);
216 break;
217 case GSW_HAL_BAUDRATE_115200:
218 cfsetospeed(&newtio, B115200);
219 cfsetispeed(&newtio, B115200);
220 break;
221 case GSW_HAL_BAUDRATE_230400:
222 cfsetospeed(&newtio, B230400);
223 cfsetispeed(&newtio, B230400);
224 break;
225 case GSW_HAL_BAUDRATE_460800:
226 cfsetospeed(&newtio, B460800);
227 cfsetispeed(&newtio, B460800);
228 break;
229 case GSW_HAL_BAUDRATE_500000:
230 cfsetospeed(&newtio, B500000);
231 cfsetispeed(&newtio, B500000);
232 break;
233 case GSW_HAL_BAUDRATE_576000:
234 cfsetospeed(&newtio, B576000);
235 cfsetispeed(&newtio, B576000);
236 break;
237 case GSW_HAL_BAUDRATE_921600:
238 cfsetospeed(&newtio, B921600);
239 cfsetispeed(&newtio, B921600);
240 break;
241 default:
242 cfsetospeed(&newtio, B115200);
243 cfsetispeed(&newtio, B115200);
244 break;
245 }
246
247 switch(bits)
248 {
hong.liucd370792025-05-28 06:29:19 -0700249 case 5:
b.liu68a94c92025-05-24 12:53:41 +0800250 newtio.c_cflag &= ~CSIZE;
251 newtio.c_cflag |= CS5;
252 break;
hong.liucd370792025-05-28 06:29:19 -0700253 case 6:
b.liu68a94c92025-05-24 12:53:41 +0800254 newtio.c_cflag &= ~CSIZE;
255 newtio.c_cflag |= CS6;
256 break;
hong.liucd370792025-05-28 06:29:19 -0700257 case 7:
b.liu68a94c92025-05-24 12:53:41 +0800258 newtio.c_cflag &= ~CSIZE;
259 newtio.c_cflag |= CS7;
260 break;
hong.liucd370792025-05-28 06:29:19 -0700261 case 8:
b.liu68a94c92025-05-24 12:53:41 +0800262 newtio.c_cflag &= ~CSIZE;
263 newtio.c_cflag |= CS8;
264 break;
265 default:
266 LOGD("No set databit.");
267 break;
268 }
269
270 if(stop == 2) {
271 newtio.c_cflag |= CSTOPB;
272 } else {
273 newtio.c_cflag &= ~CSTOPB;
274 }
275
276 switch (parity)
277 {
hong.liucd370792025-05-28 06:29:19 -0700278 case 'O':
279 case 'o':// 奇校验
b.liu68a94c92025-05-24 12:53:41 +0800280 newtio.c_cflag |= PARENB;
281 newtio.c_cflag |= PARODD;
282 break;
hong.liucd370792025-05-28 06:29:19 -0700283 case 'E':
284 case 'e':// 偶校验
b.liu68a94c92025-05-24 12:53:41 +0800285 newtio.c_cflag |= PARENB;
286 newtio.c_cflag &= ~PARODD;
287 break;
hong.liucd370792025-05-28 06:29:19 -0700288 case 'N':
289 case 'n':// 无奇偶校验
b.liu68a94c92025-05-24 12:53:41 +0800290 newtio.c_cflag &= ~PARENB;
291 break;
292 default:
293 LOGD("No set parity.");
294 break;
295 }
296
297 if (tcsetattr(fd, TCSANOW, &newtio) < 0) {
298 LOGE("Can't set port setting");
299 return -1;
300 }
301
302 return fd;
303}
304
hong.liud2417072025-06-27 07:10:37 -0700305void gsw_uart_flush(int32_t fd)
b.liu68a94c92025-05-24 12:53:41 +0800306{
zw.wang10b141c2025-06-19 11:18:30 +0800307 if (handle())
308 return;
b.liu68a94c92025-05-24 12:53:41 +0800309 if (tcflush(fd, TCIOFLUSH) < 0)
310 {
hong.liucd370792025-05-28 06:29:19 -0700311 LOGE("flush fail\n");
312 //return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800313 }
hong.liucd370792025-05-28 06:29:19 -0700314 else
315 LOGD("flush success\n");
316 //return GSW_HAL_SUCCESS;
b.liu68a94c92025-05-24 12:53:41 +0800317}
318
hong.liucd370792025-05-28 06:29:19 -0700319int gsw_uart_read(int fd, unsigned char *buffer, int len, int timeout_ms)
b.liu68a94c92025-05-24 12:53:41 +0800320{
321 if (handle())
hong.liucd370792025-05-28 06:29:19 -0700322 return GSW_HAL_NORMAL_FAIL;
323 if(len <= 0 || timeout_ms < -1)
324 {
325 LOGE("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);
326 return GSW_HAL_NORMAL_FAIL;
327 }
b.liu68a94c92025-05-24 12:53:41 +0800328 int flags = fcntl(fd, F_GETFL); // 获取当前状态标志
329 if (flags == -1)
330 {
331 perror("fcntl get");
hong.liucd370792025-05-28 06:29:19 -0700332 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800333 }
334
335 struct termios newtio;
336 if (tcgetattr(fd, &newtio) < 0) {
337 perror("tcgetattr failed");
338 return -1;
339 }
340 if (timeout_ms == 0)
341 {
342 flags |= O_NONBLOCK; // 设置非阻塞标志
343 fcntl(fd, F_SETFL, flags);
344 newtio.c_cc[VMIN] = 0;
345 newtio.c_cc[VTIME] = 0;
346 }
hong.liucd370792025-05-28 06:29:19 -0700347 else if (timeout_ms == -1)
b.liu68a94c92025-05-24 12:53:41 +0800348 {
349 flags &= ~O_NONBLOCK; // 清除非阻塞标志
350 fcntl(fd, F_SETFL, flags);
351 newtio.c_cc[VMIN] = 1;
hong.liucd370792025-05-28 06:29:19 -0700352 newtio.c_cc[VTIME] = 0;
b.liu68a94c92025-05-24 12:53:41 +0800353 }
354 else
355 {
356 flags &= ~O_NONBLOCK; // 清除非阻塞标志
357 fcntl(fd, F_SETFL, flags);
358 newtio.c_cc[VMIN] = 0;
359 newtio.c_cc[VTIME] = timeout_ms/100;
360 }
361 if(timeout_ms != 0)
362 LOGI("%s :VMIN = %d ;VTIME = %d\n",__func__,newtio.c_cc[VMIN],newtio.c_cc[VTIME]);
363 if (tcsetattr(fd, TCSANOW, &newtio) != 0)
364 {
365 perror("tcsetattr");
366 return -1;
367 }
368 //gsw_uart_flush(fd);
369 int data_len = read(fd, buffer, len);
370 if (data_len < 0)
371 {
372 if(errno == EAGAIN || errno == EWOULDBLOCK)
373 return 0;
374 else
hong.liucd370792025-05-28 06:29:19 -0700375 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800376 }
377 return data_len;
378}
379
380
hong.liucd370792025-05-28 06:29:19 -0700381int gsw_uart_write(int fd, const unsigned char *buffer, int len)
b.liu68a94c92025-05-24 12:53:41 +0800382{
383 //gsw_uart_flush(fd);
384 if (write(fd, buffer, len) < 0)
385 {
hong.liucd370792025-05-28 06:29:19 -0700386 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800387 }
388 return GSW_HAL_SUCCESS;
389}
390
391int32_t gsw_uart_ioctl(int32_t fd, uint32_t cmd, void *pvalue)
392{
393 if (handle())
hong.liucd370792025-05-28 06:29:19 -0700394 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800395 if (fd < 0 || pvalue == NULL)
396 {
397 LOGE("Invalid file descriptor");
hong.liucd370792025-05-28 06:29:19 -0700398 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800399 }
400 if (ioctl(fd, cmd, pvalue) < 0)
401 {
402 LOGE("Could not set DCB,error:%d, %s\n",errno, strerror(errno));
hong.liucd370792025-05-28 06:29:19 -0700403 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800404 }
405 return GSW_HAL_SUCCESS;
406}
407
hong.liucd370792025-05-28 06:29:19 -0700408void gsw_uart_close(int fd)
b.liu68a94c92025-05-24 12:53:41 +0800409{
zw.wang10b141c2025-06-19 11:18:30 +0800410 if (handle())
411 return;
b.liu68a94c92025-05-24 12:53:41 +0800412 if (fd <= 0)
hong.liucd370792025-05-28 06:29:19 -0700413 LOGE("fd = %d fail\n",fd);
414 //return GSW_HAL_NORMAL_FAIL;
415 else
416 {
417 //gsw_uart_flush(fd);
418 int ret = close(fd);
419 if(ret < 0)
420 {
421 LOGE("close fail ret = %d\n",ret);
422 }
423 else
424 {
425 LOGI("close success ret = %d\n",ret);
426 }
427 }
428
429 //return GSW_HAL_SUCCESS;
b.liu68a94c92025-05-24 12:53:41 +0800430}
431
hong.liud2417072025-06-27 07:10:37 -0700432int gsw_uart_open(unsigned int baudrate, unsigned int bits, char parity, unsigned int stop)
433{
434 return gsw_uart_open_ex((int8_t *)MODEM_CONNECT_MCU_PORT, (gsw_hal_uart_baudrate)baudrate, bits, parity, stop);
435}