Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions serial.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
39 changes: 39 additions & 0 deletions serial_rs485_linux.go
Original file line number Diff line number Diff line change
@@ -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)
}
11 changes: 11 additions & 0 deletions serial_rs485_stub.go
Original file line number Diff line number Diff line change
@@ -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")
}
20 changes: 20 additions & 0 deletions serial_rs485_unix.go
Original file line number Diff line number Diff line change
@@ -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
}
39 changes: 0 additions & 39 deletions serial_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
}