]> sigrok.org Git - libsigrok.git/blob - hardware/common/serial.c
serial: Initial code for setting DTR/RTS.
[libsigrok.git] / hardware / common / serial.c
1 /*
2  * This file is part of the sigrok project.
3  *
4  * Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.com>
5  * Copyright (C) 2010-2012 Uwe Hermann <uwe@hermann-uwe.de>
6  * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <string.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <unistd.h>
27 #ifdef _WIN32
28 #include <windows.h>
29 #else
30 #include <glob.h>
31 #include <termios.h>
32 #endif
33 #include <stdlib.h>
34 #include <errno.h>
35 #include <sys/ioctl.h>
36 #include <glib.h>
37 #include "libsigrok.h"
38 #include "libsigrok-internal.h"
39
40 /* Message logging helpers with driver-specific prefix string. */
41 #define DRIVER_LOG_DOMAIN "serial: "
42 #define sr_log(l, s, args...) sr_log(l, DRIVER_LOG_DOMAIN s, ## args)
43 #define sr_spew(s, args...) sr_spew(DRIVER_LOG_DOMAIN s, ## args)
44 #define sr_dbg(s, args...) sr_dbg(DRIVER_LOG_DOMAIN s, ## args)
45 #define sr_info(s, args...) sr_info(DRIVER_LOG_DOMAIN s, ## args)
46 #define sr_warn(s, args...) sr_warn(DRIVER_LOG_DOMAIN s, ## args)
47 #define sr_err(s, args...) sr_err(DRIVER_LOG_DOMAIN s, ## args)
48
49 // FIXME: Must be moved, or rather passed as function argument.
50 #ifdef _WIN32
51 static HANDLE hdl;
52 #endif
53
54 /**
55  * Open the specified serial port.
56  *
57  * @param serial Previously initialized serial port structure.
58  * @param flags Flags to use when opening the serial port.
59  * TODO: Abstract 'flags', currently they're OS-specific!
60  *
61  * If the serial structure contains a serialcomm string, it will be
62  * passed to serial_set_paramstr() after the port is opened.
63  *
64  * @return SR_OK on success, SR_ERR on failure.
65  */
66 SR_PRIV int serial_open(struct sr_serial_dev_inst *serial, int flags)
67 {
68
69         if (!serial) {
70                 sr_dbg("Invalid serial port.");
71                 return SR_ERR;
72         }
73
74         sr_spew("Opening serial port '%s' (flags %d).", serial->port, flags);
75
76 #ifdef _WIN32
77         hdl = CreateFile(serial->port, GENERIC_READ | GENERIC_WRITE, 0, 0,
78                          OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
79         if (hdl == INVALID_HANDLE_VALUE) {
80                 sr_err("Error opening serial port '%s'.", serial->port);
81                 return SR_ERR;
82         }
83 #else
84         if ((serial->fd = open(serial->port, flags)) < 0) {
85                 sr_err("Error opening serial port '%s': %s.", serial->port,
86                        strerror(errno));
87                 return SR_ERR;
88         } else
89                 sr_spew("Opened serial port '%s' (fd %d).", serial->port, serial->fd);
90 #endif
91
92         if (serial->serialcomm)
93                 return serial_set_paramstr(serial, serial->serialcomm);
94         else
95                 return SR_OK;
96 }
97
98 /**
99  * Close the specified serial port.
100  *
101  * @param serial Previously initialized serial port structure.
102  *
103  * @return SR_OK on success, SR_ERR on failure.
104  */
105 SR_PRIV int serial_close(struct sr_serial_dev_inst *serial)
106 {
107         int ret;
108
109         if (!serial) {
110                 sr_dbg("Invalid serial port.");
111                 return SR_ERR;
112         }
113
114         if (serial->fd == -1) {
115                 sr_dbg("Cannot close unopened serial port %s (fd %d).",
116                                 serial->port, serial->fd);
117                 return SR_ERR;
118         }
119
120         sr_spew("Closing serial port %s (fd %d).", serial->port, serial->fd);
121         ret = SR_OK;
122
123 #ifdef _WIN32
124         /* Returns non-zero upon success, 0 upon failure. */
125         if (CloseHandle(hdl) == 0)
126                 ret = SR_ERR;
127 #else
128         /* Returns 0 upon success, -1 upon failure. */
129         if (close(serial->fd) < 0) {
130                 sr_err("Error closing serial port: %s (fd %d).", strerror(errno),
131                                 serial->fd);
132                 ret = SR_ERR;
133         }
134 #endif
135
136         serial->fd = -1;
137
138         return ret;
139 }
140
141 /**
142  * Flush serial port buffers.
143  *
144  * @param serial Previously initialized serial port structure.
145  *
146  * @return SR_OK on success, SR_ERR on failure.
147  */
148 SR_PRIV int serial_flush(struct sr_serial_dev_inst *serial)
149 {
150         int ret;
151
152         if (!serial) {
153                 sr_dbg("Invalid serial port.");
154                 return SR_ERR;
155         }
156
157         if (serial->fd == -1) {
158                 sr_dbg("Cannot flush unopened serial port %s (fd %d).",
159                                 serial->port, serial->fd);
160                 return SR_ERR;
161         }
162
163         sr_spew("Flushing serial port %s (fd %d).", serial->port, serial->fd);
164         ret = SR_OK;
165
166 #ifdef _WIN32
167         /* Returns non-zero upon success, 0 upon failure. */
168         if (PurgeComm(hdl, PURGE_RXCLEAR | PURGE_TXCLEAR) == 0) {
169                 sr_err("Error flushing serial port: %s.", strerror(errno));
170                 ret = SR_ERR;
171         }
172 #else
173         /* Returns 0 upon success, -1 upon failure. */
174         if (tcflush(serial->fd, TCIOFLUSH) < 0) {
175                 sr_err("Error flushing serial port: %s.", strerror(errno));
176                 ret = SR_ERR;
177         }
178
179         return ret;
180 #endif
181 }
182
183 /**
184  * Write a number of bytes to the specified serial port.
185  *
186  * @param serial Previously initialized serial port structure.
187  * @param buf Buffer containing the bytes to write.
188  * @param count Number of bytes to write.
189  *
190  * @return The number of bytes written, or -1 upon failure.
191  */
192 SR_PRIV int serial_write(struct sr_serial_dev_inst *serial,
193                 const void *buf, size_t count)
194 {
195         ssize_t ret;
196
197         if (!serial) {
198                 sr_dbg("Invalid serial port.");
199                 return -1;
200         }
201
202         if (serial->fd == -1) {
203                 sr_dbg("Cannot use unopened serial port %s (fd %d).",
204                                 serial->port, serial->fd);
205                 return -1;
206         }
207
208 #ifdef _WIN32
209         DWORD tmp = 0;
210
211         /* FIXME */
212         /* Returns non-zero upon success, 0 upon failure. */
213         WriteFile(hdl, buf, count, &tmp, NULL);
214 #else
215         /* Returns the number of bytes written, or -1 upon failure. */
216         ret = write(serial->fd, buf, count);
217         if (ret < 0)
218                 sr_err("Write error: %s.", strerror(errno));
219         else
220                 sr_spew("Wrote %d/%d bytes (fd %d).", ret, count, serial->fd);
221 #endif
222
223         return ret;
224 }
225
226 /**
227  * Read a number of bytes from the specified serial port.
228  *
229  * @param serial Previously initialized serial port structure.
230  * @param buf Buffer where to store the bytes that are read.
231  * @param count The number of bytes to read.
232  *
233  * @return The number of bytes read, or -1 upon failure.
234  */
235 SR_PRIV int serial_read(struct sr_serial_dev_inst *serial, void *buf,
236                 size_t count)
237 {
238         ssize_t ret;
239
240         if (!serial) {
241                 sr_dbg("Invalid serial port.");
242                 return -1;
243         }
244
245         if (serial->fd == -1) {
246                 sr_dbg("Cannot use unopened serial port %s (fd %d).",
247                                 serial->port, serial->fd);
248                 return -1;
249         }
250
251 #ifdef _WIN32
252         DWORD tmp = 0;
253
254         /* FIXME */
255         /* Returns non-zero upon success, 0 upon failure. */
256         return ReadFile(hdl, buf, count, &tmp, NULL);
257 #else
258         /* Returns the number of bytes read, or -1 upon failure. */
259         ret = read(serial->fd, buf, count);
260         if (ret < 0)
261                 /*
262                  * Should be sr_err(), but that would yield lots of
263                  * "Resource temporarily unavailable" messages.
264                  */
265                 sr_spew("Read error: %s (fd %d).", strerror(errno), serial->fd);
266         else
267                 sr_spew("Read %d/%d bytes (fd %d).", ret, count, serial->fd);
268 #endif
269
270         return ret;
271 }
272
273 /**
274  * Set serial parameters for the specified serial port.
275  *
276  * @param serial Previously initialized serial port structure.
277  * @param baudrate The baudrate to set.
278  * @param bits The number of data bits to use.
279  * @param parity The parity setting to use (0 = none, 1 = even, 2 = odd).
280  * @param stopbits The number of stop bits to use (1 or 2).
281  * @param flowcontrol The flow control settings to use (0 = none, 1 = RTS/CTS,
282  *                    2 = XON/XOFF).
283  *
284  * @return SR_OK upon success, SR_ERR upon failure.
285  */
286 SR_PRIV int serial_set_params(struct sr_serial_dev_inst *serial, int baudrate,
287                 int bits, int parity, int stopbits, int flowcontrol)
288 {
289         if (!serial) {
290                 sr_dbg("Invalid serial port.");
291                 return SR_ERR;
292         }
293
294         if (serial->fd == -1) {
295                 sr_dbg("Cannot configure unopened serial port %s (fd %d).",
296                                 serial->port, serial->fd);
297                 return SR_ERR;
298         }
299
300         sr_spew("Setting serial parameters on port %s (fd %d).", serial->port,
301                         serial->fd);
302
303 #ifdef _WIN32
304         DCB dcb;
305
306         if (!GetCommState(hdl, &dcb))
307                 return SR_ERR;
308
309         switch (baudrate) {
310         case 115200:
311                 dcb.BaudRate = CBR_115200;
312                 break;
313         case 57600:
314                 dcb.BaudRate = CBR_57600;
315                 break;
316         case 38400:
317                 dcb.BaudRate = CBR_38400;
318                 break;
319         case 19200:
320                 dcb.BaudRate = CBR_19200;
321                 break;
322         case 9600:
323                 dcb.BaudRate = CBR_9600;
324                 break;
325         case 4800:
326                 dcb.BaudRate = CBR_4800;
327                 break;
328         case 2400:
329                 dcb.BaudRate = CBR_2400;
330                 break;
331         default:
332                 sr_err("Unsupported baudrate %d.", baudrate);
333                 return SR_ERR;
334         }
335         dcb.ByteSize = bits;
336         dcb.Parity = NOPARITY; /* TODO: Don't hardcode. */
337         dcb.StopBits = ONESTOPBIT; /* TODO: Don't hardcode. */
338
339         if (!SetCommState(hdl, &dcb))
340                 return SR_ERR;
341 #else
342         struct termios term;
343         speed_t baud;
344         int ret, controlbits;
345
346         if (tcgetattr(serial->fd, &term) < 0) {
347                 sr_err("tcgetattr() error on port %s (fd %d): %s.",
348                                 serial->port, serial->fd, strerror(errno));
349                 return SR_ERR;
350         }
351
352         switch (baudrate) {
353         case 50:
354                 baud = B50;
355                 break;
356         case 75:
357                 baud = B75;
358                 break;
359         case 110:
360                 baud = B110;
361                 break;
362         case 134:
363                 baud = B134;
364                 break;
365         case 150:
366                 baud = B150;
367                 break;
368         case 200:
369                 baud = B200;
370                 break;
371         case 300:
372                 baud = B300;
373                 break;
374         case 600:
375                 baud = B600;
376                 break;
377         case 1200:
378                 baud = B1200;
379                 break;
380         case 1800:
381                 baud = B1800;
382                 break;
383         case 2400:
384                 baud = B2400;
385                 break;
386         case 4800:
387                 baud = B4800;
388                 break;
389         case 9600:
390                 baud = B9600;
391                 break;
392         case 19200:
393                 baud = B19200;
394                 break;
395         case 38400:
396                 baud = B38400;
397                 break;
398         case 57600:
399                 baud = B57600;
400                 break;
401         case 115200:
402                 baud = B115200;
403                 break;
404         case 230400:
405                 baud = B230400;
406                 break;
407 #ifndef __APPLE__
408         case 460800:
409                 baud = B460800;
410                 break;
411 #endif
412         default:
413                 sr_err("Unsupported baudrate %d.", baudrate);
414                 return SR_ERR;
415         }
416
417         sr_spew("Configuring output baudrate to %d (%d).", baudrate, baud);
418         if (cfsetospeed(&term, baud) < 0) {
419                 sr_err("cfsetospeed() error: %s.", strerror(errno));
420                 return SR_ERR;
421         }
422
423         sr_spew("Configuring input baudrate to %d (%d).", baudrate, baud);
424         if (cfsetispeed(&term, baud) < 0) {
425                 sr_err("cfsetispeed() error: %s.", strerror(errno));
426                 return SR_ERR;
427         }
428
429         sr_spew("Configuring %d data bits.", bits);
430         term.c_cflag &= ~CSIZE;
431         switch (bits) {
432         case 8:
433                 term.c_cflag |= CS8;
434                 break;
435         case 7:
436                 term.c_cflag |= CS7;
437                 break;
438         default:
439                 sr_err("Unsupported data bits number %d.", bits);
440                 return SR_ERR;
441         }
442
443         sr_spew("Configuring %d stop bits.", stopbits);
444         term.c_cflag &= ~CSTOPB;
445         switch (stopbits) {
446         case 1:
447                 term.c_cflag &= ~CSTOPB;
448                 break;
449         case 2:
450                 term.c_cflag |= CSTOPB;
451                 break;
452         default:
453                 sr_err("Unsupported stopbits number %d.", stopbits);
454                 return SR_ERR;
455         }
456
457         term.c_iflag &= ~(IXON | IXOFF);
458         term.c_cflag &= ~CRTSCTS;
459         switch (flowcontrol) {
460         case 0:
461                 /* No flow control. */
462                 sr_spew("Configuring no flow control.");
463                 break;
464         case 1:
465                 sr_spew("Configuring RTS/CTS flow control.");
466                 term.c_cflag |= CRTSCTS;
467                 break;
468         case 2:
469                 sr_spew("Configuring XON/XOFF flow control.");
470                 term.c_iflag |= IXON | IXOFF;
471                 break;
472         default:
473                 sr_err("Unsupported flow control setting %d.", flowcontrol);
474                 return SR_ERR;
475         }
476
477         term.c_iflag &= ~IGNPAR;
478         term.c_cflag &= ~(PARODD | PARENB);
479         switch (parity) {
480         case SERIAL_PARITY_NONE:
481                 sr_spew("Configuring no parity.");
482                 term.c_iflag |= IGNPAR;
483                 break;
484         case SERIAL_PARITY_EVEN:
485                 sr_spew("Configuring even parity.");
486                 term.c_cflag |= PARENB;
487                 break;
488         case SERIAL_PARITY_ODD:
489                 sr_spew("Configuring odd parity.");
490                 term.c_cflag |= PARENB | PARODD;
491                 break;
492         default:
493                 sr_err("Unsupported parity setting %d.", parity);
494                 return SR_ERR;
495         }
496
497         /* Do not translate carriage return to newline on input. */
498         term.c_iflag &= ~(ICRNL);
499
500         /* Disable canonical mode, and don't echo input characters. */
501         term.c_lflag &= ~(ICANON | ECHO);
502
503         /* Write the configured settings. */
504         if (tcsetattr(serial->fd, TCSADRAIN, &term) < 0) {
505                 sr_err("tcsetattr() error: %s.", strerror(errno));
506                 return SR_ERR;
507         }
508
509 #if 0
510         /* TODO: Make configurable via driver options. */
511
512         sr_spew("Configuring RTS to 1/high.");
513         controlbits = TIOCM_RTS;
514         if ((ret = ioctl(serial->fd, TIOCMBIC, &controlbits)) < 0) {
515                 sr_err("Error setting RTS to 1: %s.", strerror(errno));
516                 return SR_ERR;
517         }
518
519         sr_spew("Configuring DTR to 0/low.");
520         controlbits = TIOCM_DTR;
521         if ((ret = ioctl(serial->fd, TIOCMBIS, &controlbits)) < 0) {
522                 sr_err("Error setting DTR to 0: %s.", strerror(errno));
523                 return SR_ERR;
524         }
525 #endif
526
527 #endif
528
529         return SR_OK;
530 }
531
532 /**
533  * Set serial parameters for the specified serial port.
534  *
535  * @param serial Previously initialized serial port structure.
536  * @param paramstr A serial communication parameters string, in the form
537  * of <speed>/<data bits><parity><stopbits>, for example "9600/8n1" or
538  * "600/7o2".
539  *
540  * @return SR_OK upon success, SR_ERR upon failure.
541  */
542 #define SERIAL_COMM_SPEC "^(\\d+)/([78])([neo])([12])$"
543 SR_PRIV int serial_set_paramstr(struct sr_serial_dev_inst *serial,
544                 const char *paramstr)
545 {
546         GRegex *reg;
547         GMatchInfo *match;
548         int speed, databits, parity, stopbits;
549         char *mstr;
550
551         speed = databits = parity = stopbits = 0;
552         reg = g_regex_new(SERIAL_COMM_SPEC, 0, 0, NULL);
553         if (g_regex_match(reg, paramstr, 0, &match)) {
554                 if ((mstr = g_match_info_fetch(match, 1)))
555                         speed = strtoul(mstr, NULL, 10);
556                 g_free(mstr);
557                 if ((mstr = g_match_info_fetch(match, 2)))
558                         databits = strtoul(mstr, NULL, 10);
559                 g_free(mstr);
560                 if ((mstr = g_match_info_fetch(match, 3))) {
561                         switch (mstr[0]) {
562                         case 'n':
563                                 parity = SERIAL_PARITY_NONE;
564                                 break;
565                         case 'e':
566                                 parity = SERIAL_PARITY_EVEN;
567                                 break;
568                         case 'o':
569                                 parity = SERIAL_PARITY_ODD;
570                                 break;
571                         }
572                 }
573                 g_free(mstr);
574                 if ((mstr = g_match_info_fetch(match, 4)))
575                         stopbits = strtoul(mstr, NULL, 10);
576                 g_free(mstr);
577         }
578         g_match_info_unref(match);
579         g_regex_unref(reg);
580
581         if (speed)
582                 return serial_set_params(serial, speed, databits, parity, stopbits, 0);
583         else
584                 return SR_ERR_ARG;
585 }
586
587 /**
588  * Read a line from the specified serial port.
589  *
590  * @param serial Previously initialized serial port structure.
591  * @param buf Buffer where to store the bytes that are read.
592  * @param buflen Size of the buffer.
593  * @param timeout_ms How long to wait for a line to come in.
594  *
595  * Reading stops when CR of LR is found, which is stripped from the buffer.
596  *
597  * @return SR_OK on success, SR_ERR on failure.
598  */
599 SR_PRIV int serial_readline(struct sr_serial_dev_inst *serial, char **buf,
600                 int *buflen, gint64 timeout_ms)
601 {
602         gint64 start;
603         int maxlen, len;
604
605         if (!serial || serial->fd == -1) {
606                 sr_dbg("Invalid serial port.");
607                 return SR_ERR;
608         }
609
610         if (serial->fd == -1) {
611                 sr_dbg("Cannot use unopened serial port %s (fd %d).",
612                                 serial->port, serial->fd);
613                 return -1;
614         }
615
616         timeout_ms *= 1000;
617         start = g_get_monotonic_time();
618
619         maxlen = *buflen;
620         *buflen = len = 0;
621         while(1) {
622                 len = maxlen - *buflen - 1;
623                 if (len < 1)
624                         break;
625                 len = serial_read(serial, *buf + *buflen, 1);
626                 if (len > 0) {
627                         *buflen += len;
628                         *(*buf + *buflen) = '\0';
629                         if (*buflen > 0 && (*(*buf + *buflen - 1) == '\r'
630                                         || *(*buf + *buflen - 1) == '\n')) {
631                                 /* Strip CR/LF and terminate. */
632                                 *(*buf + --*buflen) = '\0';
633                                 break;
634                         }
635                 }
636                 if (g_get_monotonic_time() - start > timeout_ms)
637                         /* Timeout */
638                         break;
639                 g_usleep(2000);
640         }
641         if (*buflen)
642                 sr_dbg("Received %d: '%s'.", *buflen, *buf);
643
644         return SR_OK;
645 }
646
647 /**
648  * Try to find a valid packet in a serial data stream.
649  *
650  * @param serial Previously initialized serial port structure.
651  * @param buf Buffer containing the bytes to write.
652  * @param count Size of the buffer.
653  * @param packet_size Size, in bytes, of a valid packet.
654  * @param is_valid Callback that assesses whether the packet is valid or not.
655  * @param timeout_ms The timeout after which, if no packet is detected, to
656  *                   abort scanning.
657  * @param baudrate The baudrate of the serial port. This parameter is not
658  *                 critical, but it helps fine tune the serial port polling
659  *                 delay.
660  *
661  * @return SR_OK if a valid packet is found within the given timeout,
662  *         SR_ERR upon failure.
663  */
664 SR_PRIV int serial_stream_detect(struct sr_serial_dev_inst *serial,
665                                  uint8_t *buf, size_t *buflen,
666                                  size_t packet_size, packet_valid_t is_valid,
667                                  uint64_t timeout_ms, int baudrate)
668 {
669         uint64_t start, time, byte_delay_us;
670         size_t ibuf, i, maxlen;
671         int len;
672
673         maxlen = *buflen;
674
675         sr_dbg("Detecting packets on FD %d (timeout = %" PRIu64
676                "ms, baudrate = %d).", serial->fd, timeout_ms, baudrate);
677
678         if (maxlen < (packet_size / 2) ) {
679                 sr_err("Buffer size must be at least twice the packet size.");
680                 return SR_ERR;
681         }
682
683         /* Assume 8n1 transmission. That is 10 bits for every byte. */
684         byte_delay_us = 10 * (1000000 / baudrate);
685         start = g_get_monotonic_time();
686
687         i = ibuf = len = 0;
688         while (ibuf < maxlen) {
689                 len = serial_read(serial, &buf[ibuf], 1);
690                 if (len > 0) {
691                         ibuf += len;
692                 } else if (len == 0) {
693                         sr_spew("Error: Only read 0 bytes.");
694                 } else {
695                         /* Error reading byte, but continuing anyway. */
696                 }
697
698                 time = g_get_monotonic_time() - start;
699                 time /= 1000;
700
701                 if ((ibuf - i) >= packet_size) {
702                         /* We have at least a packet's worth of data. */
703                         if (is_valid(&buf[i])) {
704                                 sr_spew("Found valid %d-byte packet after "
705                                         "%" PRIu64 "ms.", (ibuf - i), time);
706                                 *buflen = ibuf;
707                                 return SR_OK;
708                         } else {
709                                 sr_spew("Got %d bytes, but not a valid "
710                                         "packet.", (ibuf - i));
711                         }
712                         /* Not a valid packet. Continue searching. */
713                         i++;
714                 }
715                 if (time >= timeout_ms) {
716                         /* Timeout */
717                         sr_dbg("Detection timed out after %dms.", time);
718                         break;
719                 }
720                 g_usleep(byte_delay_us);
721         }
722
723         *buflen = ibuf;
724
725         sr_err("Didn't find a valid packet (read %d bytes).", *buflen);
726
727         return SR_ERR;
728 }