blob: ca6f779c4094a8113ba6664d542f7064bcf7a89b [file] [log] [blame]
b.liu1c74d692024-08-14 17:43:59 +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
11#include "mbtk_log.h"
12#include "ql/ql_uart.h"
13
14int Ql_UART_Open(const char* port, Enum_BaudRate baudrate, Enum_FlowCtrl flowctrl)
15{
16 int fd;
17 if((fd = open(port, O_RDWR | O_NOCTTY)) < 0)
18 {
19 LOGE("open %s failed - %d", port, errno);
20 return -1;
21 }
22
23 LOGD("Open %s success.", port);
24
25 /* set newtio */
26 struct termios newtio;
27 memset(&newtio, 0, sizeof(newtio));
28 if (tcflush(fd, TCIOFLUSH) < 0) {
29 LOGE("Could not flush uart port");
30 return -1;
31 }
32
33 newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
34 newtio.c_cc[VMIN] = 0; /* blocking read until 5 chars received */
35
36 if(flowctrl == FC_RTSCTS) {
37 newtio.c_cflag |= CRTSCTS;
38 } else if(flowctrl == FC_XONXOFF) {
39 newtio.c_cflag |= (IXON | IXOFF);
40 } else {
41 // newtio.c_cflag |= CRTSCTS;
42 }
43 /* c_iflag 输入模式 */
44 newtio.c_iflag &= ~(ICRNL | INLCR);
45 newtio.c_iflag &= ~(IXON | IXOFF | IXANY);
46
47 // /* c_lflag 本地模式 */
48 newtio.c_cflag &= ~ INPCK;
49 newtio.c_cflag |= (CLOCAL | CREAD);
50
51 // /* c_lflag 本地模式 */
52 newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
53 /* c_oflag 输出模式 */
54 newtio.c_oflag &= ~ OPOST;
55 newtio.c_oflag &= ~(ONLCR | OCRNL);
56
57 /* c_cflag 控制模式 */
58 newtio.c_cflag &= ~ CSIZE;
59 newtio.c_cflag |= CS8;
60 newtio.c_cflag &= ~ CSTOPB;
61 newtio.c_cflag &= ~ PARENB;
62
63 switch(baudrate)
64 {
65 case B_300:
66 cfsetospeed(&newtio, B300);
67 cfsetispeed(&newtio, B300);
68 break;
69 case B_600:
70 cfsetospeed(&newtio, B600);
71 cfsetispeed(&newtio, B600);
72 break;
73 case B_1200:
74 cfsetospeed(&newtio, B1200);
75 cfsetispeed(&newtio, B1200);
76 break;
77 case B_2400:
78 cfsetospeed(&newtio, B2400);
79 cfsetispeed(&newtio, B2400);
80 break;
81 case B_4800:
82 cfsetospeed(&newtio, B4800);
83 cfsetispeed(&newtio, B4800);
84 break;
85 case B_9600:
86 cfsetospeed(&newtio, B9600);
87 cfsetispeed(&newtio, B9600);
88 break;
89 case B_19200:
90 cfsetospeed(&newtio, B19200);
91 cfsetispeed(&newtio, B19200);
92 break;
93 case B_38400:
94 cfsetospeed(&newtio, B38400);
95 cfsetispeed(&newtio, B38400);
96 break;
97 case B_57600:
98 cfsetospeed(&newtio, B57600);
99 cfsetispeed(&newtio, B57600);
100 break;
101 case B_115200:
102 cfsetospeed(&newtio, B115200);
103 cfsetispeed(&newtio, B115200);
104 break;
105 case B_230400:
106 cfsetospeed(&newtio, B230400);
107 cfsetispeed(&newtio, B230400);
108 break;
109 case B_460800:
110 cfsetospeed(&newtio, B460800);
111 cfsetispeed(&newtio, B460800);
112 break;
113 case B_921600:
114 cfsetospeed(&newtio, B921600);
115 cfsetispeed(&newtio, B921600);
116 break;
117 case B_3000000:
118 cfsetospeed(&newtio, B3000000);
119 cfsetispeed(&newtio, B3000000);
120 break;
121 case B_4000000:
122 cfsetospeed(&newtio, B4000000);
123 cfsetispeed(&newtio, B4000000);
124 break;
125 default:
126 cfsetospeed(&newtio, B115200);
127 cfsetispeed(&newtio, B115200);
128 break;
129 }
130
131 if (tcsetattr(fd, TCSANOW, &newtio) < 0) {
132 LOGE("Can't set port setting");
133 return -1;
134 }
135 /* Blocking behavior */
136 fcntl(fd, F_SETFL, 0);
137
138 return fd;
139}
140
141int Ql_UART_Read(int fd, char* buf, unsigned int buf_len)
142{
143 return read(fd, buf, buf_len);
144}
145
146
147int Ql_UART_Write(int fd, const char* buf, unsigned int buf_len)
148{
149 return write(fd, buf, buf_len);
150}
151
152
153int Ql_UART_SetDCB(int fd, ST_UARTDCB *dcb)
154{
155 struct termios newtio;
156 memset(&newtio, 0, sizeof(newtio));
157
158 if(tcgetattr(fd, &newtio) != 0)
159 {
160 LOGE("Serial port configuration backup errno");
161 return -1;
162 }
163
164 switch(dcb->baudrate)
165 {
166 case B_300:
167 cfsetospeed(&newtio, B300);
168 cfsetispeed(&newtio, B300);
169 break;
170 case B_600:
171 cfsetospeed(&newtio, B600);
172 cfsetispeed(&newtio, B600);
173 break;
174 case B_1200:
175 cfsetospeed(&newtio, B1200);
176 cfsetispeed(&newtio, B1200);
177 break;
178 case B_2400:
179 cfsetospeed(&newtio, B2400);
180 cfsetispeed(&newtio, B2400);
181 break;
182 case B_4800:
183 cfsetospeed(&newtio, B4800);
184 cfsetispeed(&newtio, B4800);
185 break;
186 case B_9600:
187 cfsetospeed(&newtio, B9600);
188 cfsetispeed(&newtio, B9600);
189 break;
190 case B_19200:
191 cfsetospeed(&newtio, B19200);
192 cfsetispeed(&newtio, B19200);
193 break;
194 case B_38400:
195 cfsetospeed(&newtio, B38400);
196 cfsetispeed(&newtio, B38400);
197 break;
198 case B_57600:
199 cfsetospeed(&newtio, B57600);
200 cfsetispeed(&newtio, B57600);
201 break;
202 case B_115200:
203 cfsetospeed(&newtio, B115200);
204 cfsetispeed(&newtio, B115200);
205 break;
206 case B_230400:
207 cfsetospeed(&newtio, B230400);
208 cfsetispeed(&newtio, B230400);
209 break;
210 case B_460800:
211 cfsetospeed(&newtio, B460800);
212 cfsetispeed(&newtio, B460800);
213 break;
214 case B_921600:
215 cfsetospeed(&newtio, B921600);
216 cfsetispeed(&newtio, B921600);
217 break;
218 case B_3000000:
219 cfsetospeed(&newtio, B3000000);
220 cfsetispeed(&newtio, B3000000);
221 break;
222 case B_4000000:
223 cfsetospeed(&newtio, B4000000);
224 cfsetispeed(&newtio, B4000000);
225 break;
226 default:
227 LOGD("No set speed.");
228 break;
229 }
230
231 switch(dcb->databit)
232 {
233 case DB_CS5:
234 newtio.c_cflag &= ~CSIZE;
235 newtio.c_cflag |= CS5;
236 break;
237 case DB_CS6:
238 newtio.c_cflag &= ~CSIZE;
239 newtio.c_cflag |= CS6;
240 break;
241 case DB_CS7:
242 newtio.c_cflag &= ~CSIZE;
243 newtio.c_cflag |= CS7;
244 break;
245 case DB_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(dcb->stopbit == SB_2) {
255 newtio.c_cflag |= CSTOPB;
256 } else {
257 newtio.c_cflag &= ~CSTOPB;
258 }
259
260 switch (dcb->parity)
261 {
262 case PB_ODD:// 奇校验
263 newtio.c_cflag |= PARENB;
264 newtio.c_cflag |= PARODD;
265 break;
266 case PB_EVEN:// 偶校验
267 newtio.c_cflag |= PARENB;
268 newtio.c_cflag &= ~PARODD;
269 break;
270 case PB_NONE:// 无奇偶校验
271 newtio.c_cflag &= ~PARENB;
272 break;
273 default:
274 LOGD("No set parity.");
275 break;
276 }
277
278 switch (dcb->flowctrl)
279 {
280 case FC_RTSCTS:
281 newtio.c_cflag |= CRTSCTS;
282 tcflush(fd, TCIFLUSH);
283 break;
284 case FC_XONXOFF:
285 newtio.c_iflag |= (IXON | IXOFF);
286 tcflush(fd, TCIFLUSH);
287 break;
288 case FC_NONE:
289 newtio.c_cflag &= ~CRTSCTS;
290 newtio.c_iflag &= ~(IXON | IXOFF);
291 tcflush(fd, TCIFLUSH);
292 break;
293 default:
294 LOGD("No set flow ctrl.");
295 break;
296 }
297
298 if(tcsetattr(fd, TCSANOW, &newtio) != 0)
299 {
300 LOGE("Serial port configuration backup errno");
301 return -1;
302 }
303
304 return 0;
305}
306
307
308int Ql_UART_GetDCB(int fd, ST_UARTDCB *dcb)
309{
310 struct termios newtio;
311 memset(&newtio, 0, sizeof(newtio));
312
313 if(tcgetattr(fd, &newtio) != 0)
314 {
315 LOGE("Serial port configuration backup errno");
316 return -1;
317 }
318
319 switch(cfgetispeed(&newtio))
320 {
321 case B300:
322 dcb->baudrate = B_300;
323 break;
324 case B600:
325 dcb->baudrate = B_600;
326 break;
327 case B1200:
328 dcb->baudrate = B_1200;
329 break;
330 case B2400:
331 dcb->baudrate = B_2400;
332 break;
333 case B4800:
334 dcb->baudrate = B_4800;
335 break;
336 case B9600:
337 dcb->baudrate = B_9600;
338 break;
339 case B19200:
340 dcb->baudrate = B_19200;
341 break;
342 case B38400:
343 dcb->baudrate = B_38400;
344 break;
345 case B57600:
346 dcb->baudrate = B_57600;
347 break;
348 case B115200:
349 dcb->baudrate = B_115200;
350 break;
351 case B230400:
352 dcb->baudrate = B_230400;
353 break;
354 case B460800:
355 dcb->baudrate = B_460800;
356 break;
357 case B921600:
358 dcb->baudrate = B_921600;
359 break;
360 case B3000000:
361 dcb->baudrate = B_3000000;
362 break;
363 case B4000000:
364 dcb->baudrate = B_4000000;
365 break;
366 default:
367 dcb->baudrate = B_115200;
368 break;
369 }
370
371 switch(newtio.c_cflag & CSIZE)
372 {
373 case CS5:
374 dcb->databit = DB_CS5;
375 break;
376 case CS6:
377 dcb->databit = DB_CS6;
378 break;
379 case CS7:
380 dcb->databit = DB_CS7;
381 break;
382 case CS8:
383 dcb->databit = DB_CS8;
384 break;
385 default:
386 dcb->databit = DB_CS8;
387 break;
388 }
389
390 if(newtio.c_cflag & CSTOPB) {
391 dcb->stopbit = SB_2;
392 } else {
393 dcb->stopbit = SB_1;
394 }
395
396 if(newtio.c_cflag & PARENB) { // 启用了奇偶校验
397 if(newtio.c_cflag & PARODD) {
398 dcb->parity = PB_ODD; // 奇校验
399 } else {
400 dcb->parity = PB_EVEN; // 偶校验
401 }
402 } else {
403 dcb->parity = PB_NONE;
404 }
405
406 if(newtio.c_cflag & CRTSCTS) {
407 dcb->flowctrl = FC_RTSCTS;
408 } else if(newtio.c_iflag & (IXON | IXOFF) == (IXON | IXOFF)){
409 dcb->flowctrl = FC_XONXOFF;
410 } else {
411 dcb->flowctrl = FC_NONE;
412 }
413
414 return 0;
415}
416
417
418int Ql_UART_IoCtl(int fd, unsigned int cmd, void* pValue)
419{
420 return 0;
421}
422
423
424int Ql_UART_Close(int fd)
425{
426 if (fd <= 0)
427 return -1;
428
429 close(fd);
430 return 0;
431}
432