blob: 68c32f1271d374eee1bdfa1f47f1e81dd029cf43 [file] [log] [blame]
b.liu778645e2024-06-21 16:47:42 +08001
2#include "port.h"
3
4/**
5 * @brief Send Data to serial port
6 * @param fd:file desc
7 * @param cmd:data pointer
8 * @param cmd_len:data length
9 * @retval SUCCESS/FAIL
10 */
11int uart_send(int fd, const uint8_t *cmd, int cmd_len)
12{
13 int ret = FAIL;
14
15 ret = write(fd, cmd, cmd_len);
16 if(ret < 0)
17 {
18 HDBD_LOG("[%s %d]write port failed,ret: %d\n", __FUNCTION__, __LINE__, ret);
19 return FAIL;
20 }
21
22 return SUCCESS;
23}
24
25
26/**
27 * @brief Receive data from serial port0
28 * @param fd:file desc
29 * @param buf:receive buffer
30 * @param actual_length:receive data length
31 * @param timeout:para of timeout
32 * @retval SUCCESS/FAIL
33 */
34int uart_recv(int fd, uint8_t *buf, int *actual_length, int timeout)
35{
36 int ret;
37 int temp = 0;
38 int len = *actual_length;
39 uint8_t tempBuf[128] = {0};
40 int errorCount = 0;
41 fd_set rd;
42 struct timeval tv;
43 tv.tv_sec = timeout;
44 tv.tv_usec = 0;
45
46 FD_ZERO(&rd);
47 FD_SET(fd, &rd);
48 *actual_length = 0;
49 HDBD_LOG("[%s %d] len:%d\n", __FUNCTION__, __LINE__, len);
50 while(1)
51 {
52 ret = select(fd + 1, &rd, NULL, NULL, &tv);
53 if(ret > 0){
54 if (FD_ISSET(fd, &rd)) {
55 temp = read(fd, tempBuf, 128);
56 if(temp > 0)
57 {
58 errorCount = 0;
59 if((*actual_length + temp) <= len)
60 {
61 memcpy(buf+*actual_length, tempBuf, temp);
62 *actual_length += temp;
63 }
64 else
65 {
66 memcpy(buf+*actual_length, tempBuf, (len - *actual_length));
67 *actual_length = len;
68 }
69 }
70 else
71 {
72 errorCount++;
73 }
74 HDBD_LOG("[%s %d]len:%d, *actual_length:%d, temp:%d\n", __FUNCTION__, __LINE__, len, *actual_length, temp);
75 }
76 }
77 else if(ret == 0)
78 {
79 HDBD_LOG("[%s %d]timeout\n", __FUNCTION__, __LINE__);
80 if(*actual_length <= 2)
81 {
82 goto ERR1;
83 }
84 else
85 {
86 break;
87 }
88 }
89 else
90 {
91 HDBD_LOG("[%s %d] select error!\n", __FUNCTION__, __LINE__);
92 goto ERR1;
93 }
94
95 if((*actual_length >= len) || (errorCount >= 5))
96 {
97 HDBD_LOG("[%s %d]*actual_length:%d, recv sucess,break\n", __FUNCTION__, __LINE__, *actual_length);
98 break;
99 }
100
101 }
102
103 HDBD_LOG("[%s %d]*actual_length:%d, ret:%d\n", __FUNCTION__, __LINE__, *actual_length, ret);
104 return SUCCESS;
105
106ERR1:
107 return FAIL;
108}
109
110int UartRead(int fd, uint8_t *RxBuff, long RxLen)
111{
112 #if 1
113 int GetRxLen=0;
114 int index;
115 while(RxLen){
116 //printf("RxLen=%d\r\n", RxLen);
117 index = read(fd, RxBuff+GetRxLen, 1);
118 //printf("index=%d\r\n", index);
119 GetRxLen += index;
120 //printf("GetRxLen=%d\r\n", GetRxLen);
121 RxLen--;
122 //printf("RxLen=%d\r\n", RxLen);
123 if(index == 0)
124 {
125 return GetRxLen;
126 }
127 }
128
129 return GetRxLen ;
130 #else
131 int GetRxLen=0;
132 while(RxLen){
133 //printf("[RxLen=%ld]\r\n", RxLen);
134 GetRxLen += read(fd, RxBuff+GetRxLen, 1);
135 RxLen--;
136 }
137
138 return GetRxLen ;
139 #endif
140}
141
142/**
143 * @brief Write gpio node
144 * @param path:path of gpio node
145 * @param value:'1' or '0'
146 * @retval SUCCESS/FAIL
147 */
148int write_gpio(char const* path, int value)
149{
150 int fd = -1;
151 char buffer[20] = {0};
152 int bytes = 0;
153 ssize_t amt = 0;
154
155 memset(buffer, 0x0, sizeof(buffer));
156 fd = open(path, O_RDWR);
157
158 if (fd >= 0)
159 {
160 bytes = snprintf(buffer, sizeof(buffer), "%d\n", value);
161 amt = write(fd, buffer, (size_t)bytes);
162 close(fd);
163 return amt == -1 ? -errno : 0;
164 }
165 else
166 {
167 HDBD_LOG("[%s %d]write_int failed to open %s, errno is %d \n", __FUNCTION__, __LINE__, path, errno);
168 }
169
170 return -errno;
171}
172
173/**
174 * @brief Read gpio node
175 * @param path:path of gpio node
176 * @param value:'1' or '0'
177 * @retval SUCCESS/FAIL
178 */
179int read_gpio(char const* path)
180{
181 int fd = -1;
182 char buffer[20] = {0};
183 ssize_t amt = 0;
184
185 memset(buffer, 0x0, sizeof(buffer));
186 fd = open(path, O_RDWR);
187
188 if (fd >= 0)
189 {
190 amt = read(fd, buffer, 1);
191 close(fd);
192 HDBD_LOG("[%s %d]read to <%s>, value is <%zd> \n", __FUNCTION__, __LINE__, path, amt);
193 return 0;
194 }
195 else
196 {
197 HDBD_LOG("[%s %d]read failed to open <%s>, errno is <%d> \n", __FUNCTION__, __LINE__, path, errno);
198 }
199
200 return -1;
201}
202
203/**
204 * @brief Set serial port Para
205 * @param fd:file desc
206 * @param speed:baudrate
207 * @param flow_ctrl:flow control flag
208 * @param databits:data bits
209 * @param stopbits:stop bits
210 * @param parity:parity flag
211 * @retval SUCCESS/FAIL
212 */
213int uart_set(int fd, int speed, int flow_ctrl, int databits, int stopbits, int parity)
214{
215 int i;
216 int speed_arr[11] = {B921600, B576000, B460800,B230400, B115200, B19200, B9600, B4800, B2400, B1200, B300};
217 int name_arr[11] = {921600,576000,460800,230400, 115200, 19200, 9600, 4800, 2400, 1200, 300};
218
219 struct termios options;
220
221 if ( tcgetattr( fd, &options) != 0)
222 {
223 HDBD_LOG("[%s %d]get serial options Fail\n", __FUNCTION__, __LINE__);
224 return FAIL;
225 }
226
227 for ( i = 0; i < 11; i++) /* sizeof(speed_arr) / sizeof(int) */
228 {
229 if (speed == name_arr[i])
230 {
231 cfsetispeed(&options, speed_arr[i]);
232 cfsetospeed(&options, speed_arr[i]);
233 break;
234 }
235 }
236
237 options.c_cflag |= CLOCAL;
238 options.c_cflag |= CREAD;
239
240 switch (flow_ctrl)
241 {
242
243 case 0 :
244 options.c_cflag &= ~CRTSCTS;
245 break;
246
247 case 1 :
248 options.c_cflag |= CRTSCTS;
249 break;
250 case 2 :
251 options.c_cflag |= IXON | IXOFF | IXANY;
252 break;
253 }
254
255 options.c_cflag &= ~CSIZE;
256 switch (databits)
257 {
258 case 5 :
259 options.c_cflag |= CS5;
260 break;
261 case 6 :
262 options.c_cflag |= CS6;
263 break;
264 case 7 :
265 options.c_cflag |= CS7;
266 break;
267 case 8:
268 options.c_cflag |= CS8;
269 break;
270 default:
271 HDBD_LOG("[%s %d] Unsupported data size\n", __FUNCTION__, __LINE__);
272 return FAIL;
273 }
274
275 switch (parity)
276 {
277 case 'n':
278 case 'N':
279 options.c_cflag &= ~PARENB;
280 options.c_iflag &= ~INPCK;
281 break;
282 case 'o':
283 case 'O':
284 options.c_cflag |= (PARODD | PARENB);
285 options.c_iflag |= INPCK;
286 break;
287 case 'e':
288 case 'E':
289 options.c_cflag |= PARENB;
290 options.c_cflag &= ~PARODD;
291 options.c_iflag |= INPCK;
292 break;
293 case 's':
294 case 'S':
295 options.c_cflag &= ~PARENB;
296 options.c_cflag &= ~CSTOPB;
297 break;
298 default:
299 HDBD_LOG("[%s %d] Unsupported parity\n", __FUNCTION__, __LINE__);
300 return FAIL;
301 }
302
303 switch (stopbits)
304 {
305 case 1:
306 options.c_cflag &= ~CSTOPB; break;
307 case 2:
308 options.c_cflag |= CSTOPB; break;
309 default:
310 HDBD_LOG("[%s %d] Unsupported stop bits\n", __FUNCTION__, __LINE__);
311 return FAIL;
312 }
313
314 options.c_oflag &= ~OPOST;
315 options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
316 //options.c_lflag &= ~(ISIG | ICANON);
317 options.c_cc[VTIME] = 1;
318 options.c_cc[VMIN] = 1;
319 tcflush(fd, TCIFLUSH);
320
321 if (tcsetattr(fd, TCSANOW, &options) != 0)
322 {
323 HDBD_LOG("[%s %d] com set error!\n", __FUNCTION__, __LINE__);
324 return FAIL;
325 }
326
327 return SUCCESS;
328}
329
330/**
331 * @brief Init serial port
332 * @param fd:file desc
333 * @param speed:baudrate
334 * @param flow_ctrl:flow control flag
335 * @param databits:data bits
336 * @param stopbits:stop bits
337 * @param parity:parity flag
338 * @retval SUCCESS/FAIL
339 */
340int uart_init(int fd, int speed, int flow_ctrl, int databits, int stopbits, int parity)
341{
342 if (uart_set(fd, speed, flow_ctrl, databits, stopbits, parity) == FAIL)
343 {
344 HDBD_LOG("[%s %d] Uart init false\n", __FUNCTION__, __LINE__);
345 return FAIL;
346 }
347 else
348 {
349 return SUCCESS;
350 }
351}
352
353/**
354 * @brief Init serial port
355 * @param fd:uart fd
356 * @param selector:TCIOFLUSH/TCIFLUSH
357 */
358void clearBuffer(int fd, int selector)
359{
360 tcflush(fd, selector);
361}
362
363/**
364 * @brief open serial port
365 * @param GPS_DEVICE:uart port
366 * @retval SUCCESS/FAIL
367 */
368int uart_open(unsigned char * GPS_DEVICE)
369{
370 int fd = -1;
371 int uart_init_ret = -1;
372 //*****************************************************************************
373 fd = open((char *)GPS_DEVICE, O_RDWR|O_NOCTTY|O_NDELAY);
374
375 if( fd < 0)
376 {
377 HDBD_LOG("[%s %d] : open port ERROR..state->fd=%d, errno=%d\n",__FUNCTION__, __LINE__, fd, errno);
378 return -1;
379 }
380
381 HDBD_LOG("[%s %d] : open port succceed..state->fd=%d OK\n", __FUNCTION__, __LINE__, fd);
382
383 /* set port */
384 if(fcntl( fd,F_SETFL,0)<0)
385 {
386 HDBD_LOG("[%s %d] : fcntl F_SETFL Fail\n", __FUNCTION__, __LINE__);
387 return -1;
388 }
389
390 tcflush(fd, TCIOFLUSH);
391
392 uart_init_ret = uart_init(fd, 115200, 0, 8, 1, 'N');
393 if (-1 == uart_init_ret)
394 {
395 HDBD_LOG("[%s %d] : uart_init_ret is <%d>, return -1\n", __FUNCTION__, __LINE__, uart_init_ret);
396 return -1;
397 }
398
399 HDBD_LOG("[%s %d] : Port setup finished..OK\n", __FUNCTION__, __LINE__);
400 //**********************************************************************
401 return fd;
402}
403
404int uart_close(int fd)
405{
406 close(fd);
407 return 0;
408}
409
410
411void SetOpt(int fd)
412{
413 static struct termios termold, termnew;
414 tcgetattr(fd, &termold);
415 bzero(&termnew, sizeof(termnew));
416
417 termnew.c_iflag &= ~(ICRNL | IGNCR);
418 termnew.c_cflag |= CLOCAL | CREAD; //CLOCAL:忽略modem控制线 CREAD:打开接受者
419 termnew.c_cflag &= ~CSIZE;
420 termnew.c_cflag |= CS8;
421 termnew.c_cflag &= ~CRTSCTS;
422 termnew.c_cflag &= ~PARENB;
423
424 cfsetispeed(&termnew, B115200);
425 cfsetospeed(&termnew, B115200);
426
427 termnew.c_cflag &= ~CSTOPB;
428 termnew.c_cc[VTIME] = 1; //VTIME:非cannoical模式读时的延时,以十分之一秒位单位
429 termnew.c_cc[VMIN] = 0; //VMIN:非canonical模式读到最小字符数
430 tcflush(fd, TCIFLUSH);
431 tcsetattr(fd, TCSANOW, &termnew);
432}
433
434/*
435* band : 0->460800, 1->115200, 2->9600, other->115200
436*/
437int set_baudrate(int fd, uint8_t baud)
438{
439 static struct termios termold, termnew;
440 tcgetattr(fd, &termold);
441 bzero(&termnew, sizeof(termnew));
442
443 termnew.c_iflag &= ~(ICRNL | IGNCR);
444 termnew.c_cflag |= CLOCAL | CREAD; //CLOCAL:忽略modem控制线 CREAD:打开接受者
445 termnew.c_cflag &= ~CSIZE;
446 termnew.c_cflag |= CS8;
447 termnew.c_cflag &= ~CRTSCTS;
448 termnew.c_cflag &= ~PARENB;
449
450 if(baud == 1)
451 {
452 cfsetispeed(&termnew, B460800);
453 cfsetospeed(&termnew, B460800);
454 }
455 else if(baud == 2)
456 {
457 cfsetispeed(&termnew, B115200);
458 cfsetospeed(&termnew, B115200);
459 }
460 else if(baud)
461 {
462 cfsetispeed(&termnew, B9600);
463 cfsetospeed(&termnew, B9600);
464 }
465 else
466 {
467 cfsetispeed(&termnew, B115200);
468 cfsetospeed(&termnew, B115200);
469 }
470 termnew.c_cflag &= ~CSTOPB;
471 termnew.c_cc[VTIME] = 1; //VTIME:非cannoical模式读时的延时,以十分之一秒位单位
472 termnew.c_cc[VMIN] = 0; //VMIN:非canonical模式读到最小字符数
473 tcflush(fd, TCIFLUSH);
474 tcsetattr(fd, TCSANOW, &termnew);
475 return 0;
476}
477
b.liu9e8584b2024-11-06 19:21:28 +0800478int OpenUart(const char* UART_DEV)
b.liu778645e2024-06-21 16:47:42 +0800479{
480 int fd=0;
481
482 /*第1个参数:想要打开的文件路径名,或者文件名
483 *第2个参数:open_Status:文件打开方式,可采用下面的文件打开模式:
484 O_RDONLY:以只读方式打开文件
485 O_WRONLY:以只写方式打开文件
486 O_RDWR:以读写方式打开文件
487 O_APPEND:写入数据时添加到文件末尾
488 O_CREATE:如果文件不存在则产生该文件,使用该标志需要设置访问权限位mode_t
489 O_EXCL:指定该标志,并且指定了O_CREATE标志,如果打开的文件存在则会产生一个错误
490 O_TRUNC:如果文件存在并且成功以写或者只写方式打开,则清除文件所有内容,使得文件长度变为0
491 O_NOCTTY:如果打开的是一个终端设备,这个程序不会成为对应这个端口的控制终端,如果没有该标志,任何一个输入,例如键盘中止信号等,都将影响进程。
492 O_NONBLOCK:该标志与早期使用的O_NDELAY标志作用差不多。程序不关心DCD信号线的状态,如果指定该标志,进程将一直在休眠状态,直到DCD信号线为0。
493 O_NONBLOCK和O_NDELAY所产生的结果都是使I/O变成非搁置模式(non-blocking),在读取不到数据或是写入缓冲区已满会马上return,而不会搁置程序动作,直到有数据或写入完成;
494 它们的差别在于设立O_NDELAY会使I/O函式马上回传0,但是又衍生出一个问题,因为读取到档案结尾时所回传的也是0,这样无法得知是哪中情况;因此,O_NONBLOCK就产生出来,它在读取不到数据时会回传-1,并且设置errno为EAGAIN。
495 第3个参数:设置文件访问权限的初始值
496 */
497 fd = open(UART_DEV , O_RDWR|O_NOCTTY);
498 if (fd < 0)
499 {
500 return -1;
501 }
502 SetOpt(fd);
503 return fd;
504}