Added Set(...) method to set all comm-params altogether

This commit is contained in:
Cristian Maglie
2014-12-15 18:43:09 +01:00
parent ff10f48795
commit fffcc61237
2 changed files with 65 additions and 18 deletions

View File

@@ -10,9 +10,6 @@ import "io"
// SerialPort object // SerialPort object
type SerialPort interface { type SerialPort interface {
// Read(p []byte) (n int, err error)
// Write(p []byte) (n int, err error)
// Close() error
io.ReadWriteCloser io.ReadWriteCloser
// Set port speed // Set port speed
@@ -26,6 +23,9 @@ type SerialPort interface {
// Set stop bits // Set stop bits
SetStopBits(bits StopBits) error SetStopBits(bits StopBits) error
// Set all parameters together
Set(baudrate int, parity Parity, databits int, stopbits StopBits) error
} }
type Parity int type Parity int

View File

@@ -91,6 +91,37 @@ func (port *linuxSerialPort) Write(p []byte) (n int, err error) {
return syscall.Write(port.handle, p) return syscall.Write(port.handle, p)
} }
func (port *linuxSerialPort) Set(baudrate int, parity Parity, databits int, stopbits StopBits) error {
settings, err := port.getTermSettings()
if err != nil {
return err
}
if err := setTermSettingsBaudrate(baudrate, settings); err != nil {
return err
}
if err := setTermSettingsParity(parity, settings); err != nil {
return err
}
if err := setTermSettingsDataBits(databits, settings); err != nil {
return err
}
if err := setTermSettingsStopBits(stopbits, settings); err != nil {
return err
}
return port.setTermSettings(settings)
}
func (port *linuxSerialPort) SetSpeed(speed int) error {
settings, err := port.getTermSettings()
if err != nil {
return err
}
if err := setTermSettingsBaudrate(speed, settings); err != nil {
return err
}
return port.setTermSettings(settings)
}
var baudrateMap = map[int]uint32{ var baudrateMap = map[int]uint32{
50: syscall.B50, 50: syscall.B50,
75: syscall.B75, 75: syscall.B75,
@@ -124,15 +155,11 @@ var baudrateMap = map[int]uint32{
4000000: syscall.B4000000, 4000000: syscall.B4000000,
} }
func (port *linuxSerialPort) SetSpeed(speed int) error { func setTermSettingsBaudrate(speed int, settings *syscall.Termios) error {
baudrate, ok := baudrateMap[speed] baudrate, ok := baudrateMap[speed]
if !ok { if !ok {
return &SerialPortError{code: ERROR_INVALID_PORT_SPEED} return &SerialPortError{code: ERROR_INVALID_PORT_SPEED}
} }
settings, err := port.getTermSettings()
if err != nil {
return err
}
// revert old baudrate // revert old baudrate
var BAUDMASK uint32 = 0 var BAUDMASK uint32 = 0
for _, rate := range baudrateMap { for _, rate := range baudrateMap {
@@ -143,16 +170,22 @@ func (port *linuxSerialPort) SetSpeed(speed int) error {
settings.Cflag |= baudrate settings.Cflag |= baudrate
settings.Ispeed = baudrate settings.Ispeed = baudrate
settings.Ospeed = baudrate settings.Ospeed = baudrate
return port.setTermSettings(settings) return nil
} }
func (port *linuxSerialPort) SetParity(parity Parity) error { func (port *linuxSerialPort) SetParity(parity Parity) error {
const FIXED_PARITY_FLAG uint32 = 0 // may be CMSPAR or PAREXT
settings, err := port.getTermSettings() settings, err := port.getTermSettings()
if err != nil { if err != nil {
return err return err
} }
if err := setTermSettingsParity(parity, settings); err != nil {
return err
}
return port.setTermSettings(settings)
}
func setTermSettingsParity(parity Parity, settings *syscall.Termios) error {
const FIXED_PARITY_FLAG uint32 = 0 // may be CMSPAR or PAREXT
switch parity { switch parity {
case PARITY_NONE: case PARITY_NONE:
settings.Cflag &= ^uint32(syscall.PARENB | syscall.PARODD | FIXED_PARITY_FLAG) settings.Cflag &= ^uint32(syscall.PARENB | syscall.PARODD | FIXED_PARITY_FLAG)
@@ -173,7 +206,7 @@ func (port *linuxSerialPort) SetParity(parity Parity) error {
settings.Cflag |= syscall.PARENB | FIXED_PARITY_FLAG settings.Cflag |= syscall.PARENB | FIXED_PARITY_FLAG
settings.Iflag |= syscall.INPCK settings.Iflag |= syscall.INPCK
} }
return port.setTermSettings(settings) return nil
} }
var databitsMap = map[int]uint32{ var databitsMap = map[int]uint32{
@@ -184,17 +217,24 @@ var databitsMap = map[int]uint32{
} }
func (port *linuxSerialPort) SetDataBits(bits int) error { func (port *linuxSerialPort) SetDataBits(bits int) error {
databits, ok := databitsMap[bits]
if !ok {
return &SerialPortError{code: ERROR_INVALID_PORT_DATA_BITS}
}
settings, err := port.getTermSettings() settings, err := port.getTermSettings()
if err != nil { if err != nil {
return err return err
} }
if err := setTermSettingsDataBits(bits, settings); err != nil {
return err
}
return port.setTermSettings(settings)
}
func setTermSettingsDataBits(bits int, settings *syscall.Termios) error {
databits, ok := databitsMap[bits]
if !ok {
return &SerialPortError{code: ERROR_INVALID_PORT_DATA_BITS}
}
settings.Cflag &= ^uint32(syscall.CSIZE) settings.Cflag &= ^uint32(syscall.CSIZE)
settings.Cflag |= databits settings.Cflag |= databits
return port.setTermSettings(settings) return nil
} }
func (port *linuxSerialPort) SetStopBits(bits StopBits) error { func (port *linuxSerialPort) SetStopBits(bits StopBits) error {
@@ -202,13 +242,20 @@ func (port *linuxSerialPort) SetStopBits(bits StopBits) error {
if err != nil { if err != nil {
return err return err
} }
if err := setTermSettingsStopBits(bits, settings); err != nil {
return err
}
return port.setTermSettings(settings)
}
func setTermSettingsStopBits(bits StopBits, settings *syscall.Termios) error {
switch bits { switch bits {
case STOPBITS_ONE: case STOPBITS_ONE:
settings.Cflag &= ^uint32(syscall.CSTOPB) settings.Cflag &= ^uint32(syscall.CSTOPB)
case STOPBITS_ONEPOINTFIVE, STOPBITS_TWO: case STOPBITS_ONEPOINTFIVE, STOPBITS_TWO:
settings.Cflag |= syscall.CSTOPB settings.Cflag |= syscall.CSTOPB
} }
return port.setTermSettings(settings) return nil
} }
// native syscall wrapper functions // native syscall wrapper functions