From 87b39637ffbae5ac08fd585b64c79629805c96ed Mon Sep 17 00:00:00 2001 From: Joerg Wunsch Date: Mon, 7 Mar 2022 23:20:50 +0100 Subject: [PATCH] Implement nonstandard baudrate handling on MacOS Alas, MacOS doesn't handle nonstandard baud rates like other systems in regular tcsetattr() calls. Instead, they invented a new ioctl (IOSSIOSPEED). So, if we notice we are going to configure a nonstandard rate on MacOS, issue that ioctl after configuring everything else using tcsetattr(). --- build.sh | 2 +- src/ser_posix.c | 38 ++++++++++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/build.sh b/build.sh index baea4516..4a2cbc5a 100755 --- a/build.sh +++ b/build.sh @@ -59,7 +59,7 @@ case "${ostype}" in ;; esac -cmake ${build_flags} ${extra_enable} -D CMAKE_BUILD_TYPE=${build_type} -B build_${ostype} ||\ +cmake ${build_flags} ${extra_enable} -D CMAKE_VERBOSE_MAKEFILE:BOOL=ON -D CMAKE_BUILD_TYPE=${build_type} -B build_${ostype} ||\ { echo "CMake failed."; exit 1; } cmake --build build_${ostype} ||\ { echo "Build failed."; exit 1; } diff --git a/src/ser_posix.c b/src/ser_posix.c index d2b3031b..50bd2cfe 100644 --- a/src/ser_posix.c +++ b/src/ser_posix.c @@ -28,6 +28,7 @@ #include "ac_cfg.h" #include +#include #include #include #include @@ -42,6 +43,10 @@ #include #include +#ifdef __APPLE__ +# include +#endif + #include "avrdude.h" #include "libavrdude.h" @@ -78,10 +83,12 @@ static struct baud_mapping baud_lookup_table [] = { static struct termios original_termios; static int saved_original_termios; -static speed_t serial_baud_lookup(long baud) +static speed_t serial_baud_lookup(long baud, bool *nonstandard) { struct baud_mapping *map = baud_lookup_table; + *nonstandard = false; + while (map->baud) { if (map->baud == baud) return map->speed; @@ -95,6 +102,8 @@ static speed_t serial_baud_lookup(long baud) avrdude_message(MSG_NOTICE, "%s: serial_baud_lookup(): Using non-standard baud rate: %ld", progname, baud); + *nonstandard = true; + return baud; } @@ -102,7 +111,8 @@ static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cfla { int rc; struct termios termios; - speed_t speed = serial_baud_lookup (baud); + bool nonstandard; + speed_t speed = serial_baud_lookup (baud, &nonstandard); if (!isatty(fd->ifd)) return -ENOTTY; @@ -146,8 +156,16 @@ static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cfla termios.c_iflag &= ~PARMRK; #endif /* PARMRK */ - cfsetospeed(&termios, speed); - cfsetispeed(&termios, speed); + // MacOS doesn't handle nonstandard baudrate values in + // normal tcsetattr(), sigh. +#ifdef __APPLE__ + if (!nonstandard) { +#endif + cfsetospeed(&termios, speed); + cfsetispeed(&termios, speed); +#ifdef __APPLE__ + } +#endif termios.c_cflag &= ~CSIZE; if (cflags & SERIAL_CS8) { @@ -204,6 +222,17 @@ static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cfla return -errno; } +#ifdef __APPLE__ + // handle nonstandard speed values the MacOS way + if (nonstandard) { + if (ioctl(fd->ifd, IOSSIOSPEED, &speed) < 0) { + avrdude_message(MSG_INFO, "%s: ser_setparams(): ioctrl(IOSSIOSPEED) failed\n", + progname); + return -errno; + } + } +#endif // __APPLE__ + tcflush(fd->ifd, TCIFLUSH); return 0; @@ -564,3 +593,4 @@ struct serial_device serial_serdev = struct serial_device *serdev = &serial_serdev; #endif /* WIN32 */ +