Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

custom baudrate for darwin and linux #113

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
64 changes: 19 additions & 45 deletions serial_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
package serial

import (
"fmt"
"os"
"time"
"unsafe"
Expand All @@ -12,46 +11,7 @@ import (
)

func openPort(name string, baud int, databits byte, parity Parity, stopbits StopBits, readTimeout time.Duration) (p *Port, err error) {
var bauds = map[int]uint32{
50: unix.B50,
75: unix.B75,
110: unix.B110,
134: unix.B134,
150: unix.B150,
200: unix.B200,
300: unix.B300,
600: unix.B600,
1200: unix.B1200,
1800: unix.B1800,
2400: unix.B2400,
4800: unix.B4800,
9600: unix.B9600,
19200: unix.B19200,
38400: unix.B38400,
57600: unix.B57600,
115200: unix.B115200,
230400: unix.B230400,
460800: unix.B460800,
500000: unix.B500000,
576000: unix.B576000,
921600: unix.B921600,
1000000: unix.B1000000,
1152000: unix.B1152000,
1500000: unix.B1500000,
2000000: unix.B2000000,
2500000: unix.B2500000,
3000000: unix.B3000000,
3500000: unix.B3500000,
4000000: unix.B4000000,
}

rate, ok := bauds[baud]

if !ok {
return nil, fmt.Errorf("Unrecognized baud rate")
}

f, err := os.OpenFile(name, unix.O_RDWR|unix.O_NOCTTY|unix.O_NONBLOCK, 0666)
f, err := os.OpenFile(name, unix.O_RDWR|unix.O_NOCTTY|unix.O_NONBLOCK, 0)
if err != nil {
return nil, err
}
Expand All @@ -63,7 +23,7 @@ func openPort(name string, baud int, databits byte, parity Parity, stopbits Stop
}()

// Base settings
cflagToUse := unix.CREAD | unix.CLOCAL | rate
var cflagToUse uint32 = unix.CREAD | unix.CLOCAL | unix.BOTHER | unix.HUPCL
switch databits {
case 5:
cflagToUse |= unix.CS5
Expand Down Expand Up @@ -100,19 +60,33 @@ func openPort(name string, baud int, databits byte, parity Parity, stopbits Stop
}
fd := f.Fd()
vmin, vtime := posixTimeoutValues(readTimeout)
speed := uint32(baud)
t := unix.Termios{
Iflag: unix.IGNPAR,
Cflag: cflagToUse,
Ispeed: rate,
Ospeed: rate,
Ispeed: speed,
Ospeed: speed,
}
t.Cc[unix.VMIN] = vmin
t.Cc[unix.VTIME] = vtime

/*
Raise DTR (open modem) on open. DTR will be set low
again when the connection is closed due to HUPCL.
This should guarantee a correct "restart" action
on some devices.
*/
dtrFlag := unix.TIOCM_DTR
unix.Syscall(
unix.SYS_IOCTL,
uintptr(fd),
uintptr(unix.TIOCMBIS), // set/raise DTR pin
uintptr(unsafe.Pointer(&dtrFlag)))

if _, _, errno := unix.Syscall6(
unix.SYS_IOCTL,
uintptr(fd),
uintptr(unix.TCSETS),
uintptr(unix.TCSETS2),
uintptr(unsafe.Pointer(&t)),
0,
0,
Expand Down
127 changes: 65 additions & 62 deletions serial_posix.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ import (
"errors"
"fmt"
"os"
"runtime"
"syscall"
"time"
//"unsafe"
"unsafe"
)

func openPort(name string, baud int, databits byte, parity Parity, stopbits StopBits, readTimeout time.Duration) (p *Port, err error) {
f, err := os.OpenFile(name, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0666)
f, err := os.OpenFile(name, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0)
if err != nil {
return
}

fd := C.int(f.Fd())
if C.isatty(fd) != 1 {
f.Close()
Expand All @@ -35,54 +35,57 @@ func openPort(name string, baud int, databits byte, parity Parity, stopbits Stop
f.Close()
return nil, err
}
var speed C.speed_t
switch baud {
case 115200:
speed = C.B115200
case 57600:
speed = C.B57600
case 38400:
speed = C.B38400
case 19200:
speed = C.B19200
case 9600:
speed = C.B9600
case 4800:
speed = C.B4800
case 2400:
speed = C.B2400
case 1200:
speed = C.B1200
case 600:
speed = C.B600
case 300:
speed = C.B300
case 200:
speed = C.B200
case 150:
speed = C.B150
case 134:
speed = C.B134
case 110:
speed = C.B110
case 75:
speed = C.B75
case 50:
speed = C.B50
default:
f.Close()
return nil, fmt.Errorf("Unknown baud rate %v", baud)
}

_, err = C.cfsetispeed(&st, speed)
if err != nil {
f.Close()
return nil, err
}
_, err = C.cfsetospeed(&st, speed)
if err != nil {
f.Close()
return nil, err
if runtime.GOOS != "darwin" {
var speed C.speed_t
switch baud {
case 115200:
speed = C.B115200
case 57600:
speed = C.B57600
case 38400:
speed = C.B38400
case 19200:
speed = C.B19200
case 9600:
speed = C.B9600
case 4800:
speed = C.B4800
case 2400:
speed = C.B2400
case 1200:
speed = C.B1200
case 600:
speed = C.B600
case 300:
speed = C.B300
case 200:
speed = C.B200
case 150:
speed = C.B150
case 134:
speed = C.B134
case 110:
speed = C.B110
case 75:
speed = C.B75
case 50:
speed = C.B50
default:
f.Close()
return nil, fmt.Errorf("Unknown baud rate %v", baud)
}

_, err = C.cfsetispeed(&st, speed)
if err != nil {
f.Close()
return nil, err
}
_, err = C.cfsetospeed(&st, speed)
if err != nil {
f.Close()
return nil, err
}
}

// Turn off break interrupts, CR->NL, Parity checks, strip, and IXON
Expand Down Expand Up @@ -145,7 +148,6 @@ func openPort(name string, baud int, databits byte, parity Parity, stopbits Stop
return nil, err
}

//fmt.Println("Tweaking", name)
r1, _, e := syscall.Syscall(syscall.SYS_FCNTL,
uintptr(f.Fd()),
uintptr(syscall.F_SETFL),
Expand All @@ -156,17 +158,18 @@ func openPort(name string, baud int, databits byte, parity Parity, stopbits Stop
return nil, errors.New(s)
}

/*
r1, _, e = syscall.Syscall(syscall.SYS_IOCTL,
uintptr(f.Fd()),
uintptr(0x80045402), // IOSSIOSPEED
uintptr(unsafe.Pointer(&baud)));
if e != 0 || r1 != 0 {
s := fmt.Sprint("Baudrate syscall error:", e, r1)
f.Close()
return nil, os.NewError(s)
}
*/
if runtime.GOOS == "darwin" {
b := C.speed_t(baud)
r1, _, e = syscall.Syscall(syscall.SYS_IOCTL,
uintptr(f.Fd()),
uintptr(0x80045402), // IOSSIOSPEED
uintptr(unsafe.Pointer(&b)))
if e != 0 || r1 != 0 {
s := fmt.Sprint("Baudrate syscall error:", e, r1)
f.Close()
return nil, errors.New(s)
}
}

return &Port{f: f}, nil
}
Expand Down