summaryrefslogtreecommitdiffstats
path: root/serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'serial.c')
-rw-r--r--serial.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/serial.c b/serial.c
index 76d34a263..10d739a33 100644
--- a/serial.c
+++ b/serial.c
@@ -15,8 +15,6 @@
* GNU General Public License for more details.
*/
-#include "platform.h"
-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -49,6 +47,10 @@ fdtype sp_fd = SER_INV_FD;
* On Linux there is a non-standard way to use arbitrary baud rates that we use if there is no
* matching standard rate, see custom_baud.c
*
+ * On Darwin there is also a non-standard ioctl() to set arbitrary baud rates
+ * and any above 230400, see custom_baud_darwin.c and
+ * https://opensource.apple.com/source/IOSerialFamily/IOSerialFamily-91/tests/IOSerialTestLib.c.auto.html
+ *
* On Windows there exist similar macros (starting with CBR_ instead of B) but they are only defined for
* backwards compatibility and the API supports arbitrary baud rates in the same manner as the macros, see
* http://msdn.microsoft.com/en-us/library/windows/desktop/aa363214(v=vs.85).aspx
@@ -181,6 +183,7 @@ int serialport_config(fdtype fd, int baud)
}
msg_pdbg("Baud rate is %ld.\n", dcb.BaudRate);
#else
+ int custom_baud = (baud >= 0 && use_custom_baud(baud, sp_baudtable));
struct termios wanted, observed;
if (tcgetattr(fd, &observed) != 0) {
msg_perr_strerror("Could not fetch original serial port configuration: ");
@@ -188,8 +191,8 @@ int serialport_config(fdtype fd, int baud)
}
wanted = observed;
if (baud >= 0) {
- if (use_custom_baud(baud, sp_baudtable)) {
- if (set_custom_baudrate(fd, baud)) {
+ if (custom_baud) {
+ if (set_custom_baudrate(fd, baud, BEFORE_FLAGS, NULL)) {
msg_perr_strerror("Could not set custom baudrate: ");
return 1;
}
@@ -200,7 +203,6 @@ int serialport_config(fdtype fd, int baud)
msg_perr_strerror("Could not fetch serial port configuration: ");
return 1;
}
- msg_pdbg("Using custom baud rate.\n");
} else {
const struct baudentry *entry = round_baud(baud);
if (cfsetispeed(&wanted, entry->flag) != 0 || cfsetospeed(&wanted, entry->flag) != 0) {
@@ -214,6 +216,10 @@ int serialport_config(fdtype fd, int baud)
wanted.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | IEXTEN);
wanted.c_iflag &= ~(IXON | IXOFF | IXANY | ICRNL | IGNCR | INLCR);
wanted.c_oflag &= ~OPOST;
+ if (custom_baud && set_custom_baudrate(fd, baud, WITH_FLAGS, &wanted)) {
+ msg_perr_strerror("Could not set custom baudrate: ");
+ return 1;
+ }
if (tcsetattr(fd, TCSANOW, &wanted) != 0) {
msg_perr_strerror("Could not change serial port configuration: ");
return 1;
@@ -238,6 +244,13 @@ int serialport_config(fdtype fd, int baud)
(long)observed.c_oflag, (long)wanted.c_oflag
);
}
+ if (custom_baud) {
+ if (set_custom_baudrate(fd, baud, AFTER_FLAGS, &wanted)) {
+ msg_perr_strerror("Could not set custom baudrate: ");
+ return 1;
+ }
+ msg_pdbg("Using custom baud rate.\n");
+ }
if (cfgetispeed(&observed) != cfgetispeed(&wanted) ||
cfgetospeed(&observed) != cfgetospeed(&wanted)) {
msg_pwarn("Could not set baud rates exactly.\n");
@@ -405,7 +418,7 @@ int serialport_write(const unsigned char *buf, unsigned int writecnt)
if (!tmp) {
msg_pdbg2("Empty write\n");
empty_writes--;
- internal_delay(500);
+ default_delay(500);
if (empty_writes == 0) {
msg_perr("Serial port is unresponsive!\n");
return 1;
@@ -512,7 +525,7 @@ int serialport_read_nonblock(unsigned char *c, unsigned int readcnt, unsigned in
ret = 0;
break;
}
- internal_delay(1000); /* 1ms units */
+ default_delay(1000); /* 1ms units */
}
if (really_read != NULL)
*really_read = rd_bytes;
@@ -598,7 +611,7 @@ int serialport_write_nonblock(const unsigned char *buf, unsigned int writecnt, u
break;
}
}
- internal_delay(1000); /* 1ms units */
+ default_delay(1000); /* 1ms units */
}
if (really_wrote != NULL)
*really_wrote = wr_bytes;