2 * This file is part of the libserialport project.
4 * Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.com>
5 * Copyright (C) 2010-2012 Uwe Hermann <uwe@hermann-uwe.de>
6 * Copyright (C) 2013 Martin Ling <martin-libserialport@earth.li>
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as
10 * published by the Free Software Foundation, either version 3 of the
11 * License, or (at your option) any later version.
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.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/types.h>
31 #include <sys/ioctl.h>
36 #include "serialport.h"
38 static int sp_validate_port(struct sp_port
*port
)
43 if (port
->hdl
== INVALID_HANDLE_VALUE
)
52 #define CHECK_PORT() do { if (!sp_validate_port(port)) return SP_ERR_ARG; } while (0)
55 * Open the specified serial port.
57 * @param port Pointer to empty port structure allocated by caller.
58 * @param portname Name of port to open.
59 * @param flags Flags to use when opening the serial port. Possible flags
60 * are: SP_MODE_RDWR, SP_MODE_RDONLY, SP_MODE_NONBLOCK.
62 * @return SP_OK on success, SP_ERR_FAIL on failure,
63 * or SP_ERR_ARG if an invalid port or name is passed.
65 int sp_open(struct sp_port
*port
, char *portname
, int flags
)
73 port
->name
= portname
;
76 DWORD desired_access
= 0, flags_and_attributes
= 0;
77 /* Map 'flags' to the OS-specific settings. */
78 desired_access
|= GENERIC_READ
;
79 flags_and_attributes
= FILE_ATTRIBUTE_NORMAL
;
80 if (flags
& SP_MODE_RDWR
)
81 desired_access
|= GENERIC_WRITE
;
82 if (flags
& SP_MODE_NONBLOCK
)
83 flags_and_attributes
|= FILE_FLAG_OVERLAPPED
;
85 port
->hdl
= CreateFile(port
->name
, desired_access
, 0, 0,
86 OPEN_EXISTING
, flags_and_attributes
, 0);
87 if (port
->hdl
== INVALID_HANDLE_VALUE
)
91 /* Map 'flags' to the OS-specific settings. */
92 if (flags
& SP_MODE_RDWR
)
93 flags_local
|= O_RDWR
;
94 if (flags
& SP_MODE_RDONLY
)
95 flags_local
|= O_RDONLY
;
96 if (flags
& SP_MODE_NONBLOCK
)
97 flags_local
|= O_NONBLOCK
;
99 if ((port
->fd
= open(port
->name
, flags_local
)) < 0)
107 * Close the specified serial port.
109 * @param port Pointer to port structure.
111 * @return SP_OK on success, SP_ERR_FAIL on failure,
112 * or SP_ERR_ARG if an invalid port is passed.
114 int sp_close(struct sp_port
*port
)
119 /* Returns non-zero upon success, 0 upon failure. */
120 if (CloseHandle(port
->hdl
) == 0)
123 /* Returns 0 upon success, -1 upon failure. */
124 if (close(port
->fd
) == -1)
132 * Flush serial port buffers.
134 * @param port Pointer to port structure.
136 * @return SP_OK on success, SP_ERR_FAIL on failure,
137 * or SP_ERR_ARG if an invalid port is passed.
139 int sp_flush(struct sp_port
*port
)
144 /* Returns non-zero upon success, 0 upon failure. */
145 if (PurgeComm(port
->hdl
, PURGE_RXCLEAR
| PURGE_TXCLEAR
) == 0)
148 /* Returns 0 upon success, -1 upon failure. */
149 if (tcflush(port
->fd
, TCIOFLUSH
) < 0)
156 * Write a number of bytes to the specified serial port.
158 * @param port Pointer to port structure.
159 * @param buf Buffer containing the bytes to write.
160 * @param count Number of bytes to write.
162 * @return The number of bytes written, SP_ERR_FAIL on failure,
163 * or SP_ERR_ARG if an invalid port is passed.
165 int sp_write(struct sp_port
*port
, const void *buf
, size_t count
)
174 /* Returns non-zero upon success, 0 upon failure. */
175 if (WriteFile(port
->hdl
, buf
, count
, &written
, NULL
) == 0)
179 /* Returns the number of bytes written, or -1 upon failure. */
180 ssize_t written
= write(port
->fd
, buf
, count
);
189 * Read a number of bytes from the specified serial port.
191 * @param port Pointer to port structure.
192 * @param buf Buffer where to store the bytes that are read.
193 * @param count The number of bytes to read.
195 * @return The number of bytes read, SP_ERR_FAIL on failure,
196 * or SP_ERR_ARG if an invalid port is passed.
198 int sp_read(struct sp_port
*port
, void *buf
, size_t count
)
206 DWORD bytes_read
= 0;
207 /* Returns non-zero upon success, 0 upon failure. */
208 if (ReadFile(port
->hdl
, buf
, count
, &bytes_read
, NULL
) == 0)
213 /* Returns the number of bytes read, or -1 upon failure. */
214 if ((bytes_read
= read(port
->fd
, buf
, count
)) < 0)
221 * Set serial parameters for the specified serial port.
223 * @param port Pointer to port structure.
224 * @param baudrate The baudrate to set.
225 * @param bits The number of data bits to use.
226 * @param parity The parity setting to use (0 = none, 1 = even, 2 = odd).
227 * @param stopbits The number of stop bits to use (1 or 2).
228 * @param flowcontrol The flow control settings to use (0 = none, 1 = RTS/CTS,
231 * @return The number of bytes read, SP_ERR_FAIL on failure,
232 * or SP_ERR_ARG if an invalid argument is passed.
234 int sp_set_params(struct sp_port
*port
, int baudrate
,
235 int bits
, int parity
, int stopbits
,
236 int flowcontrol
, int rts
, int dtr
)
243 if (!GetCommState(port
->hdl
, &dcb
))
248 * The baudrates 50/75/134/150/200/1800/230400/460800 do not seem to
249 * have documented CBR_* macros.
252 dcb
.BaudRate
= CBR_110
;
255 dcb
.BaudRate
= CBR_300
;
258 dcb
.BaudRate
= CBR_600
;
261 dcb
.BaudRate
= CBR_1200
;
264 dcb
.BaudRate
= CBR_2400
;
267 dcb
.BaudRate
= CBR_4800
;
270 dcb
.BaudRate
= CBR_9600
;
273 dcb
.BaudRate
= CBR_14400
; /* Not available on Unix? */
276 dcb
.BaudRate
= CBR_19200
;
279 dcb
.BaudRate
= CBR_38400
;
282 dcb
.BaudRate
= CBR_57600
;
285 dcb
.BaudRate
= CBR_115200
;
288 dcb
.BaudRate
= CBR_128000
; /* Not available on Unix? */
291 dcb
.BaudRate
= CBR_256000
; /* Not available on Unix? */
298 /* Note: There's also ONE5STOPBITS == 1.5 (unneeded so far). */
300 dcb
.StopBits
= ONESTOPBIT
;
303 dcb
.StopBits
= TWOSTOPBITS
;
310 /* Note: There's also SPACEPARITY, MARKPARITY (unneeded so far). */
312 dcb
.Parity
= NOPARITY
;
315 dcb
.Parity
= EVENPARITY
;
318 dcb
.Parity
= ODDPARITY
;
326 dcb
.fRtsControl
= RTS_CONTROL_ENABLE
;
328 dcb
.fRtsControl
= RTS_CONTROL_DISABLE
;
333 dcb
.fDtrControl
= DTR_CONTROL_ENABLE
;
335 dcb
.fDtrControl
= DTR_CONTROL_DISABLE
;
338 if (!SetCommState(port
->hdl
, &dcb
))
345 if (tcgetattr(port
->fd
, &term
) < 0)
403 #if !defined(__APPLE__) && !defined(__OpenBSD__)
412 if (cfsetospeed(&term
, baud
) < 0)
415 if (cfsetispeed(&term
, baud
) < 0)
418 term
.c_cflag
&= ~CSIZE
;
430 term
.c_cflag
&= ~CSTOPB
;
433 term
.c_cflag
&= ~CSTOPB
;
436 term
.c_cflag
|= CSTOPB
;
442 term
.c_iflag
&= ~(IXON
| IXOFF
);
443 term
.c_cflag
&= ~CRTSCTS
;
444 switch (flowcontrol
) {
446 /* No flow control. */
449 term
.c_cflag
|= CRTSCTS
;
452 term
.c_iflag
|= IXON
| IXOFF
;
458 term
.c_iflag
&= ~IGNPAR
;
459 term
.c_cflag
&= ~(PARODD
| PARENB
);
462 term
.c_iflag
|= IGNPAR
;
465 term
.c_cflag
|= PARENB
;
468 term
.c_cflag
|= PARENB
| PARODD
;
474 /* Turn off all serial port cooking. */
475 term
.c_iflag
&= ~(ISTRIP
| INLCR
| ICRNL
);
476 term
.c_oflag
&= ~(ONLCR
| OCRNL
| ONOCR
);
477 #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
478 term
.c_oflag
&= ~OFILL
;
481 /* Disable canonical mode, and don't echo input characters. */
482 term
.c_lflag
&= ~(ICANON
| ECHO
);
484 /* Write the configured settings. */
485 if (tcsetattr(port
->fd
, TCSADRAIN
, &term
) < 0)
489 controlbits
= TIOCM_RTS
;
490 if (ioctl(port
->fd
, rts
? TIOCMBIS
: TIOCMBIC
,
496 controlbits
= TIOCM_DTR
;
497 if (ioctl(port
->fd
, dtr
? TIOCMBIS
: TIOCMBIC
,
507 * Get error code for failed operation.
509 * In order to obtain the correct result, this function should be called
510 * straight after the failure, before executing any other system operations.
512 * @return The system's numeric code for the error that caused the last
515 int sp_last_error_code(void)
518 return GetLastError();
525 * Get error message for failed operation.
527 * In order to obtain the correct result, this function should be called
528 * straight after the failure, before executing other system operations.
530 * @return The system's message for the error that caused the last
531 * operation to fail. This string may be allocated by the function,
532 * and can be freed after use by calling sp_free_error_message.
534 char *sp_last_error_message(void)
538 DWORD error
= GetLastError();
541 FORMAT_MESSAGE_ALLOCATE_BUFFER
|
542 FORMAT_MESSAGE_FROM_SYSTEM
|
543 FORMAT_MESSAGE_IGNORE_INSERTS
,
546 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
552 return strerror(errno
);
557 * Free error message.
559 * This function can be used to free a string returned by the
560 * sp_last_error_message function.
562 void sp_free_error_message(char *message
)