blob: 718ca47014968f249d9262291625f99813ed94b9 [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
14#include "gsw_uart.h"
15
16#ifndef LOG_ERR_LEVEL
17#define LOG_ERR_LEVEL 3 /* error conditions */
18#endif
19#ifndef LOG_WARN_LEVEL
20#define LOG_WARN_LEVEL 4 /* warning conditions */
21#endif
22#ifndef LOG_INFO_LEVEL
23#define LOG_INFO_LEVEL 6 /* informational */
24#endif
25#ifndef LOG_DEBUG_LEVEL
26#define LOG_DEBUG_LEVEL 7 /* debug-level messages */
27#endif
28#ifndef LOG_VERBOSE_LEVEL
29#define LOG_VERBOSE_LEVEL 8
30#endif
31
l.yang6a42e4d2025-05-28 01:04:20 -070032#define GSW_UART "[HAL][GSW_UART]"
33
34
b.liu68a94c92025-05-24 12:53:41 +080035#define LOGV(fmt, args ...) \
36 do{ \
37 char *file_ptr_1001 = __FILE__; \
38 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
39 char line_1001[10] = {0}; \
40 sprintf(line_1001, "%d", __LINE__); \
41 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
42 if(*ptr_1001 == '/') \
43 break; \
44 ptr_1001--; \
45 } \
l.yang6a42e4d2025-05-28 01:04:20 -070046 fun_ptr_log(LOG_VERBOSE_LEVEL, "%s#%s: "GSW_UART"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080047 } while(0)
48
49#define LOGI(fmt, args...) \
50 do{ \
51 char *file_ptr_1001 = __FILE__; \
52 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
53 char line_1001[10] = {0}; \
54 sprintf(line_1001, "%d", __LINE__); \
55 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
56 if(*ptr_1001 == '/') \
57 break; \
58 ptr_1001--; \
59 } \
l.yang6a42e4d2025-05-28 01:04:20 -070060 fun_ptr_log(LOG_INFO_LEVEL, "%s#%s: "GSW_UART"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080061 } while(0)
62
63#define LOGD(fmt, args...) \
64 do{ \
65 char *file_ptr_1001 = __FILE__; \
66 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
67 char line_1001[10] = {0}; \
68 sprintf(line_1001, "%d", __LINE__); \
69 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
70 if(*ptr_1001 == '/') \
71 break; \
72 ptr_1001--; \
73 } \
l.yang6a42e4d2025-05-28 01:04:20 -070074 fun_ptr_log(LOG_DEBUG_LEVEL, "%s#%s: "GSW_UART"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080075 } while(0)
76
77#define LOGW(fmt, args...) \
78 do{ \
79 char *file_ptr_1001 = __FILE__; \
80 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
81 char line_1001[10] = {0}; \
82 sprintf(line_1001, "%d", __LINE__); \
83 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
84 if(*ptr_1001 == '/') \
85 break; \
86 ptr_1001--; \
87 } \
l.yang6a42e4d2025-05-28 01:04:20 -070088 fun_ptr_log(LOG_WARN_LEVEL, "%s#%s: "GSW_UART"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080089 } while(0)
90
91#define LOGE(fmt, args...) \
92 do{ \
93 char *file_ptr_1001 = __FILE__; \
94 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
95 char line_1001[10] = {0}; \
96 sprintf(line_1001, "%d", __LINE__); \
97 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
98 if(*ptr_1001 == '/') \
99 break; \
100 ptr_1001--; \
101 } \
l.yang6a42e4d2025-05-28 01:04:20 -0700102 fun_ptr_log(LOG_ERR_LEVEL, "%s#%s: "GSW_UART"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +0800103 } while(0)
104
105typedef void (*mbtk_log)(int level, const char *format,...);
106static mbtk_log fun_ptr_log = NULL;
107void *dlHandle_uart = NULL;
108char *lynqLib_uart = "/lib/libmbtk_lib.so";
109
110static int handle()
111{
112 if(dlHandle_uart == NULL || fun_ptr_log == NULL)
113 {
114 dlHandle_uart = dlopen(lynqLib_uart, RTLD_NOW);
115 fun_ptr_log = (mbtk_log)dlsym(dlHandle_uart, "mbtk_log");
116 if(fun_ptr_log == NULL || dlHandle_uart == NULL)
117 {
118 return GSW_HAL_FAIL;
119 }
120 }
121 return GSW_HAL_SUCCESS;
122}
123
124
125
126
127int32_t gsw_uart_open_ex(int8_t *port, gsw_hal_uart_baudrate baudrate, uint32_t bits, int8_t parity, uint32_t stop)
128{
129 if (handle())
130 return GSW_HAL_FAIL;
131 int fd = -1;
132 if((fd = open((const char *)port, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0)
133 {
134 LOGE("open %s failed - %d", port, errno);
135 return -1;
136 }
137 LOGD("Open %s success.", port);
138
139 /* set newtio */
140 struct termios newtio;
141 memset(&newtio, 0, sizeof(newtio));
142 if (tcflush(fd, TCIOFLUSH) < 0) {
143 LOGE("Could not flush uart port");
144 return -1;
145 }
146
147 newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
148 newtio.c_cc[VMIN] = 0; /* blocking read until 5 chars received */
149
150 /* c_iflag 输入模式 */
151 newtio.c_iflag &= ~(ICRNL | INLCR);
152 newtio.c_iflag &= ~(IXON | IXOFF | IXANY);
153
154 // /* c_lflag 本地模式 */
155 newtio.c_cflag &= ~ INPCK;
156 newtio.c_cflag |= (CLOCAL | CREAD);
157
158 // /* c_lflag 本地模式 */
159 newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
160 /* c_oflag 输出模式 */
161 newtio.c_oflag &= ~ OPOST;
162 newtio.c_oflag &= ~(ONLCR | OCRNL);
163
164 /* c_cflag 控制模式 */
165 newtio.c_cflag &= ~ CSIZE;
166 newtio.c_cflag |= CS8;
167 newtio.c_cflag &= ~ CSTOPB;
168 newtio.c_cflag &= ~ PARENB;
169
170
171 switch(baudrate)
172 {
173 case GSW_HAL_BAUDRATE_1200:
174 cfsetospeed(&newtio, B1200);
175 cfsetispeed(&newtio, B1200);
176 break;
177 case GSW_HAL_BAUDRATE_1800:
178 cfsetospeed(&newtio, B1800);
179 cfsetispeed(&newtio, B1800);
180 break;
181 case GSW_HAL_BAUDRATE_4800:
182 cfsetospeed(&newtio, B4800);
183 cfsetispeed(&newtio, B4800);
184 break;
185 case GSW_HAL_BAUDRATE_9600:
186 cfsetospeed(&newtio, B9600);
187 cfsetispeed(&newtio, B9600);
188 break;
189 case GSW_HAL_BAUDRATE_19200:
190 cfsetospeed(&newtio, B19200);
191 cfsetispeed(&newtio, B19200);
192 break;
193 case GSW_HAL_BAUDRATE_38400:
194 cfsetospeed(&newtio, B38400);
195 cfsetispeed(&newtio, B38400);
196 break;
197 case GSW_HAL_BAUDRATE_57600:
198 cfsetospeed(&newtio, B57600);
199 cfsetispeed(&newtio, B57600);
200 break;
201 case GSW_HAL_BAUDRATE_115200:
202 cfsetospeed(&newtio, B115200);
203 cfsetispeed(&newtio, B115200);
204 break;
205 case GSW_HAL_BAUDRATE_230400:
206 cfsetospeed(&newtio, B230400);
207 cfsetispeed(&newtio, B230400);
208 break;
209 case GSW_HAL_BAUDRATE_460800:
210 cfsetospeed(&newtio, B460800);
211 cfsetispeed(&newtio, B460800);
212 break;
213 case GSW_HAL_BAUDRATE_500000:
214 cfsetospeed(&newtio, B500000);
215 cfsetispeed(&newtio, B500000);
216 break;
217 case GSW_HAL_BAUDRATE_576000:
218 cfsetospeed(&newtio, B576000);
219 cfsetispeed(&newtio, B576000);
220 break;
221 case GSW_HAL_BAUDRATE_921600:
222 cfsetospeed(&newtio, B921600);
223 cfsetispeed(&newtio, B921600);
224 break;
225 default:
226 cfsetospeed(&newtio, B115200);
227 cfsetispeed(&newtio, B115200);
228 break;
229 }
230
231 switch(bits)
232 {
233 case CS5:
234 newtio.c_cflag &= ~CSIZE;
235 newtio.c_cflag |= CS5;
236 break;
237 case CS6:
238 newtio.c_cflag &= ~CSIZE;
239 newtio.c_cflag |= CS6;
240 break;
241 case CS7:
242 newtio.c_cflag &= ~CSIZE;
243 newtio.c_cflag |= CS7;
244 break;
245 case CS8:
246 newtio.c_cflag &= ~CSIZE;
247 newtio.c_cflag |= CS8;
248 break;
249 default:
250 LOGD("No set databit.");
251 break;
252 }
253
254 if(stop == 2) {
255 newtio.c_cflag |= CSTOPB;
256 } else {
257 newtio.c_cflag &= ~CSTOPB;
258 }
259
260 switch (parity)
261 {
262 case '1':// 奇校验
263 newtio.c_cflag |= PARENB;
264 newtio.c_cflag |= PARODD;
265 break;
266 case '2':// 偶校验
267 newtio.c_cflag |= PARENB;
268 newtio.c_cflag &= ~PARODD;
269 break;
270 case '0':// 无奇偶校验
271 newtio.c_cflag &= ~PARENB;
272 break;
273 default:
274 LOGD("No set parity.");
275 break;
276 }
277
278 if (tcsetattr(fd, TCSANOW, &newtio) < 0) {
279 LOGE("Can't set port setting");
280 return -1;
281 }
282
283 return fd;
284}
285
286int32_t gsw_uart_flush(int32_t fd)
287{
288 if (tcflush(fd, TCIOFLUSH) < 0)
289 {
290 return GSW_HAL_FAIL;
291 }
292 return GSW_HAL_SUCCESS;
293}
294
295
296int32_t gsw_uart_read(int32_t fd, uint8_t *buffer, uint32_t len, int32_t timeout_ms)
297{
298 if (handle())
299 return GSW_HAL_FAIL;
300 int flags = fcntl(fd, F_GETFL); // 获取当前状态标志
301 if (flags == -1)
302 {
303 perror("fcntl get");
304 return GSW_HAL_FAIL;
305 }
306
307 struct termios newtio;
308 if (tcgetattr(fd, &newtio) < 0) {
309 perror("tcgetattr failed");
310 return -1;
311 }
312 if (timeout_ms == 0)
313 {
314 flags |= O_NONBLOCK; // 设置非阻塞标志
315 fcntl(fd, F_SETFL, flags);
316 newtio.c_cc[VMIN] = 0;
317 newtio.c_cc[VTIME] = 0;
318 }
319 else if (timeout_ms == 1)
320 {
321 flags &= ~O_NONBLOCK; // 清除非阻塞标志
322 fcntl(fd, F_SETFL, flags);
323 newtio.c_cc[VMIN] = 1;
324 newtio.c_cc[VTIME] = timeout_ms/100;
325 }
326 else
327 {
328 flags &= ~O_NONBLOCK; // 清除非阻塞标志
329 fcntl(fd, F_SETFL, flags);
330 newtio.c_cc[VMIN] = 0;
331 newtio.c_cc[VTIME] = timeout_ms/100;
332 }
333 if(timeout_ms != 0)
334 LOGI("%s :VMIN = %d ;VTIME = %d\n",__func__,newtio.c_cc[VMIN],newtio.c_cc[VTIME]);
335 if (tcsetattr(fd, TCSANOW, &newtio) != 0)
336 {
337 perror("tcsetattr");
338 return -1;
339 }
340 //gsw_uart_flush(fd);
341 int data_len = read(fd, buffer, len);
342 if (data_len < 0)
343 {
344 if(errno == EAGAIN || errno == EWOULDBLOCK)
345 return 0;
346 else
347 return GSW_HAL_FAIL;
348 }
349 return data_len;
350}
351
352
353int32_t gsw_uart_write(int32_t fd, const uint8_t *buffer, uint32_t len)
354{
355 //gsw_uart_flush(fd);
356 if (write(fd, buffer, len) < 0)
357 {
358 return GSW_HAL_FAIL;
359 }
360 return GSW_HAL_SUCCESS;
361}
362
363int32_t gsw_uart_ioctl(int32_t fd, uint32_t cmd, void *pvalue)
364{
365 if (handle())
366 return GSW_HAL_FAIL;
367 if (fd < 0 || pvalue == NULL)
368 {
369 LOGE("Invalid file descriptor");
370 return GSW_HAL_FAIL;
371 }
372 if (ioctl(fd, cmd, pvalue) < 0)
373 {
374 LOGE("Could not set DCB,error:%d, %s\n",errno, strerror(errno));
375 return GSW_HAL_FAIL;
376 }
377 return GSW_HAL_SUCCESS;
378}
379
380
381
382
383int32_t gsw_uart_close(int32_t fd)
384{
385 if (fd <= 0)
386 return GSW_HAL_FAIL;
387 //gsw_uart_flush(fd);
388 close(fd);
389 return GSW_HAL_SUCCESS;
390}
391