blob: bb4aa1b4985a492da0194f13ac36c0d98b085fa4 [file] [log] [blame]
xf.libdd93d52023-05-12 07:10:14 -07001#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4#include <signal.h>
5#include <sys/types.h>
6#include <sys/socket.h>
7#include <unistd.h>
8#include <sys/types.h>
9#include <sys/stat.h>
10#include <fcntl.h>
11#include <string.h>
12#include <errno.h>
13#include <sys/socket.h>
14#include <sys/ioctl.h>
15#include <net/if.h>
16#include <net/if_arp.h>
17#include <netinet/in.h>
18#include <linux/sockios.h>
19//#include <cfg_api.h>
20#include <termios.h>
21#include <sys/prctl.h>
22#include <pthread.h>
23#include <assert.h>
24#include <sys/select.h>
25
26#define UART_DEV "/dev/ttyS0"
27#define ONE_LEN 4095
28typedef unsigned int uint32_t;
29typedef unsigned char uint8_t;
30
31int uart_fd_0 = -1;
32int uart_fd_1 = -1;
33int times = 0;
34int tlen = 0;
35uint8_t dbuf[2100000];
36
37static const uint8_t crc_table[] =
38{
39 0x00,0x31,0x62,0x53,0xc4,0xf5,0xa6,0x97,0xb9,0x88,0xdb,0xea,0x7d,0x4c,0x1f,0x2e,
40 0x43,0x72,0x21,0x10,0x87,0xb6,0xe5,0xd4,0xfa,0xcb,0x98,0xa9,0x3e,0x0f,0x5c,0x6d,
41 0x86,0xb7,0xe4,0xd5,0x42,0x73,0x20,0x11,0x3f,0x0e,0x5d,0x6c,0xfb,0xca,0x99,0xa8,
42 0xc5,0xf4,0xa7,0x96,0x01,0x30,0x63,0x52,0x7c,0x4d,0x1e,0x2f,0xb8,0x89,0xda,0xeb,
43 0x3d,0x0c,0x5f,0x6e,0xf9,0xc8,0x9b,0xaa,0x84,0xb5,0xe6,0xd7,0x40,0x71,0x22,0x13,
44 0x7e,0x4f,0x1c,0x2d,0xba,0x8b,0xd8,0xe9,0xc7,0xf6,0xa5,0x94,0x03,0x32,0x61,0x50,
45 0xbb,0x8a,0xd9,0xe8,0x7f,0x4e,0x1d,0x2c,0x02,0x33,0x60,0x51,0xc6,0xf7,0xa4,0x95,
46 0xf8,0xc9,0x9a,0xab,0x3c,0x0d,0x5e,0x6f,0x41,0x70,0x23,0x12,0x85,0xb4,0xe7,0xd6,
47 0x7a,0x4b,0x18,0x29,0xbe,0x8f,0xdc,0xed,0xc3,0xf2,0xa1,0x90,0x07,0x36,0x65,0x54,
48 0x39,0x08,0x5b,0x6a,0xfd,0xcc,0x9f,0xae,0x80,0xb1,0xe2,0xd3,0x44,0x75,0x26,0x17,
49 0xfc,0xcd,0x9e,0xaf,0x38,0x09,0x5a,0x6b,0x45,0x74,0x27,0x16,0x81,0xb0,0xe3,0xd2,
50 0xbf,0x8e,0xdd,0xec,0x7b,0x4a,0x19,0x28,0x06,0x37,0x64,0x55,0xc2,0xf3,0xa0,0x91,
51 0x47,0x76,0x25,0x14,0x83,0xb2,0xe1,0xd0,0xfe,0xcf,0x9c,0xad,0x3a,0x0b,0x58,0x69,
52 0x04,0x35,0x66,0x57,0xc0,0xf1,0xa2,0x93,0xbd,0x8c,0xdf,0xee,0x79,0x48,0x1b,0x2a,
53 0xc1,0xf0,0xa3,0x92,0x05,0x34,0x67,0x56,0x78,0x49,0x1a,0x2b,0xbc,0x8d,0xde,0xef,
54 0x82,0xb3,0xe0,0xd1,0x46,0x77,0x24,0x15,0x3b,0x0a,0x59,0x68,0xff,0xce,0x9d,0xac
55};
56
57uint8_t fibo_crc_calc( uint8_t *datain,uint32_t datalen)
58{
59 uint8_t *input = (uint8_t*)datain;
60 uint8_t fcs = (uint8_t)0xFF;
61 int32_t i;
62 for (i = 0; i < (int32_t)datalen; i++)
63 fcs = crc_table[fcs ^ (uint8_t)input[i]];
64
65 return (uint8_t) (0xFF - fcs);
66
67}
68
69void int_handle(int signo)
70{
71 if(signo == SIGINT)
72 {
73 printf("recv signal\n");
74 exit(1);
75 }
76}
77
78int32_t com_Convbaud(uint32_t iBaudrate)
79{
80 switch(iBaudrate)
81 {
82 case 0:
83 return B0;
84 case 50:
85 return B50;
86 case 75:
87 return B75;
88 case 110:
89 return B110;
90 case 134:
91 return B134;
92 case 150:
93 return B150;
94 case 200:
95 return B200;
96 case 300:
97 return B300;
98 case 600:
99 return B600;
100 case 1200:
101 return B1200;
102 case 1800:
103 return B1800;
104 case 2400:
105 return B2400;
106 case 4800:
107 return B4800;
108 case 9600:
109 return B9600;
110 case 19200:
111 return B19200;
112 case 38400:
113 return B38400;
114 case 57600:
115 return B57600;
116 case 115200:
117 return B115200;
118 case 230400:
119 return B230400;
120 case 460800:
121 return B460800;
122 case 500000:
123 return B500000;
124 case 576000:
125 return B576000;
126 case 921600:
127 return B921600;
128 case 1000000:
129 return B1000000;
130 case 1152000:
131 return B1152000;
132 case 1500000:
133 return B1500000;
134 case 2000000:
135 return B2000000;
136 case 2500000:
137 return B2500000;
138 case 3000000:
139 return B3000000;
140 case 3500000:
141 return B3500000;
142 case 4000000:
143 return B4000000;
144 default:
145 return B115200;
146 }
147}
148
149static int com_SetBaud(int32_t iFdCom,int nSpeed)
150{
151 int ret = 0;
152 struct termios tOldTermios = {0};
153 int32_t iBaudrate = 0;
154 bzero(&tOldTermios, sizeof(tOldTermios));
155
156 ret = tcgetattr(iFdCom, &tOldTermios); // get the serial port attributions
157 if(ret)
158 {
159 printf("tcgetattr failed! \n");
160 }
161
162 iBaudrate = com_Convbaud(nSpeed);
163 if(iBaudrate == B115200 && nSpeed != 115200){
164 //got specil baud, not standerd
165 printf("the baud set is not standerd, please call other function to set \n");
166 return 1;
167 }
168 tcflush(iFdCom, TCIOFLUSH);
169 cfsetispeed(&tOldTermios, iBaudrate); //填入串口输入端波特率
170 cfsetospeed(&tOldTermios, iBaudrate); //填入串口输出端波特率
171 if(tcsetattr(iFdCom, TCSANOW, &tOldTermios) != 0) //设置新属性, TCSANOW: 所由改变立即生效
172 {
173 printf("Set vFnSetBaud error. iFd == %d\n", iFdCom);
174 return 1;
175 }
176 tcflush(iFdCom, TCIOFLUSH);
177
178 return 0;
179
180}
181
182static void com_SetnBit(int32_t iFdCom, int nBits)
183{
184 struct termios tOldTermios = {0};
185
186 bzero(&tOldTermios, sizeof(tOldTermios));
187
188 tcgetattr(iFdCom, &tOldTermios); // get the serial port attributions
189
190 switch( nBits )
191 {
192 case 7:
193 tOldTermios.c_cflag |= CS7;
194 break;
195 case 8:
196 default:
197 tOldTermios.c_cflag |= CS8;
198 break;
199 }
200
201 if(tcsetattr(iFdCom, TCSANOW, &tOldTermios) != 0) //设置新属性, TCSANOW: 所由改变立即生效
202 {
203 printf("Set vFnSetnBit error. iFd == %d\n", iFdCom);
204 return;
205 }
206 tcflush(iFdCom, TCIOFLUSH);
207
208}
209
210static void com_SetParity(int32_t iFdCom,char nEvent)
211{
212 struct termios tOldTermios = {0};
213
214 bzero(&tOldTermios, sizeof(tOldTermios));
215
216 tcgetattr(iFdCom, &tOldTermios); // get the serial port attributions
217 switch( nEvent )
218 {
219 case 'O': //奇校验
220 tOldTermios.c_cflag |= PARENB;
221 tOldTermios.c_cflag |= PARODD;
222 tOldTermios.c_iflag |= (INPCK | ISTRIP);
223 break;
224 case 'E': //偶校验
225 tOldTermios.c_iflag |= (INPCK | ISTRIP);
226 tOldTermios.c_cflag |= PARENB;
227 tOldTermios.c_cflag &= ~PARODD;
228 break;
229 case 'N': //无校验
230 default:
231 tOldTermios.c_cflag &= ~PARENB;
232 break;
233 }
234 if(tcsetattr(iFdCom, TCSANOW, &tOldTermios) != 0) //设置新属性, TCSANOW: 所由改变立即生效
235 {
236 printf("Set vFnSetParity error. iFd == %d\n", iFdCom);
237 return;
238 }
239 tcflush(iFdCom, TCIOFLUSH);
240
241}
242
243static void com_SetnStop(int32_t iFdCom, int nStop)
244{
245 struct termios tOldTermios = {0};
246
247 bzero(&tOldTermios, sizeof(tOldTermios));
248
249 tcgetattr(iFdCom, &tOldTermios); // get the serial port attributions
250
251
252 switch( nStop )
253 {
254 case 1:
255 tOldTermios.c_cflag &= ~CSTOPB;
256 break;
257 case 2:
258 tOldTermios.c_cflag |= CSTOPB;
259 break;
260 default:
261 tOldTermios.c_cflag &= ~CSTOPB;
262 break;
263 }
264 if(tcsetattr(iFdCom, TCSANOW, &tOldTermios) != 0) //设置新属性, TCSANOW: 所由改变立即生效
265 {
266 printf("Set vFnSetnStop error. iFd == %d\n", iFdCom);
267 return;
268 }
269 tcflush(iFdCom, TCIOFLUSH);
270
271}
272
273static void com_SetCtrl(int32_t iFdCom, int nCtrl)
274{
275 struct termios tOldTermios = {0};
276
277 bzero(&tOldTermios, sizeof(tOldTermios));
278
279 tcgetattr(iFdCom, &tOldTermios); // get the serial port attributions
280
281 switch(nCtrl)
282 {
283 case 0:
284 {
285 tOldTermios.c_cflag &= ~CRTSCTS; //no flow control
286 tOldTermios.c_iflag |= IGNBRK | IGNPAR;
287 }break;
288 case 1:
289 {
290 tOldTermios.c_cflag |= CRTSCTS; //hardware flow control
291 }break;
292 case 2:
293 {
294 tOldTermios.c_iflag |= IXON | IXOFF | IXANY; //software flow control
295 }break;
296 default:
297 break;
298 }
299
300 if(tcsetattr(iFdCom, TCSANOW, &tOldTermios) != 0) //设置新属性, TCSANOW: 所由改变立即生效
301 {
302 printf("Set vFnSetCtrl error. iFd == %d\n", iFdCom);
303 return;
304 }
305 tcflush(iFdCom, TCIOFLUSH);
306
307 //printf("Set vFnSetCtrl end\n");
308
309}
310
311
312static void com_SetTimeOut(int32_t iFdCom, int iTime)
313{
314 struct termios tOldTermios = {0};
315
316 bzero(&tOldTermios, sizeof(tOldTermios));
317
318 tcgetattr(iFdCom, &tOldTermios); // get the serial port attributions
319
320 tOldTermios.c_cc[VTIME] = iTime;
321 tOldTermios.c_cc[VMIN] = 0;
322
323 if(tcsetattr(iFdCom, TCSANOW, &tOldTermios) != 0) //设置新属性, TCSANOW: 所由改变立即生效
324 {
325 printf("Set TimeOut error. iFd == %d\n", iFdCom);
326 return;
327 }
328 tcflush(iFdCom, TCIOFLUSH);
329
330}
331
xf.li742dd022023-06-08 01:43:32 -0700332static void com_SetIO_Para(int32_t iFdCom)
333{
334 struct termios tOldTermios = {0};
335
336 bzero(&tOldTermios, sizeof(tOldTermios));
337 tcgetattr(iFdCom, &tOldTermios); // get the serial port attributions
338 tOldTermios.c_iflag &= ~(ICRNL | IXON);
339 tOldTermios.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ISIG);
340 tOldTermios.c_oflag &= ~OPOST;
341 if(tcsetattr(iFdCom, TCSANOW, &tOldTermios) != 0) //设置新属性, TCSANOW: 所由改变立即生效
342 {
343 printf("Set TimeOut error. iFd == %d\n", iFdCom);
344 return;
345 }
346 tcflush(iFdCom, TCIOFLUSH);
347 printf("com_SetIO_Para over.\n");
348}
349
xf.libdd93d52023-05-12 07:10:14 -0700350
351static int zUP_SetPort_0(int32_t iFd ,int ctsrts_en, int iBaud, int iDelay)
352{
353 com_SetBaud(iFd, iBaud);
354 com_SetnBit(iFd, 8);
355 com_SetParity(iFd, 'N');
356 //com_SetParity(iFd, 'O');
357 com_SetnStop(iFd,1);
358 com_SetCtrl(iFd,ctsrts_en); //add flow control
xf.li742dd022023-06-08 01:43:32 -0700359 com_SetIO_Para(iFd);
xf.libdd93d52023-05-12 07:10:14 -0700360 com_SetTimeOut(iFd,iDelay); //timeout 100ms
361
362 printf("set serial port done!\n");
363
364 return 0;
365}
366
367int block_select_one_time()
368{
369 int ret;
370 fd_set rfds;
371 FD_ZERO(&rfds);
372 FD_SET(uart_fd_0,&rfds);
373
374 ret = select(uart_fd_0+1,&rfds,NULL,NULL,NULL);
375 if(ret == -1)
376 {
377 printf("select error: -1");
378 return 0;
379 }
380 else
381 {
382 return 1;
383 }
384
385 return 1;
386}
387
388void check_one_time()
389{
390 uint8_t crc_board = 0;
391 if((dbuf[0] != 0xA5)||(dbuf[1] != 0x5A)||(dbuf[tlen-2] != 0xD5)||(dbuf[tlen-1] != 0x5D))
392 {
393 printf("head or tail error \n");
394 assert(0);
395 }
396
397 uint8_t* dbuf2 = NULL;
398 dbuf2 = (uint8_t*)malloc(2100000);
399 if(dbuf2 == NULL)
400 {
401 printf("malloc failed!\n");
402 exit(1);
403 }
404
405 memcpy(dbuf2, dbuf+2, tlen-5);
406
407 crc_board = fibo_crc_calc(dbuf2,tlen-5);
408 if(crc_board != dbuf[tlen-3])
409 {
410 printf("crc error, value is %d\n", crc_board);
411 assert(0);
412 }
413
414 printf("----------------------crc pass! value :%d----------------------\n", crc_board);
415
416 if(dbuf2 != NULL)
417 {
418 free(dbuf2);
419 dbuf2 = NULL;
420 }
421}
422
423
424int send_one_time()
425{
426 int len = 0;
427
428 len = write(uart_fd_0, &times, 4);
429 if(len <= 0)
430 {
431 printf("Ack write failed %s\n",strerror(errno));
432 return 0;
433 }
434
435 printf("Ack send success index :%d\n", times);
436 return 1;
437}
438
439
440int read_datas_tty()
441{
442 int recv_len = 0;
443 tlen = 0;
444
445 while(1)
446 {
447 recv_len = read(uart_fd_0, dbuf+tlen, ONE_LEN);
448 if(recv_len == 0)
449 {
450 printf("read end! please wait for this packet's handle\n");
451 break;
452 }
453 else if(recv_len < 0)
454 {
455 printf("read_datas_tty error %s\n",strerror(errno));
456 return 0;
457 }
458 else
459 {
460 tlen += recv_len;
461 }
462 }
463
464 printf("read last time len :%d total len :%d\n",recv_len, tlen);
465 //printf("0 is %#x, 1 is %#x, -3 is %#x, -2 is %#x, -1 is %#x\n",dbuf[0],dbuf[1],dbuf[tlen-3],dbuf[tlen-2],dbuf[tlen-1]);
466
467 return 1;
468}
469
470int main(int argc, char** argv)
471{
472 int ret0 = 0;
473 int baud = atoi(argv[1]);
474 int delay = atoi(argv[2]);
475 printf("crc main programe start...\n");
476
477 signal(SIGINT,int_handle);
478 uart_fd_0 = open("/dev/ttyS0",O_RDWR);
479
480 if(uart_fd_0 < 0)
481 {
482 printf("open uart dev failed :%s\n",strerror(errno));
483 return -1;
484 }
485
486 zUP_SetPort_0(uart_fd_0, 0, baud, delay);
487
488 memset(dbuf,0,2100000);
489 while(1)
490 {
491 ret0 = send_one_time();
492 if(!ret0)
493 {
494 break;
495 }
496
497 if(block_select_one_time())
498 {
499 ret0 = read_datas_tty();
500 if(ret0)
501 {
502 check_one_time();
503 times++;
504 }
505 else
506 {
507 printf("read_datas_tty failed\n");
508 break;
509 }
510 }
511 }
512
513 printf("crc main programe end...\n");
514 close(uart_fd_0);
515 return 1;
516}
517