Thread (17 messages) 17 messages, 2 authors, 2017-01-11

imx: RS-485 problems during TX, maybe DMA related

From: Clemens Gruber <hidden>
Date: 2017-01-08 18:06:27
Also in: linux-serial, lkml
Subsystem: the rest, tty layer and serial drivers · Maintainers: Linus Torvalds, Greg Kroah-Hartman, Jiri Slaby

Hi Fabio,

On Sun, Jan 08, 2017 at 12:30:24AM -0200, Fabio Estevam wrote:
Hi Clemens,

On Sat, Jan 7, 2017 at 9:06 PM, Clemens Gruber
[off-list ref] wrote:
quoted
Just remuxed GPIO signals to these pads, applied your two patches and
used rts-gpios in the DT but I still see the same problem :/

When transmit something, I get doubled characters, then zeros and at the
end garbled data of previous transmissions, same as described in my
first post (Logic analyzer: https://pqgruber.com/rs485_results.png)
The data is always 4096 bytes long, this explains why the echo command
is blocking for about 4 seconds (<- 4096 bytes@a baudrate of 9600).
The TE line is also high until all 4096 bytes are sent.

I think this comes from the UART_XMIT_SIZE which is defined to the page
size.
Maybe there is something wrong in imx_transmit_buffer and leads to the
whole circular buffer being sent out all the time, not stopping..

Do these debug logs tell you anything?
https://gist.github.com/clemensg/1ac5ee8a8ea32acc9145c5aa8407aea5

I am analyzing the signals coming directly from the i.MX6Q, so this must
be a software problem, but I don't understand why it works for you, if
we use the same software.

Do you use any other patches on top of mainline and do you use the SDMA
scripts from the ROM?
No, I use the original 4.9 + the two patches I sent. Yes, I do use the
SDMA scripts from ROM.

Here is the procedure I did to try to reproduce the issue you reported:

(The rs485conf is available at:
https://github.com/mniestroj/rs485conf/blob/master/main.c )

First of all I enable rs485 for ttymxc3 using the rs485conf application:

root at imx6qsabresd:/home# ./rs485conf  /dev/ttymxc3 -e 1
[   27.106517] random: crng init done
= Current configuration:
RS485 enabled:                false
RTS on send:                  high
RTS after send:               low
RTS delay before send:        0
RTS delay after send:         0
Receive during sending data:  true

= New configuration:
RS485 enabled:                true
RTS on send:                  high
RTS after send:               low
RTS delay before send:        0
RTS delay after send:         0
Receive during sending data:  true

= Saved configuration:
RS485 enabled:                true
RTS on send:                  high
RTS after send:               low
RTS delay before send:        0
RTS delay after send:         0
Receive during sending data:  true
root at imx6qsabresd:/ho

Then

root at imx6qsabresd:/home# echo A > /dev/ttymxc3

(wait 10 seconds)

root at imx6qsabresd:/home# echo B > /dev/ttymxc3

(wait 10 seconds)

root at imx6qsabresd:/home# echo C > /dev/ttymxc3

On the serial console at 9600bps only the:
A
B
C

are seen, so not duplicated characters, nor noise is seen on the console.
I just did the experiment with your configuration and the rs485conf tool
you mentioned.
But still, no luck :(

What's the revision of the i.MX6Q on your board? Mine is 1.5 (TO 1.3)

Another example: If I run the following on the board..

while true; do
  echo ABCDEFGHIJKLM > /dev/ttymxc4
  sleep 0.5
  echo abc > /dev/ttymxc4 > /dev/ttymxc4
  sleep 0.5
done

Many transmits contain garbled (doubled and sometimes also extended to
a length of 4096 bytes, containing zeros) data.
I can see a few transmissions that are sent correctly, though.

Interesting side note: With the following patch, the problems disappear:
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 451e50f6d77a..eb9f0ce6c34a 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1270,8 +1270,10 @@ static int imx_startup(struct uart_port *port)
 	writel(temp & ~UCR4_DREN, sport->port.membase + UCR4);
 
 	/* Can we enable the DMA support? */
+#if 0
 	if (!uart_console(port) && !sport->dma_is_inited)
 		imx_uart_dma_init(sport);
+#endif
 
 	spin_lock_irqsave(&sport->port.lock, flags);
 	/* Reset fifo's and state machines */
--
Regards,
Clemens
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help