blob: 8136259eaf6575ac697c3e195c96de3161b8d0b4 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/**
2 * ±¾³ÌÐò·ûºÏGPLÌõÔ¼
3 * Beneboy 2003-5-16
4 */
5#include <stdio.h> // printf
6#include <fcntl.h> // open
7#include <string.h> // bzero
8#include <stdlib.h> // exit
9#include <sys/times.h> // times
10#include <sys/types.h> // pid_t
11#include <termios.h> //termios, tcgetattr(), tcsetattr()
12#include <unistd.h>
13#include <sys/ioctl.h> // ioctl
14#include "port_com.h"
15#include "amt.h"
16
17// ½ÓÊÕ³¬Ê±
18#define TIMEOUT_SEC(buflen,baud) (buflen*20/baud+1)
19#define TIMEOUT_USEC 0
20
21// serial port information
22portinfo_t g_sPortInfo =
23{
24 '0', // print prompt after receiving
25 115200, // baudrate: 115200
26 '8', // databit: 8
27 '0', // debug: off
28 '0', // echo: off
29 '0', // flow control: software
30 '0', // default tty: COM1
31 '0', // parity: none
32 '1', // stopbit: 1
33 0 // reserved
34};
35
36/**
37 * ²¨ÌØÂÊת»¯×ª»»º¯Êý
38 */
39int convbaud(unsigned long int baudrate)
40{
41 switch (baudrate)
42 {
43 case 2400:
44 return B2400;
45 case 4800:
46 return B4800;
47 case 9600:
48 return B9600;
49 case 19200:
50 return B19200;
51 case 38400:
52 return B38400;
53 case 57600:
54 return B57600;
55 case 115200:
56 return B115200;
57 case 921600:
58 return B921600;
59 default:
60 return B9600;
61 }
62}
63
64/**
65 * Setup comm attr
66 * fd: ´®¿ÚÎļþÃèÊö·û, pportinfo: ´ýÉèÖõĶ˿ÚÐÅÏ¢s
67 *
68 */
69int PortSet(int fd)
70{
71 struct termios termios_old, termios_new;
72 int baudrate, tmp;
73 char databit, stopbit, parity, fctl;
74 bzero(&termios_old, sizeof(termios_old));
75 bzero(&termios_new, sizeof(termios_new));
76 cfmakeraw(&termios_new);
77 tcgetattr(fd, &termios_old); //get the serial port attributions
78 /*------------ÉèÖö˿ÚÊôÐÔ----------------*/
79 //baudrates
80 baudrate = convbaud(g_sPortInfo.baudrate);
81 cfsetispeed(&termios_new, baudrate); // ÌîÈë´®¿ÚÊäÈë¶Ë²¨ÌØÂÊ
82 cfsetospeed(&termios_new, baudrate); // ÌîÈë´®¿ÚÊä³ö¶Ë²¨ÌØÂÊ
83 termios_new.c_cflag |= CLOCAL; // ¿ØÖÆÄ£Ê½, ±£Ö¤³ÌÐò²»»á³ÉΪ¶Ë¿ÚµÄÕ¼ÓÐÕß
84 termios_new.c_cflag |= CREAD; // ¿ØÖÆÄ£Ê½, ʹÄܶ˿ڶÁÈ¡ÊäÈëµÄÊý¾Ý
85 // ¿ØÖÆÄ£Ê½, flow control
86 fctl = g_sPortInfo.fctl;
87 switch (fctl)
88 {
89 case '0':
90 {
91 termios_new.c_cflag &= ~CRTSCTS; //no flow control
92 }
93 break;
94 case '1':
95 {
96 termios_new.c_cflag |= CRTSCTS; //hardware flow control
97 }
98 break;
99 case '2':
100 {
101 termios_new.c_iflag |= IXON | IXOFF | IXANY; //software flow control
102 }
103 break;
104 default:
105 {
106 printf("Unknown fctl %c\n", fctl);
107 break;
108 }
109 }
110
111 // ¿ØÖÆÄ£Ê½, data bits
112 termios_new.c_cflag &= ~CSIZE; // ¿ØÖÆÄ£Ê½, ÆÁ±Î×Ö·û´óСλ
113 databit = g_sPortInfo.databit;
114 switch (databit)
115 {
116 case '5':
117 termios_new.c_cflag |= CS5;
118 //lint -fallthrough
119 case '6':
120 termios_new.c_cflag |= CS6;
121 //lint -fallthrough
122 case '7':
123 termios_new.c_cflag |= CS7;
124 //lint -fallthrough
125 default:
126 termios_new.c_cflag |= CS8;
127 }
128
129 // ¿ØÖÆÄ£Ê½ parity check
130 parity = g_sPortInfo.parity;
131 switch (parity)
132 {
133 case '0':
134 {
135 termios_new.c_cflag &= ~PARENB; // no parity check
136 }
137 break;
138 case '1':
139 {
140 termios_new.c_cflag |= PARENB; // odd check
141 termios_new.c_cflag &= ~PARODD;
142 }
143 break;
144 case '2':
145 {
146 termios_new.c_cflag |= PARENB; // even check
147 termios_new.c_cflag |= PARODD;
148 }
149 break;
150 default:
151 {
152 printf("Unknown parity %c\n", parity);
153 break;
154 }
155 }
156
157 // ¿ØÖÆÄ£Ê½, stop bits
158 stopbit = g_sPortInfo.stopbit;
159 if (stopbit == '2')
160 {
161 termios_new.c_cflag |= CSTOPB; // 2 stop bits
162 }
163 else
164 {
165 termios_new.c_cflag &= ~CSTOPB; // 1 stop bits
166 }
167
168 //other attributions default
169 termios_new.c_oflag &= ~OPOST; // Êä³öģʽ, ԭʼÊý¾ÝÊä³ö
170 termios_new.c_cc[VMIN] = 1; // ¿ØÖÆ×Ö·û, ËùÒª¶ÁÈ¡×Ö·ûµÄ×îСÊýÁ¿
171 termios_new.c_cc[VTIME] = 1; // ¿ØÖÆ×Ö·û, ¶ÁÈ¡µÚÒ»¸ö×Ö·ûµÄµÈ´ýʱ¼ä, unit: (1/10)second
172 tcflush(fd, TCIFLUSH); // Òç³öµÄÊý¾Ý¿ÉÒÔ½ÓÊÕ,µ«²»¶Á
173 tmp = tcsetattr(fd, TCSANOW, &termios_new); // ÉèÖÃÐÂÊôÐÔ, TCSANOW: ËùÓɸıäÁ¢¼´ÉúЧ
174 tcgetattr(fd, &termios_old);
175 return(tmp);
176}
177
178/**
179 * Open serial port
180 * tty: ¶Ë¿ÚºÅ ttyS0, ttyS1, ....
181 * ·µ»ØÖµÎª´®¿ÚÎļþÃèÊö·û
182 */
183int PortOpen(pportinfo_t pportinfo, int mode)
184{
185 UNUSED(pportinfo);
186 UNUSED(mode);
187
188 return 0;
189}
190
191/**
192 * Close serial port
193 */
194void PortClose(int fd)
195{
196 close(fd);
197}
198
199/**
200 * PortSend
201 * fd: ´®¿ÚÃèÊö·û,
202 * data: ´ý·¢ËÍÊý¾ÝÖ¸Õë
203 * datalen: Êý¾Ý³¤¶È
204 * flag: ·¢ËÍ·½Ê½±êʶ
205 * ·µ»ØÊµ¼Ê·¢Ëͳ¤¶È
206 */
207int PortSend(int fd, unsigned char* data, int datalen, int flag)
208{
209 int snRet = 0;
210
211 if (flag == WAIT_ALL)
212 {
213 int offset = 0;
214
215 while (offset < datalen)
216 {
217 snRet = write(fd, (data + offset), min(datalen - offset, 4096));
218 if (snRet > 0)
219 {
220 offset += snRet;
221 }
222 else
223 {
224 usleep(2*1000);
225 }
226 }
227
228 return offset;
229 }
230 else
231 {
232 snRet = write(fd, data, datalen);
233 return snRet;
234 }
235}
236
237/**
238 * PortRecv
239 * ²ÎÊý£º
240 * fd: ´®¿ÚÃèÊö·û,
241 * data: ´ý½ÓÊÕÊý¾ÝÖ¸Õë
242 * datalen: Êý¾Ý³¤¶È
243 * flag: ½ÓÊÕ·½Ê½±êʶ
244 * ·µ»ØÊµ¼Ê¶ÁÈëµÄ×Ö½ÚÊý
245 */
246int PortRecv(int fd, unsigned char* data, int datalen, int flag)
247{
248 int snRet = 0;
249
250 if (flag == WAIT_ALL)
251 {
252 int offset = 0;
253
254 while (offset < datalen)
255 {
256 snRet = read(fd, (data + offset), (datalen - offset));
257
258 if (snRet > 0)
259 {
260 offset += snRet;
261 }
262 else
263 {
264 return snRet;
265 }
266 }
267
268 return offset;
269 }
270 else
271 {
272 snRet = read(fd, data, datalen);
273 return snRet;
274 }
275}
276
277int uart_set(int fd)
278{
279 struct termios termios_old, termios_new;
280 int baudrate, tmp;
281 char databit, stopbit, parity, fctl;
282 portinfo_t uart_Info =
283 {
284 '0', // print prompt after receiving
285 921600, // baudrate: 921600
286 '8', // databit: 8
287 '0', // debug: off
288 '0', // echo: off
289 '0', // flow control: software
290 '0', // default tty: COM1
291 '0', // parity: none
292 '1', // stopbit: 1
293 0 // reserved
294 };
295 bzero(&termios_old, sizeof(termios_old));
296 bzero(&termios_new, sizeof(termios_new));
297 cfmakeraw(&termios_new);
298 tcgetattr(fd, &termios_old); //get the serial port attributions
299 /*------------ÉèÖö˿ÚÊôÐÔ----------------*/
300 //baudrates
301 baudrate = convbaud(uart_Info.baudrate);
302 cfsetispeed(&termios_new, baudrate); // ÌîÈë´®¿ÚÊäÈë¶Ë²¨ÌØÂÊ
303 cfsetospeed(&termios_new, baudrate); // ÌîÈë´®¿ÚÊä³ö¶Ë²¨ÌØÂÊ
304 termios_new.c_cflag |= CLOCAL; // ¿ØÖÆÄ£Ê½, ±£Ö¤³ÌÐò²»»á³ÉΪ¶Ë¿ÚµÄÕ¼ÓÐÕß
305 termios_new.c_cflag |= CREAD; // ¿ØÖÆÄ£Ê½, ʹÄܶ˿ڶÁÈ¡ÊäÈëµÄÊý¾Ý
306 // ¿ØÖÆÄ£Ê½, flow control
307 fctl = uart_Info.fctl;
308 switch (fctl)
309 {
310 case '0':
311 {
312 termios_new.c_cflag &= ~CRTSCTS; //no flow control
313 }
314 break;
315 case '1':
316 {
317 termios_new.c_cflag |= CRTSCTS; //hardware flow control
318 }
319 break;
320 case '2':
321 {
322 termios_new.c_iflag |= IXON | IXOFF | IXANY; //software flow control
323 }
324 break;
325 default:
326 {
327 printf("Unknown fctl %c\n", fctl);
328 break;
329 }
330 }
331
332 // ¿ØÖÆÄ£Ê½, data bits
333 termios_new.c_cflag &= ~CSIZE; // ¿ØÖÆÄ£Ê½, ÆÁ±Î×Ö·û´óСλ
334 databit = uart_Info.databit;
335 switch (databit)
336 {
337 case '5':
338 termios_new.c_cflag |= CS5;
339 //lint -fallthrough
340 case '6':
341 termios_new.c_cflag |= CS6;
342 //lint -fallthrough
343 case '7':
344 termios_new.c_cflag |= CS7;
345 //lint -fallthrough
346 default:
347 termios_new.c_cflag |= CS8;
348 }
349
350 // ¿ØÖÆÄ£Ê½ parity check
351 parity = uart_Info.parity;
352 switch (parity)
353 {
354 case '0':
355 {
356 termios_new.c_cflag &= ~PARENB; // no parity check
357 }
358 break;
359 case '1':
360 {
361 termios_new.c_cflag |= PARENB; // odd check
362 termios_new.c_cflag &= ~PARODD;
363 }
364 break;
365 case '2':
366 {
367 termios_new.c_cflag |= PARENB; // even check
368 termios_new.c_cflag |= PARODD;
369 }
370 break;
371 default:
372 {
373 printf("Unknown parity %c\n", parity);
374 break;
375 }
376 }
377
378 // ¿ØÖÆÄ£Ê½, stop bits
379 stopbit = uart_Info.stopbit;
380 if (stopbit == '2')
381 {
382 termios_new.c_cflag |= CSTOPB; // 2 stop bits
383 }
384 else
385 {
386 termios_new.c_cflag &= ~CSTOPB; // 1 stop bits
387 }
388
389 //other attributions default
390 termios_new.c_oflag &= ~OPOST; // Êä³öģʽ, ԭʼÊý¾ÝÊä³ö
391 termios_new.c_cc[VMIN] = 1; // ¿ØÖÆ×Ö·û, ËùÒª¶ÁÈ¡×Ö·ûµÄ×îСÊýÁ¿
392 termios_new.c_cc[VTIME] = 1; // ¿ØÖÆ×Ö·û, ¶ÁÈ¡µÚÒ»¸ö×Ö·ûµÄµÈ´ýʱ¼ä, unit: (1/10)second
393 tcflush(fd, TCIFLUSH); // Òç³öµÄÊý¾Ý¿ÉÒÔ½ÓÊÕ,µ«²»¶Á
394 tmp = tcsetattr(fd, TCSANOW, &termios_new); // ÉèÖÃÐÂÊôÐÔ, TCSANOW: ËùÓɸıäÁ¢¼´ÉúЧ
395 tcgetattr(fd, &termios_old);
396 return(tmp);
397
398}
399
400
401