Beispiel #1
0
func (bp *baseport) SetReadParams(minread int, timeout float64) error {
	inttimeout := int(timeout * 10)
	if inttimeout < 0 {
		return &ParameterError{"timeout", "needs to be 0 or higher"}
	}
	// if a timeout is desired but too small for the termios timeout
	// granularity, set the minimum timeout
	if timeout > 0 && inttimeout == 0 {
		inttimeout = 1
	}

	tio, err := bp.getattr()
	if err != nil {
		return &Error{"getattr", err}
	}

	tio.c_cc[C.VMIN] = C.cc_t(minread)
	tio.c_cc[C.VTIME] = C.cc_t(inttimeout)

	//fmt.Printf("baud rates from termios: %d, %d\n", tio.c_ispeed, tio.c_ospeed)

	err = bp.setattr(tio)
	if err != nil {
		return &Error{"setattr", err}
	}

	return nil
}
Beispiel #2
0
func makeCAttributes(attr *Attributes) C.struct_termios {
	var cattr C.struct_termios
	cattr.c_iflag = C.tcflag_t(attr.Input)
	cattr.c_oflag = C.tcflag_t(attr.Output)
	cattr.c_cflag = C.tcflag_t(attr.Control)
	cattr.c_lflag = C.tcflag_t(attr.Local)
	for i := 0; i < C.NCCS; i++ {
		cattr.c_cc[i] = C.cc_t(attr.ControlChars[i])
	}
	return cattr
}
Beispiel #3
0
func cTermios(goTerm *Termios) *C.struct_termios {
	var cTerm C.struct_termios

	cTerm.c_iflag = C.tcflag_t(goTerm.IFlag)
	cTerm.c_oflag = C.tcflag_t(goTerm.OFlag)
	cTerm.c_cflag = C.tcflag_t(goTerm.CFlag)
	cTerm.c_lflag = C.tcflag_t(goTerm.LFlag)
	for idx, ch := range goTerm.CC {
		cTerm.c_cc[idx] = C.cc_t(ch)
	}
	cTerm.c_ispeed = C.speed_t(goTerm.ISpeed)
	cTerm.c_ospeed = C.speed_t(goTerm.OSpeed)

	return &cTerm
}
Beispiel #4
0
func openPort(name string, baud int, readTimeout time.Duration) (p *Port, 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
	}

	// Turn off break interrupts, CR->NL, Parity checks, strip, and IXON
	st.c_iflag &= ^C.tcflag_t(C.BRKINT | C.ICRNL | C.INPCK | C.ISTRIP | C.IXOFF | C.IXON | C.PARMRK)

	// Select local mode, turn off parity, set to 8 bits
	st.c_cflag &= ^C.tcflag_t(C.CSIZE | C.PARENB)
	st.c_cflag |= (C.CLOCAL | C.CREAD | C.CS8)

	// 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)

	// set blocking / non-blocking read
	/*
	*	http://man7.org/linux/man-pages/man3/termios.3.html
	* - Supports blocking read and read with timeout operations
	 */
	vmin, vtime := posixTimeoutValues(readTimeout)
	st.c_cc[C.VMIN] = C.cc_t(vmin)
	st.c_cc[C.VTIME] = C.cc_t(vtime)

	_, 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 &Port{f: f}, nil
}
Beispiel #5
0
// SetVMin sets the minimal number of characters for noncanonical read.
func (term *Termios) SetVMin(v uint8) {
	term.c_cc[C.VMIN] = C.cc_t(v)
}
Beispiel #6
0
// SetVTime sets the timeout in deciseconds for noncanonical read.
func (term *Termios) SetVTime(v uint8) {
	term.c_cc[C.VTIME] = C.cc_t(v)
}
Beispiel #7
0
// CcSet sets the Termios control character in index idx to c.
func (t *Termios) CcSet(idx int, c Cc) { t.t.c_cc[idx] = C.cc_t(c) }