|
| 1 | +package serial |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "syscall" |
| 6 | + "unsafe" |
| 7 | +) |
| 8 | + |
| 9 | +var baudRates = map[int]uint32{ |
| 10 | + 50: syscall.B50, |
| 11 | + 75: syscall.B75, |
| 12 | + 110: syscall.B110, |
| 13 | + 134: syscall.B134, |
| 14 | + 150: syscall.B150, |
| 15 | + 200: syscall.B200, |
| 16 | + 300: syscall.B300, |
| 17 | + 600: syscall.B600, |
| 18 | + 1200: syscall.B1200, |
| 19 | + 1800: syscall.B1800, |
| 20 | + 2400: syscall.B2400, |
| 21 | + 4800: syscall.B4800, |
| 22 | + 9600: syscall.B9600, |
| 23 | + 19200: syscall.B19200, |
| 24 | + 38400: syscall.B38400, |
| 25 | + 57600: syscall.B57600, |
| 26 | + 115200: syscall.B115200, |
| 27 | + 230400: syscall.B230400, |
| 28 | +} |
| 29 | + |
| 30 | +var charSizes = map[int]uint32{ |
| 31 | + 5: syscall.CS5, |
| 32 | + 6: syscall.CS6, |
| 33 | + 7: syscall.CS7, |
| 34 | + 8: syscall.CS8, |
| 35 | +} |
| 36 | + |
| 37 | +// syscallSelect is a wapper for syscall.Select that only returns error. |
| 38 | +func syscallSelect(n int, r *syscall.FdSet, w *syscall.FdSet, e *syscall.FdSet, tv *syscall.Timeval) error { |
| 39 | + return syscall.Select(n, r, w, e, tv) |
| 40 | +} |
| 41 | + |
| 42 | +// tcsetattr sets terminal file descriptor parameters. |
| 43 | +// See man tcsetattr(3). |
| 44 | +func tcsetattr(fd int, termios *syscall.Termios) (err error) { |
| 45 | + r, _, errno := syscall.Syscall(uintptr(syscall.SYS_IOCTL), |
| 46 | + uintptr(fd), uintptr(syscall.TIOCSETA), uintptr(unsafe.Pointer(termios))) |
| 47 | + if errno != 0 { |
| 48 | + err = errno |
| 49 | + return |
| 50 | + } |
| 51 | + if r != 0 { |
| 52 | + err = fmt.Errorf("tcsetattr failed %v", r) |
| 53 | + } |
| 54 | + return |
| 55 | +} |
| 56 | + |
| 57 | +// tcgetattr gets terminal file descriptor parameters. |
| 58 | +// See man tcgetattr(3). |
| 59 | +func tcgetattr(fd int, termios *syscall.Termios) (err error) { |
| 60 | + r, _, errno := syscall.Syscall(uintptr(syscall.SYS_IOCTL), |
| 61 | + uintptr(fd), uintptr(syscall.TIOCGETA), uintptr(unsafe.Pointer(termios))) |
| 62 | + if errno != 0 { |
| 63 | + err = errno |
| 64 | + return |
| 65 | + } |
| 66 | + if r != 0 { |
| 67 | + err = fmt.Errorf("tcgetattr failed %v", r) |
| 68 | + return |
| 69 | + } |
| 70 | + return |
| 71 | +} |
| 72 | + |
| 73 | +// fdget returns index and offset of fd in fds. |
| 74 | +func fdget(fd int, fds *syscall.FdSet) (index, offset int) { |
| 75 | + index = fd / (syscall.FD_SETSIZE / len(fds.Bits)) % len(fds.Bits) |
| 76 | + offset = fd % (syscall.FD_SETSIZE / len(fds.Bits)) |
| 77 | + return |
| 78 | +} |
| 79 | + |
| 80 | +// fdset implements FD_SET macro. |
| 81 | +func fdset(fd int, fds *syscall.FdSet) { |
| 82 | + idx, pos := fdget(fd, fds) |
| 83 | + fds.Bits[idx] = 1 << uint(pos) |
| 84 | +} |
| 85 | + |
| 86 | +// fdisset implements FD_ISSET macro. |
| 87 | +func fdisset(fd int, fds *syscall.FdSet) bool { |
| 88 | + idx, pos := fdget(fd, fds) |
| 89 | + return fds.Bits[idx]&(1<<uint(pos)) != 0 |
| 90 | +} |
0 commit comments