Skip to content

Commit

Permalink
Solve issue Custom Baudrate OSX #139 of original repo; inspired by Py…
Browse files Browse the repository at this point in the history
…Serial source code and #57 of github.com/npat-efault/picocom, we need to set custom baudrate after calling tcsetattr; tested on macOS Mojave 10.14.4 (#218)
  • Loading branch information
atomiechen authored Jun 10, 2021
1 parent 7439db1 commit a93fc84
Showing 1 changed file with 35 additions and 30 deletions.
65 changes: 35 additions & 30 deletions src/impl/unix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -304,36 +304,6 @@ Serial::SerialImpl::reconfigurePort ()
#endif
default:
custom_baud = true;
// OS X support
#if defined(MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4)
// Starting with Tiger, the IOSSIOSPEED ioctl can be used to set arbitrary baud rates
// other than those specified by POSIX. The driver for the underlying serial hardware
// ultimately determines which baud rates can be used. This ioctl sets both the input
// and output speed.
speed_t new_baud = static_cast<speed_t> (baudrate_);
if (-1 == ioctl (fd_, IOSSIOSPEED, &new_baud, 1)) {
THROW (IOException, errno);
}
// Linux Support
#elif defined(__linux__) && defined (TIOCSSERIAL)
struct serial_struct ser;

if (-1 == ioctl (fd_, TIOCGSERIAL, &ser)) {
THROW (IOException, errno);
}

// set custom divisor
ser.custom_divisor = ser.baud_base / static_cast<int> (baudrate_);
// update flags
ser.flags &= ~ASYNC_SPD_MASK;
ser.flags |= ASYNC_SPD_CUST;

if (-1 == ioctl (fd_, TIOCSSERIAL, &ser)) {
THROW (IOException, errno);
}
#else
throw invalid_argument ("OS does not currently support custom bauds");
#endif
}
if (custom_baud == false) {
#ifdef _BSD_SOURCE
Expand Down Expand Up @@ -443,6 +413,41 @@ Serial::SerialImpl::reconfigurePort ()
// activate settings
::tcsetattr (fd_, TCSANOW, &options);

// apply custom baud rate, if any
if (custom_baud == true) {
// OS X support
#if defined(MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4)
// Starting with Tiger, the IOSSIOSPEED ioctl can be used to set arbitrary baud rates
// other than those specified by POSIX. The driver for the underlying serial hardware
// ultimately determines which baud rates can be used. This ioctl sets both the input
// and output speed.
speed_t new_baud = static_cast<speed_t> (baudrate_);
// PySerial uses IOSSIOSPEED=0x80045402
if (-1 == ioctl (fd_, IOSSIOSPEED, &new_baud, 1)) {
THROW (IOException, errno);
}
// Linux Support
#elif defined(__linux__) && defined (TIOCSSERIAL)
struct serial_struct ser;

if (-1 == ioctl (fd_, TIOCGSERIAL, &ser)) {
THROW (IOException, errno);
}

// set custom divisor
ser.custom_divisor = ser.baud_base / static_cast<int> (baudrate_);
// update flags
ser.flags &= ~ASYNC_SPD_MASK;
ser.flags |= ASYNC_SPD_CUST;

if (-1 == ioctl (fd_, TIOCSSERIAL, &ser)) {
THROW (IOException, errno);
}
#else
throw invalid_argument ("OS does not currently support custom bauds");
#endif
}

// Update byte_time_ based on the new settings.
uint32_t bit_time_ns = 1e9 / baudrate_;
byte_time_ns_ = bit_time_ns * (1 + bytesize_ + parity_ + stopbits_);
Expand Down

0 comments on commit a93fc84

Please sign in to comment.