diff --git a/serial.go b/serial.go index 674069b..43f0f74 100644 --- a/serial.go +++ b/serial.go @@ -53,7 +53,7 @@ type Port interface { // NoTimeout should be used as a parameter to SetReadTimeout to disable timeout. var NoTimeout time.Duration = -1 -// ModemStatusBits contains all the modem status bits for a serial port (CTS, DSR, etc...). +// ModemStatusBits contains all the modem input status bits for a serial port (CTS, DSR, etc...). // It can be retrieved with the Port.GetModemStatusBits() method. type ModemStatusBits struct { CTS bool // ClearToSend status @@ -62,6 +62,13 @@ type ModemStatusBits struct { DCD bool // DataCarrierDetect status } +// ModemOutputBits contains all the modem output bits for a serial port. +// This is used in the Mode.InitialStatusBits struct to specify the initial status of the bits. +type ModemOutputBits struct { + RTS bool // ReadyToSend status + DTR bool // DataTerminalReady status +} + // Open opens the serial port using the specified modes func Open(portName string, mode *Mode) (Port, error) { return nativeOpen(portName, mode) @@ -74,12 +81,11 @@ func GetPortsList() ([]string, error) { // Mode describes a serial port configuration. type Mode struct { - BaudRate int // The serial port bitrate (aka Baudrate) - DataBits int // Size of the character (must be 5, 6, 7 or 8) - Parity Parity // Parity (see Parity type for more info) - StopBits StopBits // Stop bits (see StopBits type for more info) - InitialRTS bool // Initial state for RTS - InitialDTR bool // Initial state for DTR + BaudRate int // The serial port bitrate (aka Baudrate) + DataBits int // Size of the character (must be 5, 6, 7 or 8) + 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) } // Parity describes a serial port parity setting diff --git a/serial_unix.go b/serial_unix.go index 2f7e1d1..4a8ef66 100644 --- a/serial_unix.go +++ b/serial_unix.go @@ -235,14 +235,31 @@ func nativeOpen(portName string, mode *Mode) (*unixPort, error) { // Explicitly disable RTS/CTS flow control setTermSettingsCtsRts(false, settings) - port.SetDTR(mode.InitialDTR) - port.SetRTS(mode.InitialRTS) - if port.setTermSettings(settings) != nil { port.Close() return nil, &PortError{code: InvalidSerialPort} } + if mode.InitialStatusBits != nil { + status, err := port.getModemBitsStatus() + if err != nil { + return nil, &PortError{code: InvalidSerialPort, causedBy: err} + } + if mode.InitialStatusBits.DTR { + status |= unix.TIOCM_DTR + } else { + status &^= unix.TIOCM_DTR + } + if mode.InitialStatusBits.RTS { + status |= unix.TIOCM_RTS + } else { + status &^= unix.TIOCM_RTS + } + if err := port.setModemBitsStatus(status); err != nil { + return nil, &PortError{code: InvalidSerialPort, causedBy: err} + } + } + // MacOSX require that this operation is the last one otherwise an // 'Invalid serial port' error is returned... don't know why... if port.SetMode(mode) != nil { diff --git a/serial_windows.go b/serial_windows.go index dd0715c..4b652b5 100644 --- a/serial_windows.go +++ b/serial_windows.go @@ -450,13 +450,18 @@ func nativeOpen(portName string, mode *Mode) (*windowsPort, error) { port.Close() return nil, &PortError{code: InvalidSerialPort} } - params.Flags &= dcbRTSControlDisbaleMask - if mode.InitialRTS { - params.Flags |= dcbRTSControlEnable - } params.Flags &= dcbDTRControlDisableMask - if mode.InitialDTR { + params.Flags &= dcbRTSControlDisbaleMask + if mode.InitialStatusBits == nil { params.Flags |= dcbDTRControlEnable + params.Flags |= dcbRTSControlEnable + } else { + if mode.InitialStatusBits.DTR { + params.Flags |= dcbDTRControlEnable + } + if mode.InitialStatusBits.RTS { + params.Flags |= dcbRTSControlEnable + } } params.Flags &^= dcbOutXCTSFlow params.Flags &^= dcbOutXDSRFlow