Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is mark and space parity possible using boost.asio?

I cannot seen to get the serial port set up correctly using the termios structure so i am looking at third party libraries.

I have been advised to try boost.asio but when looking through the examples it appears that it does not support mark and space parity, is this true?

If it is possible could someone show example code on how to do mark and space parity in boost.asio. I am using 8 databits, 115220 baud rate and 1 stop bit.

Does anyone know of any third party libraries that support mark and space parity on linux that I can use instead of boost?

like image 500
Skeith Avatar asked Oct 18 '11 11:10

Skeith


1 Answers

There is a very good article on this problem here.

In particular

MARK and SPACE parity, although implemented in most hardware, are not defined in the POSIX standard. The manpage of of the Unix/Linux termios library, for instance, doesn't loose a single word about these two parity modes. (Note that PARMRK has nothing to do with MARK parity.)

This is why, I think, these options are not implemented in Boost.Asio.

There are a number of solutions suggested: For example:

The mode 8M1 (8 data bits, MARK parity, 1 stop bit) can be emulated with 8N2. Instead of sending a parity bit and a stop bit, two stop bits are transmitted. Since stop bits are always 1 (mark bits), the two modes are equivalent.

If these don't match your requirements then you can get the native representation of your serial port in boost asio. From the docs:

basic_serial_port::native_handle

Get the native serial port representation.

native_handle_type native_handle();
This function may be used to obtain the underlying representation of the serial port. This is intended to allow access to native serial port functionality that is not otherwise provided.

To get an idea of usage have a look at

boost_1_45_0/boost/asio/serial_port_base.hpp

and in particular the code to do with parity on linux:

switch (value_)
  {
  case none:
    storage.c_iflag |= IGNPAR;
    storage.c_cflag &= ~(PARENB | PARODD);
    break;
  case even:
    storage.c_iflag &= ~(IGNPAR | PARMRK);
    storage.c_iflag |= INPCK;
    storage.c_cflag |= PARENB;
    storage.c_cflag &= ~PARODD;
    break;
  case odd:
    storage.c_iflag &= ~(IGNPAR | PARMRK);
    storage.c_iflag |= INPCK;
    storage.c_cflag |= (PARENB | PARODD);
    break;
  default:
    break;
  }

I think you want to use the native_handle to set set the flag something like so:

cflag |= PARENB | CMSPAR // To select SPACE parity
cflag &= ~PARODD

cflag |= PARENB | CMSPAR | PARODD // to select MARK parity

(according to here, anyway) Also see wrong sequence of libserial received data

like image 121
Tom Avatar answered Sep 24 '22 20:09

Tom