Created
May 13, 2014 19:44
-
-
Save macmania/757410a44f56c2c36df8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // +build !windows,cgo | |
| package serial | |
| // #include <termios.h> | |
| // #include <unistd.h> | |
| import "C" | |
| // TODO: Maybe change to using syscall package + ioctl instead of cgo | |
| import ( | |
| "errors" | |
| "fmt" | |
| "io" | |
| "os" | |
| "syscall" | |
| "unsafe" | |
| ) | |
| func openPort(name string, baud int) (rwc io.ReadWriteCloser, err error) { | |
| f, err := os.OpenFile(name, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0666) | |
| if err != nil { | |
| return | |
| } | |
| fd := C.int(f.Fd()) | |
| if C.isatty(fd) != 1 { | |
| f.Close() | |
| return nil, errors.New("File is not a tty") | |
| } | |
| var st C.struct_termios | |
| _, err = C.tcgetattr(fd, &st) | |
| if err != nil { | |
| 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 | |
| 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 | |
| } | |
| // Select local mode | |
| st.c_cflag |= (C.CLOCAL | C.CREAD) | |
| // Select raw mode | |
| st.c_lflag &= ^C.tcflag_t(C.ICANON | C.ECHO | C.ECHOE | C.ISIG) | |
| st.c_oflag &= ^C.tcflag_t(C.OPOST) | |
| _, err = C.tcsetattr(fd, C.TCSANOW, &st) | |
| if err != nil { | |
| f.Close() | |
| return nil, err | |
| } | |
| //fmt.Println("Tweaking", name) | |
| r1, _, e := syscall.Syscall(syscall.SYS_FCNTL, | |
| uintptr(f.Fd()), | |
| uintptr(syscall.F_SETFL), | |
| uintptr(0)) | |
| if e != 0 || r1 != 0 { | |
| s := fmt.Sprint("Clearing NONBLOCK syscall error:", e, r1) | |
| f.Close() | |
| 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) | |
| } | |
| */ | |
| return f, nil | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment