Merge branch 'bit-fixes' into v1

This commit is contained in:
Cristian Maglie
2016-10-29 23:37:08 +02:00
7 changed files with 172 additions and 104 deletions

View File

@@ -94,6 +94,10 @@ const (
InvalidSpeed InvalidSpeed
// InvalidDataBits the number of data bits is not valid or not supported // InvalidDataBits the number of data bits is not valid or not supported
InvalidDataBits InvalidDataBits
// InvalidParity the selected parity is not valid or not supported
InvalidParity
// InvalidStopBits the selected number of stop bits is not valid or not supported
InvalidStopBits
// ErrorEnumeratingPorts an error occurred while listing serial port // ErrorEnumeratingPorts an error occurred while listing serial port
ErrorEnumeratingPorts ErrorEnumeratingPorts
) )
@@ -110,9 +114,13 @@ func (e PortError) EncodedErrorString() string {
case PermissionDenied: case PermissionDenied:
return "Permission denied" return "Permission denied"
case InvalidSpeed: case InvalidSpeed:
return "Invalid port speed" return "Port speed invalid or not supported"
case InvalidDataBits: case InvalidDataBits:
return "Invalid port data bits" return "Port data bits invalid or not supported"
case InvalidParity:
return "Port parity invalid or not supported"
case InvalidStopBits:
return "Port stop bits invalid or not supported"
case ErrorEnumeratingPorts: case ErrorEnumeratingPorts:
return "Could not enumerate serial ports" return "Could not enumerate serial ports"
default: default:

View File

@@ -11,48 +11,6 @@ import "syscall"
const devFolder = "/dev" const devFolder = "/dev"
const regexFilter = "^(cu|tty)\\..*" const regexFilter = "^(cu|tty)\\..*"
// termios manipulation functions
var baudrateMap = map[int]uint{
0: syscall.B9600, // Default to 9600
50: syscall.B50,
75: syscall.B75,
110: syscall.B110,
134: syscall.B134,
150: syscall.B150,
200: syscall.B200,
300: syscall.B300,
600: syscall.B600,
1200: syscall.B1200,
1800: syscall.B1800,
2400: syscall.B2400,
4800: syscall.B4800,
9600: syscall.B9600,
19200: syscall.B19200,
38400: syscall.B38400,
57600: syscall.B57600,
115200: syscall.B115200,
230400: syscall.B230400,
}
var databitsMap = map[int]uint{
0: syscall.CS8, // Default to 8 bits
5: syscall.CS5,
6: syscall.CS6,
7: syscall.CS7,
8: syscall.CS8,
}
const tcCMSPAR uint = 0 // may be CMSPAR or PAREXT
const tcIUCLC uint = 0
const tcCCTS_OFLOW uint = 0x00010000
const tcCRTS_IFLOW uint = 0x00020000
const tcCRTSCTS uint = (tcCCTS_OFLOW | tcCRTS_IFLOW)
// syscall wrappers
//sys ioctl(fd int, req uint64, data uintptr) (err error) //sys ioctl(fd int, req uint64, data uintptr) (err error)
const ioctlTcgetattr = syscall.TIOCGETA const ioctlTcgetattr = syscall.TIOCGETA

View File

@@ -6,6 +6,44 @@
package serial // import "go.bug.st/serial.v1" package serial // import "go.bug.st/serial.v1"
func termiosMask(data uint) uint32 { import "syscall"
return uint32(data)
// termios manipulation functions
var baudrateMap = map[int]uint32{
0: syscall.B9600, // Default to 9600
50: syscall.B50,
75: syscall.B75,
110: syscall.B110,
134: syscall.B134,
150: syscall.B150,
200: syscall.B200,
300: syscall.B300,
600: syscall.B600,
1200: syscall.B1200,
1800: syscall.B1800,
2400: syscall.B2400,
4800: syscall.B4800,
9600: syscall.B9600,
19200: syscall.B19200,
38400: syscall.B38400,
57600: syscall.B57600,
115200: syscall.B115200,
230400: syscall.B230400,
} }
var databitsMap = map[int]uint32{
0: syscall.CS8, // Default to 8 bits
5: syscall.CS5,
6: syscall.CS6,
7: syscall.CS7,
8: syscall.CS8,
}
const tcCMSPAR uint32 = 0 // may be CMSPAR or PAREXT
const tcIUCLC uint32 = 0
const tcCCTS_OFLOW uint32 = 0x00010000
const tcCRTS_IFLOW uint32 = 0x00020000
const tcCRTSCTS uint32 = (tcCCTS_OFLOW | tcCRTS_IFLOW)

View File

@@ -6,8 +6,44 @@
package serial // import "go.bug.st/serial.v1" package serial // import "go.bug.st/serial.v1"
import "syscall"
// termios manipulation functions // termios manipulation functions
func termiosMask(data uint) uint64 { var baudrateMap = map[int]uint64{
return uint64(data) 0: syscall.B9600, // Default to 9600
50: syscall.B50,
75: syscall.B75,
110: syscall.B110,
134: syscall.B134,
150: syscall.B150,
200: syscall.B200,
300: syscall.B300,
600: syscall.B600,
1200: syscall.B1200,
1800: syscall.B1800,
2400: syscall.B2400,
4800: syscall.B4800,
9600: syscall.B9600,
19200: syscall.B19200,
38400: syscall.B38400,
57600: syscall.B57600,
115200: syscall.B115200,
230400: syscall.B230400,
} }
var databitsMap = map[int]uint64{
0: syscall.CS8, // Default to 8 bits
5: syscall.CS5,
6: syscall.CS6,
7: syscall.CS7,
8: syscall.CS8,
}
const tcCMSPAR uint64 = 0 // may be CMSPAR or PAREXT
const tcIUCLC uint64 = 0
const tcCCTS_OFLOW uint64 = 0x00010000
const tcCRTS_IFLOW uint64 = 0x00020000
const tcCRTSCTS uint64 = (tcCCTS_OFLOW | tcCRTS_IFLOW)

View File

@@ -13,7 +13,7 @@ const regexFilter = "^(cu|tty)\\..*"
// termios manipulation functions // termios manipulation functions
var baudrateMap = map[int]uint{ var baudrateMap = map[int]uint32{
0: syscall.B9600, // Default to 9600 0: syscall.B9600, // Default to 9600
50: syscall.B50, 50: syscall.B50,
75: syscall.B75, 75: syscall.B75,
@@ -37,7 +37,7 @@ var baudrateMap = map[int]uint{
921600: syscall.B921600, 921600: syscall.B921600,
} }
var databitsMap = map[int]uint{ var databitsMap = map[int]uint32{
0: syscall.CS8, // Default to 8 bits 0: syscall.CS8, // Default to 8 bits
5: syscall.CS5, 5: syscall.CS5,
6: syscall.CS6, 6: syscall.CS6,
@@ -45,19 +45,13 @@ var databitsMap = map[int]uint{
8: syscall.CS8, 8: syscall.CS8,
} }
const tcCMSPAR uint = 0 // may be CMSPAR or PAREXT const tcCMSPAR uint32 = 0 // may be CMSPAR or PAREXT
const tcIUCLC uint = 0 const tcIUCLC uint32 = 0
const tcCCTS_OFLOW uint = 0x00010000 const tcCCTS_OFLOW uint32 = 0x00010000
const tcCRTS_IFLOW uint = 0x00020000 const tcCRTS_IFLOW uint32 = 0x00020000
const tcCRTSCTS uint = tcCCTS_OFLOW const tcCRTSCTS uint32 = tcCCTS_OFLOW
func termiosMask(data uint) uint32 {
return uint32(data)
}
// syscall wrappers
//sys ioctl(fd int, req uint64, data uintptr) (err error) //sys ioctl(fd int, req uint64, data uintptr) (err error)

View File

@@ -13,7 +13,7 @@ const regexFilter = "(ttyS|ttyUSB|ttyACM|ttyAMA|rfcomm|ttyO)[0-9]{1,3}"
// termios manipulation functions // termios manipulation functions
var baudrateMap = map[int]uint{ var baudrateMap = map[int]uint32{
0: syscall.B9600, // Default to 9600 0: syscall.B9600, // Default to 9600
50: syscall.B50, 50: syscall.B50,
75: syscall.B75, 75: syscall.B75,
@@ -47,7 +47,7 @@ var baudrateMap = map[int]uint{
4000000: syscall.B4000000, 4000000: syscall.B4000000,
} }
var databitsMap = map[int]uint{ var databitsMap = map[int]uint32{
0: syscall.CS8, // Default to 8 bits 0: syscall.CS8, // Default to 8 bits
5: syscall.CS5, 5: syscall.CS5,
6: syscall.CS6, 6: syscall.CS6,
@@ -55,16 +55,10 @@ var databitsMap = map[int]uint{
8: syscall.CS8, 8: syscall.CS8,
} }
const tcCMSPAR uint = 0 // may be CMSPAR or PAREXT const tcCMSPAR uint32 = 0 // may be CMSPAR or PAREXT
const tcIUCLC = syscall.IUCLC const tcIUCLC = syscall.IUCLC
const tcCRTSCTS uint = 0x80000000 const tcCRTSCTS uint32 = 0x80000000
func termiosMask(data uint) uint32 {
return uint32(data)
}
// syscall wrappers
//sys ioctl(fd int, req uint64, data uintptr) (err error) //sys ioctl(fd int, req uint64, data uintptr) (err error)

View File

@@ -148,38 +148,51 @@ func setTermSettingsBaudrate(speed int, settings *syscall.Termios) error {
return &PortError{code: InvalidSpeed} return &PortError{code: InvalidSpeed}
} }
// revert old baudrate // revert old baudrate
var BAUDMASK uint
for _, rate := range baudrateMap { for _, rate := range baudrateMap {
BAUDMASK |= rate settings.Cflag &^= rate
} }
settings.Cflag &= ^termiosMask(BAUDMASK)
// set new baudrate // set new baudrate
settings.Cflag |= termiosMask(baudrate) settings.Cflag |= baudrate
settings.Ispeed = termiosMask(baudrate) settings.Ispeed = baudrate
settings.Ospeed = termiosMask(baudrate) settings.Ospeed = baudrate
return nil return nil
} }
func setTermSettingsParity(parity Parity, settings *syscall.Termios) error { func setTermSettingsParity(parity Parity, settings *syscall.Termios) error {
switch parity { switch parity {
case NoParity: case NoParity:
settings.Cflag &= ^termiosMask(syscall.PARENB | syscall.PARODD | tcCMSPAR) settings.Cflag &^= syscall.PARENB
settings.Iflag &= ^termiosMask(syscall.INPCK) settings.Cflag &^= syscall.PARODD
settings.Cflag &^= tcCMSPAR
settings.Iflag &^= syscall.INPCK
case OddParity: case OddParity:
settings.Cflag |= termiosMask(syscall.PARENB | syscall.PARODD) settings.Cflag |= syscall.PARENB
settings.Cflag &= ^termiosMask(tcCMSPAR) settings.Cflag |= syscall.PARODD
settings.Iflag |= termiosMask(syscall.INPCK) settings.Cflag &^= tcCMSPAR
settings.Iflag |= syscall.INPCK
case EvenParity: case EvenParity:
settings.Cflag &= ^termiosMask(syscall.PARODD | tcCMSPAR) settings.Cflag |= syscall.PARENB
settings.Cflag |= termiosMask(syscall.PARENB) settings.Cflag &^= syscall.PARODD
settings.Iflag |= termiosMask(syscall.INPCK) settings.Cflag &^= tcCMSPAR
settings.Iflag |= syscall.INPCK
case MarkParity: case MarkParity:
settings.Cflag |= termiosMask(syscall.PARENB | syscall.PARODD | tcCMSPAR) if tcCMSPAR == 0 {
settings.Iflag |= termiosMask(syscall.INPCK) return &PortError{code: InvalidParity}
}
settings.Cflag |= syscall.PARENB
settings.Cflag |= syscall.PARODD
settings.Cflag |= tcCMSPAR
settings.Iflag |= syscall.INPCK
case SpaceParity: case SpaceParity:
settings.Cflag &= ^termiosMask(syscall.PARODD) if tcCMSPAR == 0 {
settings.Cflag |= termiosMask(syscall.PARENB | tcCMSPAR) return &PortError{code: InvalidParity}
settings.Iflag |= termiosMask(syscall.INPCK) }
settings.Cflag |= syscall.PARENB
settings.Cflag &^= syscall.PARODD
settings.Cflag |= tcCMSPAR
settings.Iflag |= syscall.INPCK
default:
return &PortError{code: InvalidParity}
} }
return nil return nil
} }
@@ -189,40 +202,67 @@ func setTermSettingsDataBits(bits int, settings *syscall.Termios) error {
if !ok { if !ok {
return &PortError{code: InvalidDataBits} return &PortError{code: InvalidDataBits}
} }
settings.Cflag &= ^termiosMask(syscall.CSIZE) // Remove previous databits setting
settings.Cflag |= termiosMask(databits) settings.Cflag &^= syscall.CSIZE
// Set requested databits
settings.Cflag |= databits
return nil return nil
} }
func setTermSettingsStopBits(bits StopBits, settings *syscall.Termios) error { func setTermSettingsStopBits(bits StopBits, settings *syscall.Termios) error {
switch bits { switch bits {
case OneStopBit: case OneStopBit:
settings.Cflag &= ^termiosMask(syscall.CSTOPB) settings.Cflag &^= syscall.CSTOPB
case OnePointFiveStopBits, TwoStopBits: case OnePointFiveStopBits:
settings.Cflag |= termiosMask(syscall.CSTOPB) return &PortError{code: InvalidStopBits}
case TwoStopBits:
settings.Cflag |= syscall.CSTOPB
default:
return &PortError{code: InvalidStopBits}
} }
return nil return nil
} }
func setTermSettingsCtsRts(enable bool, settings *syscall.Termios) { func setTermSettingsCtsRts(enable bool, settings *syscall.Termios) {
if enable { if enable {
settings.Cflag |= termiosMask(tcCRTSCTS) settings.Cflag |= tcCRTSCTS
} else { } else {
settings.Cflag &= ^termiosMask(tcCRTSCTS) settings.Cflag &^= tcCRTSCTS
} }
} }
func setRawMode(settings *syscall.Termios) { func setRawMode(settings *syscall.Termios) {
// Set local mode // Set local mode
settings.Cflag |= termiosMask(syscall.CREAD | syscall.CLOCAL) settings.Cflag |= syscall.CREAD
settings.Cflag |= syscall.CLOCAL
// Set raw mode // Set raw mode
settings.Lflag &= ^termiosMask(syscall.ICANON | syscall.ECHO | syscall.ECHOE | syscall.ECHOK | settings.Lflag &^= syscall.ICANON
syscall.ECHONL | syscall.ECHOCTL | syscall.ECHOPRT | syscall.ECHOKE | syscall.ISIG | syscall.IEXTEN) settings.Lflag &^= syscall.ECHO
settings.Iflag &= ^termiosMask(syscall.IXON | syscall.IXOFF | syscall.IXANY | syscall.INPCK | settings.Lflag &^= syscall.ECHOE
syscall.IGNPAR | syscall.PARMRK | syscall.ISTRIP | syscall.IGNBRK | syscall.BRKINT | syscall.INLCR | settings.Lflag &^= syscall.ECHOK
syscall.IGNCR | syscall.ICRNL | tcIUCLC) settings.Lflag &^= syscall.ECHONL
settings.Oflag &= ^termiosMask(syscall.OPOST) settings.Lflag &^= syscall.ECHOCTL
settings.Lflag &^= syscall.ECHOPRT
settings.Lflag &^= syscall.ECHOKE
settings.Lflag &^= syscall.ISIG
settings.Lflag &^= syscall.IEXTEN
settings.Iflag &^= syscall.IXON
settings.Iflag &^= syscall.IXOFF
settings.Iflag &^= syscall.IXANY
settings.Iflag &^= syscall.INPCK
settings.Iflag &^= syscall.IGNPAR
settings.Iflag &^= syscall.PARMRK
settings.Iflag &^= syscall.ISTRIP
settings.Iflag &^= syscall.IGNBRK
settings.Iflag &^= syscall.BRKINT
settings.Iflag &^= syscall.INLCR
settings.Iflag &^= syscall.IGNCR
settings.Iflag &^= syscall.ICRNL
settings.Iflag &^= tcIUCLC
settings.Oflag &^= syscall.OPOST
// Block reads until at least one char is available (no timeout) // Block reads until at least one char is available (no timeout)
settings.Cc[syscall.VMIN] = 1 settings.Cc[syscall.VMIN] = 1