diff --git a/serial.go b/serial.go index b6854e6..0b403da 100644 --- a/serial.go +++ b/serial.go @@ -17,8 +17,21 @@ type SerialPort interface { // Set port speed SetSpeed(baudrate int) error + + // Set port parity + SetParity(parity Parity) error } +type Parity int + +const ( + PARITY_NONE Parity = iota + PARITY_ODD + PARITY_EVEN + PARITY_MARK + PARITY_SPACE +) + // Platform independent error type for serial ports type SerialPortError struct { err string diff --git a/serial_linux.go b/serial_linux.go index da75536..aeb2659 100644 --- a/serial_linux.go +++ b/serial_linux.go @@ -24,6 +24,14 @@ package serial static const tcflag_t IUCLC = 0; #endif +#if defined(PAREXT) + const tcflag_t FIXED_PAR_FLAG = PAREXT; +#elif defined(CMSPAR) + const tcflag_t FIXED_PAR_FLAG = CMSPAR; +#else + const tcflag_t FIXED_PAR_FLAG = 0; +#endif + // ioctl call is not available through syscall package //int ioctl_wrapper(int d, unsigned long request) { // return ioctl(d, request); @@ -209,6 +217,34 @@ func (port *linuxSerialPort) SetSpeed(speed int) error { return setTermSettings(port.Handle, settings) } +func (port *linuxSerialPort) SetParity(parity Parity) error { + settings, err := getTermSettings(port.Handle) + if err != nil { + return err + } + switch parity { + case PARITY_NONE: + settings.c_cflag &= ^C.tcflag_t(syscall.PARENB | syscall.PARODD | C.FIXED_PAR_FLAG) + settings.c_iflag &= ^C.tcflag_t(syscall.INPCK) + case PARITY_ODD: + settings.c_cflag |= syscall.PARENB | syscall.PARODD + settings.c_cflag &= ^C.tcflag_t(C.FIXED_PAR_FLAG) + settings.c_iflag |= syscall.INPCK + case PARITY_EVEN: + settings.c_cflag &= ^C.tcflag_t(syscall.PARODD | C.FIXED_PAR_FLAG) + settings.c_cflag |= syscall.PARENB + settings.c_iflag |= syscall.INPCK + case PARITY_MARK: + settings.c_cflag |= syscall.PARENB | syscall.PARODD | C.FIXED_PAR_FLAG + settings.c_iflag |= syscall.INPCK + case PARITY_SPACE: + settings.c_cflag &= ^C.tcflag_t(syscall.PARODD) + settings.c_cflag |= syscall.PARENB | C.FIXED_PAR_FLAG + settings.c_iflag |= syscall.INPCK + } + return setTermSettings(port.Handle, settings) +} + func OpenPort(portName string, exclusive bool) (SerialPort, error) { handle, err := syscall.Open(portName, syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NDELAY, 0) if err != nil { diff --git a/test/serial_test.go b/test/serial_test.go index 384d70e..15d29d4 100644 --- a/test/serial_test.go +++ b/test/serial_test.go @@ -27,8 +27,10 @@ func ExampleCommunication() { if err != nil { log.Fatal(err) } - err = port.SetSpeed(9600) - if err != nil { + if err = port.SetSpeed(9600); err != nil { + log.Fatal(err) + } + if err := port.SetParity(serial.PARITY_NONE); err != nil { log.Fatal(err) }