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