Merge branch 'bit-fixes' into v1
This commit is contained in:
12
serial.go
12
serial.go
@@ -94,6 +94,10 @@ const (
|
||||
InvalidSpeed
|
||||
// InvalidDataBits the number of data bits is not valid or not supported
|
||||
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
|
||||
)
|
||||
@@ -110,9 +114,13 @@ func (e PortError) EncodedErrorString() string {
|
||||
case PermissionDenied:
|
||||
return "Permission denied"
|
||||
case InvalidSpeed:
|
||||
return "Invalid port speed"
|
||||
return "Port speed invalid or not supported"
|
||||
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:
|
||||
return "Could not enumerate serial ports"
|
||||
default:
|
||||
|
||||
@@ -11,48 +11,6 @@ import "syscall"
|
||||
const devFolder = "/dev"
|
||||
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)
|
||||
|
||||
const ioctlTcgetattr = syscall.TIOCGETA
|
||||
|
||||
@@ -6,6 +6,44 @@
|
||||
|
||||
package serial // import "go.bug.st/serial.v1"
|
||||
|
||||
func termiosMask(data uint) uint32 {
|
||||
return uint32(data)
|
||||
import "syscall"
|
||||
|
||||
// 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)
|
||||
|
||||
@@ -6,8 +6,44 @@
|
||||
|
||||
package serial // import "go.bug.st/serial.v1"
|
||||
|
||||
import "syscall"
|
||||
|
||||
// termios manipulation functions
|
||||
|
||||
func termiosMask(data uint) uint64 {
|
||||
return uint64(data)
|
||||
var baudrateMap = map[int]uint64{
|
||||
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)
|
||||
|
||||
@@ -13,7 +13,7 @@ const regexFilter = "^(cu|tty)\\..*"
|
||||
|
||||
// termios manipulation functions
|
||||
|
||||
var baudrateMap = map[int]uint{
|
||||
var baudrateMap = map[int]uint32{
|
||||
0: syscall.B9600, // Default to 9600
|
||||
50: syscall.B50,
|
||||
75: syscall.B75,
|
||||
@@ -37,7 +37,7 @@ var baudrateMap = map[int]uint{
|
||||
921600: syscall.B921600,
|
||||
}
|
||||
|
||||
var databitsMap = map[int]uint{
|
||||
var databitsMap = map[int]uint32{
|
||||
0: syscall.CS8, // Default to 8 bits
|
||||
5: syscall.CS5,
|
||||
6: syscall.CS6,
|
||||
@@ -45,19 +45,13 @@ var databitsMap = map[int]uint{
|
||||
8: syscall.CS8,
|
||||
}
|
||||
|
||||
const tcCMSPAR uint = 0 // may be CMSPAR or PAREXT
|
||||
const tcIUCLC uint = 0
|
||||
const tcCMSPAR uint32 = 0 // may be CMSPAR or PAREXT
|
||||
const tcIUCLC uint32 = 0
|
||||
|
||||
const tcCCTS_OFLOW uint = 0x00010000
|
||||
const tcCRTS_IFLOW uint = 0x00020000
|
||||
const tcCCTS_OFLOW uint32 = 0x00010000
|
||||
const tcCRTS_IFLOW uint32 = 0x00020000
|
||||
|
||||
const tcCRTSCTS uint = tcCCTS_OFLOW
|
||||
|
||||
func termiosMask(data uint) uint32 {
|
||||
return uint32(data)
|
||||
}
|
||||
|
||||
// syscall wrappers
|
||||
const tcCRTSCTS uint32 = tcCCTS_OFLOW
|
||||
|
||||
//sys ioctl(fd int, req uint64, data uintptr) (err error)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ const regexFilter = "(ttyS|ttyUSB|ttyACM|ttyAMA|rfcomm|ttyO)[0-9]{1,3}"
|
||||
|
||||
// termios manipulation functions
|
||||
|
||||
var baudrateMap = map[int]uint{
|
||||
var baudrateMap = map[int]uint32{
|
||||
0: syscall.B9600, // Default to 9600
|
||||
50: syscall.B50,
|
||||
75: syscall.B75,
|
||||
@@ -47,7 +47,7 @@ var baudrateMap = map[int]uint{
|
||||
4000000: syscall.B4000000,
|
||||
}
|
||||
|
||||
var databitsMap = map[int]uint{
|
||||
var databitsMap = map[int]uint32{
|
||||
0: syscall.CS8, // Default to 8 bits
|
||||
5: syscall.CS5,
|
||||
6: syscall.CS6,
|
||||
@@ -55,16 +55,10 @@ var databitsMap = map[int]uint{
|
||||
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 tcCRTSCTS uint = 0x80000000
|
||||
|
||||
func termiosMask(data uint) uint32 {
|
||||
return uint32(data)
|
||||
}
|
||||
|
||||
// syscall wrappers
|
||||
const tcCRTSCTS uint32 = 0x80000000
|
||||
|
||||
//sys ioctl(fd int, req uint64, data uintptr) (err error)
|
||||
|
||||
|
||||
106
serial_unix.go
106
serial_unix.go
@@ -148,38 +148,51 @@ func setTermSettingsBaudrate(speed int, settings *syscall.Termios) error {
|
||||
return &PortError{code: InvalidSpeed}
|
||||
}
|
||||
// revert old baudrate
|
||||
var BAUDMASK uint
|
||||
for _, rate := range baudrateMap {
|
||||
BAUDMASK |= rate
|
||||
settings.Cflag &^= rate
|
||||
}
|
||||
settings.Cflag &= ^termiosMask(BAUDMASK)
|
||||
// set new baudrate
|
||||
settings.Cflag |= termiosMask(baudrate)
|
||||
settings.Ispeed = termiosMask(baudrate)
|
||||
settings.Ospeed = termiosMask(baudrate)
|
||||
settings.Cflag |= baudrate
|
||||
settings.Ispeed = baudrate
|
||||
settings.Ospeed = baudrate
|
||||
return nil
|
||||
}
|
||||
|
||||
func setTermSettingsParity(parity Parity, settings *syscall.Termios) error {
|
||||
switch parity {
|
||||
case NoParity:
|
||||
settings.Cflag &= ^termiosMask(syscall.PARENB | syscall.PARODD | tcCMSPAR)
|
||||
settings.Iflag &= ^termiosMask(syscall.INPCK)
|
||||
settings.Cflag &^= syscall.PARENB
|
||||
settings.Cflag &^= syscall.PARODD
|
||||
settings.Cflag &^= tcCMSPAR
|
||||
settings.Iflag &^= syscall.INPCK
|
||||
case OddParity:
|
||||
settings.Cflag |= termiosMask(syscall.PARENB | syscall.PARODD)
|
||||
settings.Cflag &= ^termiosMask(tcCMSPAR)
|
||||
settings.Iflag |= termiosMask(syscall.INPCK)
|
||||
settings.Cflag |= syscall.PARENB
|
||||
settings.Cflag |= syscall.PARODD
|
||||
settings.Cflag &^= tcCMSPAR
|
||||
settings.Iflag |= syscall.INPCK
|
||||
case EvenParity:
|
||||
settings.Cflag &= ^termiosMask(syscall.PARODD | tcCMSPAR)
|
||||
settings.Cflag |= termiosMask(syscall.PARENB)
|
||||
settings.Iflag |= termiosMask(syscall.INPCK)
|
||||
settings.Cflag |= syscall.PARENB
|
||||
settings.Cflag &^= syscall.PARODD
|
||||
settings.Cflag &^= tcCMSPAR
|
||||
settings.Iflag |= syscall.INPCK
|
||||
case MarkParity:
|
||||
settings.Cflag |= termiosMask(syscall.PARENB | syscall.PARODD | tcCMSPAR)
|
||||
settings.Iflag |= termiosMask(syscall.INPCK)
|
||||
if tcCMSPAR == 0 {
|
||||
return &PortError{code: InvalidParity}
|
||||
}
|
||||
settings.Cflag |= syscall.PARENB
|
||||
settings.Cflag |= syscall.PARODD
|
||||
settings.Cflag |= tcCMSPAR
|
||||
settings.Iflag |= syscall.INPCK
|
||||
case SpaceParity:
|
||||
settings.Cflag &= ^termiosMask(syscall.PARODD)
|
||||
settings.Cflag |= termiosMask(syscall.PARENB | tcCMSPAR)
|
||||
settings.Iflag |= termiosMask(syscall.INPCK)
|
||||
if tcCMSPAR == 0 {
|
||||
return &PortError{code: InvalidParity}
|
||||
}
|
||||
settings.Cflag |= syscall.PARENB
|
||||
settings.Cflag &^= syscall.PARODD
|
||||
settings.Cflag |= tcCMSPAR
|
||||
settings.Iflag |= syscall.INPCK
|
||||
default:
|
||||
return &PortError{code: InvalidParity}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -189,40 +202,67 @@ func setTermSettingsDataBits(bits int, settings *syscall.Termios) error {
|
||||
if !ok {
|
||||
return &PortError{code: InvalidDataBits}
|
||||
}
|
||||
settings.Cflag &= ^termiosMask(syscall.CSIZE)
|
||||
settings.Cflag |= termiosMask(databits)
|
||||
// Remove previous databits setting
|
||||
settings.Cflag &^= syscall.CSIZE
|
||||
// Set requested databits
|
||||
settings.Cflag |= databits
|
||||
return nil
|
||||
}
|
||||
|
||||
func setTermSettingsStopBits(bits StopBits, settings *syscall.Termios) error {
|
||||
switch bits {
|
||||
case OneStopBit:
|
||||
settings.Cflag &= ^termiosMask(syscall.CSTOPB)
|
||||
case OnePointFiveStopBits, TwoStopBits:
|
||||
settings.Cflag |= termiosMask(syscall.CSTOPB)
|
||||
settings.Cflag &^= syscall.CSTOPB
|
||||
case OnePointFiveStopBits:
|
||||
return &PortError{code: InvalidStopBits}
|
||||
case TwoStopBits:
|
||||
settings.Cflag |= syscall.CSTOPB
|
||||
default:
|
||||
return &PortError{code: InvalidStopBits}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setTermSettingsCtsRts(enable bool, settings *syscall.Termios) {
|
||||
if enable {
|
||||
settings.Cflag |= termiosMask(tcCRTSCTS)
|
||||
settings.Cflag |= tcCRTSCTS
|
||||
} else {
|
||||
settings.Cflag &= ^termiosMask(tcCRTSCTS)
|
||||
settings.Cflag &^= tcCRTSCTS
|
||||
}
|
||||
}
|
||||
|
||||
func setRawMode(settings *syscall.Termios) {
|
||||
// Set local mode
|
||||
settings.Cflag |= termiosMask(syscall.CREAD | syscall.CLOCAL)
|
||||
settings.Cflag |= syscall.CREAD
|
||||
settings.Cflag |= syscall.CLOCAL
|
||||
|
||||
// Set raw mode
|
||||
settings.Lflag &= ^termiosMask(syscall.ICANON | syscall.ECHO | syscall.ECHOE | syscall.ECHOK |
|
||||
syscall.ECHONL | syscall.ECHOCTL | syscall.ECHOPRT | syscall.ECHOKE | syscall.ISIG | syscall.IEXTEN)
|
||||
settings.Iflag &= ^termiosMask(syscall.IXON | syscall.IXOFF | syscall.IXANY | syscall.INPCK |
|
||||
syscall.IGNPAR | syscall.PARMRK | syscall.ISTRIP | syscall.IGNBRK | syscall.BRKINT | syscall.INLCR |
|
||||
syscall.IGNCR | syscall.ICRNL | tcIUCLC)
|
||||
settings.Oflag &= ^termiosMask(syscall.OPOST)
|
||||
settings.Lflag &^= syscall.ICANON
|
||||
settings.Lflag &^= syscall.ECHO
|
||||
settings.Lflag &^= syscall.ECHOE
|
||||
settings.Lflag &^= syscall.ECHOK
|
||||
settings.Lflag &^= syscall.ECHONL
|
||||
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)
|
||||
settings.Cc[syscall.VMIN] = 1
|
||||
|
||||
Reference in New Issue
Block a user