diff --git a/serial.go b/serial.go index 73adf0b..73ea1da 100644 --- a/serial.go +++ b/serial.go @@ -101,23 +101,6 @@ type Mode struct { Parity Parity // Parity (see Parity type for more info) StopBits StopBits // Stop bits (see StopBits type for more info) InitialStatusBits *ModemOutputBits // Initial output modem bits status (if nil defaults to DTR=true and RTS=true) - RS485 RS485Config // RS485 configuration -} - -// RS485Config -- platform independent RS485 config. Thie structure is ignored unless Enable is true. -type RS485Config struct { - // Enable RS485 support - Enabled bool - // Delay RTS prior to send - DelayRtsBeforeSend time.Duration - // Delay RTS after send - DelayRtsAfterSend time.Duration - // Set RTS high during send - RtsHighDuringSend bool - // Set RTS high after send - RtsHighAfterSend bool - // Rx during Tx - RxDuringTx bool } // Parity describes a serial port parity setting diff --git a/serial_rs485_linux.go b/serial_rs485_linux.go new file mode 100644 index 0000000..b706f82 --- /dev/null +++ b/serial_rs485_linux.go @@ -0,0 +1,39 @@ +//go:build linux + +package serial + +import ( + "time" + + "golang.org/x/sys/unix" +) + +const ( + rs485Enabled = 1 << 0 + rs485RTSOnSend = 1 << 1 + rs485RTSAfterSend = 1 << 2 + rs485RXDuringTX = 1 << 4 + rs485Tiocs = unix.TIOCSRS485 +) + +// EnableRS485 enables RS485 functionality of driver via an ioctl if the config says so +func (port *unixPort) EnableRS485(config *LinuxRS485Config) error { + rs485 := rs485IoctlOpts{ + rs485Enabled, + int(config.DelayRtsBeforeSend / time.Millisecond), + int(config.DelayRtsAfterSend / time.Millisecond), + [5]int{0, 0, 0, 0, 0}, + } + + if config.RtsHighDuringSend { + rs485.flags |= rs485RTSOnSend + } + if config.RtsHighAfterSend { + rs485.flags |= rs485RTSAfterSend + } + if config.RxDuringTx { + rs485.flags |= rs485RXDuringTX + } + + return unix.IoctlSetPointerInt(port.handle, rs485Tiocs, rs485.flags) +} diff --git a/serial_rs485_stub.go b/serial_rs485_stub.go new file mode 100644 index 0000000..e57d5ba --- /dev/null +++ b/serial_rs485_stub.go @@ -0,0 +1,11 @@ +//go:build darwin || freebsd || openbsd + +package serial + +import ( + "fmt" +) + +func (port *unixPort) EnableRS485(config *LinuxRS485Config) error { + return fmt.Errorf("EnableRS485 is not supported on this OS") +} diff --git a/serial_rs485_unix.go b/serial_rs485_unix.go new file mode 100644 index 0000000..0310760 --- /dev/null +++ b/serial_rs485_unix.go @@ -0,0 +1,20 @@ +//go:build linux || darwin || freebsd || openbsd + +package serial + +import "time" + +// RS485Config holds configuration for RS485 mode on Linux systems (TIOCSRS485). +// Note: This is only supported on Linux systems. +type LinuxRS485Config struct { + // Delay RTS prior to send + DelayRtsBeforeSend time.Duration + // Delay RTS after send + DelayRtsAfterSend time.Duration + // Set RTS high during send + RtsHighDuringSend bool + // Set RTS high after send + RtsHighAfterSend bool + // Rx during Tx + RxDuringTx bool +} diff --git a/serial_unix.go b/serial_unix.go index 626762f..171c8dd 100644 --- a/serial_unix.go +++ b/serial_unix.go @@ -29,14 +29,6 @@ type unixPort struct { opened uint32 } -const ( - rs485Enabled = 1 << 0 - rs485RTSOnSend = 1 << 1 - rs485RTSAfterSend = 1 << 2 - rs485RXDuringTX = 1 << 4 - rs485Tiocs = 0x542f // unix.TIOCSRS485 is not supported on MacOS -) - // rs485_ioctl_opts is used to configure RS485 options in the driver type rs485IoctlOpts struct { flags int @@ -295,12 +287,6 @@ func nativeOpen(portName string, mode *Mode) (*unixPort, error) { port.acquireExclusiveAccess() - // Enable RS485, if requested - if err = port.enableRS485(&mode.RS485); err != nil { - port.Close() - return nil, err - } - // This pipe is used as a signal to cancel blocking Read pipe := &unixutils.Pipe{} if err := pipe.Open(); err != nil { @@ -487,28 +473,3 @@ func (port *unixPort) acquireExclusiveAccess() error { func (port *unixPort) releaseExclusiveAccess() error { return unix.IoctlSetInt(port.handle, unix.TIOCNXCL, 0) } - -// enableRS485 enables RS485 functionality of driver via an ioctl if the config says so -func (port *unixPort) enableRS485(config *RS485Config) error { - if !config.Enabled { - return nil - } - rs485 := rs485IoctlOpts{ - rs485Enabled, - int(config.DelayRtsBeforeSend / time.Millisecond), - int(config.DelayRtsAfterSend / time.Millisecond), - [5]int{0, 0, 0, 0, 0}, - } - - if config.RtsHighDuringSend { - rs485.flags |= rs485RTSOnSend - } - if config.RtsHighAfterSend { - rs485.flags |= rs485RTSAfterSend - } - if config.RxDuringTx { - rs485.flags |= rs485RXDuringTX - } - - return unix.IoctlSetPointerInt(port.handle, rs485Tiocs, rs485.flags) -}