Community
cancel
Showing results for 
Search instead for 
Did you mean: 
FerryT
Valued Contributor I
2,252 Views

HSU (uart) parity check on receive not working?

We might be doing something wrong here, but whatever we try we don't get parity errors detected.

In our setup we are using base64 encoding to transfer binary data as text, so frames are started with STX (0x02) and terminated by ETX (0x03). We precede the STX by 2 PREAMBLES on transmit and require minimum 1 on receive. This way we can always correctly detect the start and end of a frame.

In the ideal case a char with a FE or PE should be translated to 0x00, but whatever we try this doesn't happen.

To test this we used 2 Edisons happily talking to each other at 8bit, 2Mb/s, 1 stop bit, however one is using parity EVEN, the other ODD. This means that a PE happens on every char received. This has been verified by our oscilloscope which has a very clever 'serial decode' function and shows PE for each decoded byte. But the Edisons are both ignoring the PE and not replacing the error byte by 0x00 (or prefixing by 0xFF 0x00, or discarding the char completely). We know the messages are received entirely without errors because we use a CRC32C on the message (after base64 decoding) and toggle a GPIO on success).

I think the kernel code taking care of FE and PE is here; https://github.com/01org/edison-linux/blob/edison-3.10.17/drivers/tty/serial/mfd_core.c https://github.com/01org/edison-linux/blob/edison-3.10.17/drivers/tty/serial/mfd_core.c

Apparently the HSU is not using n_tty.c line dicipline, but doing a new implementation.

In lines 1341 is the serial_hsu_set_termios function, that should be taking care of IGNPAR, INPCK, PARMRK flags (line 1499 - 1517).

We are using MRAA but using the following code to configure the port, because not everything can be set in MRAA (and because of bugs in MRAA we had earlier). I honestly can not see what we are doing wrong here, and I am starting to suspect a problem in the hsu kernel code (although I can't find that problem in the mfd_core.c ref'd above).

The whole problem should be easily reproducible using 2 Edisons (with Arduino carrier) and connecting RX-TX and vice versa (as well as the GND). Our code is here https://github.com/htot/hs_uart https://github.com/htot/hs_uart. If you allow me a day or so, I will push our latest code, which in addition has a command line option to switch from parity ODD to EVEN so you only need to use a single executable on both edisons ./hs_uart for ODD and ./hs_uart -e for EVEN. I will post back here when that has happened.

int

set_interface_attribs (int fd, int speed, tcflag_t parity, int disableFlowControl)

{

struct termios tty;

memset (&tty, 0, sizeof tty);

if (tcgetattr (fd, &tty) != 0)

{

printf ("error %d from tcgetattr", errno);

return -1;

}

cfsetospeed (&tty, speed);

cfsetispeed (&tty, speed);

tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars

// disable IGNBRK for mismatched speed tests; otherwise receive break

// as \000 chars

tty.c_iflag &= ~IGNBRK; // disable break processing

tty.c_lflag = 0; // no signaling chars, no echo,

// no canonical processing

tty.c_oflag = 0; // no remapping, no delays

tty.c_cc[VMIN] = 0; // read doesn't block

tty.c_cc[VTIME] = 0; // no timeout

tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl

tty.c_iflag &= ~IGNPAR; // do not ignore parity and framing errors

tty.c_iflag &= ~PARMRK; // parity or framing error char replaced with \0

tty.c_iflag |= INPCK; // enable parity checking

tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,

// enable reading

tty.c_cflag &= ~(PARENB | PARODD); // shut off parity

tty.c_cflag |= parity;

tty.c_cflag &= ~CSTOPB;

if(disableFlowControl)

tty.c_cflag &= ~CRTSCTS; // no rts/cts

else

tty.c_cflag |= CRTSCTS; // enable rts/cts

if (tcsetattr (fd, TCSANOW, &tty) != 0)

{

printf ("error %d from tcsetattr", errno);

return -1;

<span style="font-family: courier new,courier; font-si...

0 Kudos
5 Replies
FerryT
Valued Contributor I
35 Views

New code uploaded here https://github.com/htot/hs_uart https://github.com/htot/hs_uart. This should allow to reproduce the issue. A quick test to see if the code works would be to loop back the TX and RX and start with the -d option and let it run for a bout 10 seconds. Certain timings are collected and displayed at the end of the run. The program stops when a key is pressed.

 

Ferry

idata
Community Manager
35 Views

Hi Ferry,

 

 

We will try to reproduce it and we will let you know our results.

 

I'm wondering if you have tried our suggestions from this other thread: /thread/104815 https://communities.intel.com/thread/104815. Did you try to edit the configuration from the menuconfig (and then copying the generated defconfig file)? We would like to know if you had any different results.

 

 

Regards,

 

-Pablo
FerryT
Valued Contributor I
35 Views

No, I haven't tried that yet. It's a little bit of work to rebuild yocto, then reflashing, setting up network (again). That's why I hoped to achieve the same by

hsu_dma_enable = 5 or similar (see the last question in /message/415194 https://communities.intel.com/message/415194).

Ferry

FerryT
Valued Contributor I
35 Views

But thinking about the dma question a bit deeper: it's probably not the dma that is causing the delay, but the fifo. And when the fifo is used looking from the code, when a parity error occurs the whole fifo is marked with a parity error (this is not what we are seeing though). So what we probably would need is to set the fifo trigger to 1 byte to effectively disable the fifo and keep dma to make sure the uart get's serviced on time.

But first it would be good to get parity errors detected.

idata
Community Manager
35 Views

Hi Ferry,

 

 

Thank you for your patience. We just want to let you know that this issue is in consideration for a future release of Edison software.

 

 

Regards,

 

-Pablo
Reply