Lonko
Lonko

Reputation: 379

c++ serial communication linux 9data bits

a bit exotic question :D

I'm programming c++ in ubuntu 10 and i need to code a mdb(multi drop bus) protocol which uses 9 data bits in serial communication (YES 9 data bits :D)

Some drivers do support 9 data bits on some uart chips, but mostly they do not.

To explain briefly: mdb uses 8 data bits for data and 9th data bit for mode set. So when master sends first BYTE it sets mode=9thbit to 1 which means that all devices on the bus are interrupted and are looking for this first byte that holds the address of a device. If the listening device (one of many) finds its address in this first byte it knows that the following bytes will be data bytes for it. data bytes have bit 9 = mode bit set to 0

example in bits: 000001011 000000010 000000100 000000110 (1stbyte address and 3 data bytes)

The return situation from slave -> master mode bit is used for end of transmission. So the master reads from serial so long until it finds a 9bit packet that has 9th bit = 1 usualy the last 9bit sequence is a chk byte + mode = 1

So finally my question:

I know how to user CMPAR flag in termios to use parity bit for mode bit eg. setting it to either MARK(1) or SPACE(0)

example FOR ALL that don't know how:

First check if this is defined if not probably no support in termios:

    # define CMSPAR   010000000000      /* mark or space (stick) parity */

And the code for sending with mark or space parity eg. simulating 9th data bit

   struct termios tio;
    bzero(&tio, sizeof(tio));
    tcgetattr(portFileDescriptor, &tio);

    if(useMarkParity)
    {
            // Send with mark parity
            tio.c_cflag |= PARENB | CMSPAR | PARODD;
            tcsetattr(portFileDescriptor, TCSADRAIN, &tio);

    }
    else
    {
            // Send  with space parity
            tio.c_cflag |= PARENB | CMSPAR;
            tio.c_cflag &= ~PARODD;
            tcsetattr(portFileDescriptor, TCSADRAIN, &tio);
    }
    write(portFileDescriptor,DATA, DATALEN);

Now what i don't know HOW to set the parity checking on receive, i have tried almost all combinations and i cannot get that error parity byte sequence.

Can anyone help me how to set parity checking on receive that it does not ignore parity and does not strip bytes but it adds DEL before "bad" received byte:

As it says in the POSIX Serial help

INPCK and PARMRK If IGNPAR is enabled, a NUL character (000 octal) is sent to your program before every character with a parity error. Otherwise, a DEL (177 octal) and NUL character is sent along with the bad character.

So how to correctly set PARMRK AND INPCK that it will detect mode bit = 1 as parity bit error and insert DEL 177 octal in the return stream.

Thank you :D

Upvotes: 2

Views: 5207

Answers (2)

Dan George
Dan George

Reputation: 51

I was having the same problem running in a Linux guest OS. Running the same program on another machine with Linux as the host OS works. I suspect that the virtual serial port does not pass on the parity error. See PARMRK termios behavior not working on Linux. It is still possible that the VM is not the problem because it was a completely different computer. I was able to get parity errors using Realterm in Windows (the host OS on the computer where Linux was the guest), however.

Also, note the code in n_tty.c shows it inserts '\377' '\0' rather than '\177' '\0'. This was also verified on the working configuration.

Upvotes: 0

Jim Rhodes
Jim Rhodes

Reputation: 5095

It sounds to me like you want to set space parity on the receiver and don't enable IGNPAR. That way when a byte with mark parity is received it should generate the parity error with the DEL.

Upvotes: 1

Related Questions