i.MX6 UART hardware misbehaves on baudrate mismatch

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX6 UART hardware misbehaves on baudrate mismatch

Jump to solution
5,645 Views
TroyKisky
Contributor II

I have a weird serial port issue. When I initialize uart1 at 19200,8,n,1
and send the letter 'b' at 115200,8,n,1 then the uart will continuously
receive 0xff's. Sometimes I have to send 'b' twice to get into this weird
state. Then, when I type the letter 'a', it gets out of this state.

I've done this on a board with a i.MX6Q and a board with a i.MX6S (solo) processor.

Here's test results under u-boot to get any software issues out of the mix,
but I've seen the same results using Linux.

Note: uart1 base 02020000(URXD), uart2 is u-boot console.


/* 1st initialize same as Linux for 19200,8,n,1 */
U-Boot > mw.l 02020080 00000221 && mw.l 02020084 00004027 && mw.l 02020088 00000704 && mw.l 0202008c
00004000
U-Boot > mw.l 02020090 00000b01 && mw.l 02020094 00002040 && mw.l 02020098 00005088 && mw.l 0202009c
0000002b
U-Boot > mw.l 020200a0 00000000 && mw.l 020200a4 00000053 && mw.l 020200a8 00000c34
U-Boot > mw.l 020200b0 00002ca4 && mw.l 020200b4 00000060 && mw.l 020200b8 00000000
U-Boot > md.l 02020000 1
02020000: 00000000                               ....
U-Boot > #press a at 19200,8,n,1
U-Boot > md.l 02020000 1
02020000: 00008061                               a...
U-Boot > md.l 02020000 1
02020000: 00000000                               ....

U-Boot > #press b at 19200
U-Boot > md.l 02020000 1
02020000: 00008062                               b...
U-Boot > md.l 02020000 1
02020000: 00000000                               ....
U-Boot > #press b at 115200,8,n,1
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 00000000                               ....
U-Boot > md.l 02020000 1
02020000: 00000000                               ....
U-Boot > md.l 02020000 1
02020000: 00000000                               ....
U-Boot > #press b at 115200,8,n,1
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > #press a at 115200,8,n,1
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 000080ff                               ....
U-Boot > md.l 02020000 1
02020000: 0000e0ff                               ....
U-Boot > md.l 02020000 1
02020000: 0000e0ff                               ....
U-Boot > md.l 02020000 1
02020000: 0000e0ff                               ....
U-Boot > md.l 02020000 1
02020000: 0000e0ff                               ....
U-Boot > md.l 02020000 1
02020000: 0000e0ff                               ....
U-Boot > md.l 02020000 1
02020000: 0000e0ff                               ....
U-Boot > md.l 02020000 1
02020000: 0000e0ff                               ....
U-Boot > md.l 02020000 1
02020000: 0000e0ff                               ....
U-Boot > md.l 02020000 1
02020000: 0000e0ff                               ....
U-Boot > md.l 02020000 1
02020000: 0000e0ff                               ....
U-Boot > md.l 02020000 1
02020000: 000000ff                               ....
U-Boot > md.l 02020000 1
02020000: 000000ff                               ....
U-Boot > #press c at 19200
U-Boot > md.l 02020000 1
02020000: 00008063                               c...
U-Boot > md.l 02020000 1
02020000: 000000ff                               ....
U-Boot >

Labels (3)
Tags (2)
0 Kudos
1 Solution
3,063 Views
EricNelson
Senior Contributor II

Digging through the UART registers to see if we have something mis-configured, I think I've stumbled on a clue, if not a fix.

The problem seems to go away if bit 7 of UCR3 (ADNIMP in the reference manual) is set.

U-Boot > mm.l 021e8088
021e8088: 00000704 ? 0784
021e808c: 00008000 ? x
...
... problem doesn't happen.

The manual says this about the bit:

Autobaud Detection Not Improved-. Disables new features of autobaud detection (See Baud Rate Automatic Detection Protocol, for more details).

0 Autobaud detection new features selected
1 Keep old autobaud detection mechanism

View solution in original post

0 Kudos
20 Replies
3,063 Views
EricNelson
Senior Contributor II

There's an easier way to test for this condition on machines running U-Boot.

Most boards with i.MX6 use U-Boot with a serial console at 115200, and you can change the baud rate using the magic 'baudrate' environment variable:


U-Boot > setenv baudrate 19200
## Switch baudrate to 19200 bps and press ENTER ...

Unfortunately, U-Boot will silently eat the '\xff' characters reeceived though, and this change is needed so that you can see the result:

diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c
index 56bee55..ef308dc 100644
--- a/drivers/serial/serial_mxc.c
+++ b/drivers/serial/serial_mxc.c
@@ -145,9 +145,13 @@ static void mxc_serial_setbrg(void)

static int mxc_serial_getc(void)
{
+      unsigned char rx;
        while (__REG(UART_PHYS + UTS) & UTS_RXEMPTY)
                WATCHDOG_RESET();
-      return (__REG(UART_PHYS + URXD) & URXD_RX_DATA); /* mask out status from upper word */
+      rx = (__REG(UART_PHYS + URXD) & URXD_RX_DATA); /* mask out status from upper word */
+      if (0x80 <= rx)
+              rx = '?';
+      return rx;
}

Using this, you won't need a second serial connection to the machine.

We've tested this using main-line U-Boot on our boards, and U-Boot 2009.08 and U-Boot 2013.04 releases on SABRE SDB.

FabioEstevam also reported that he was able to reproduce this (I'm not sure which board).

0 Kudos
3,055 Views
EricNelson
Senior Contributor II

An even easier test is to use stty at a Linux shell:

     # stty -F /dev/ttymxc1 19200

And then enter a 'b' at 115200.

0 Kudos
3,064 Views
EricNelson
Senior Contributor II

Digging through the UART registers to see if we have something mis-configured, I think I've stumbled on a clue, if not a fix.

The problem seems to go away if bit 7 of UCR3 (ADNIMP in the reference manual) is set.

U-Boot > mm.l 021e8088
021e8088: 00000704 ? 0784
021e808c: 00008000 ? x
...
... problem doesn't happen.

The manual says this about the bit:

Autobaud Detection Not Improved-. Disables new features of autobaud detection (See Baud Rate Automatic Detection Protocol, for more details).

0 Autobaud detection new features selected
1 Keep old autobaud detection mechanism

0 Kudos
3,063 Views
TroyKisky
Contributor II

Wow, I'm amazed you found that, and so very quickly.

Thank you!!!!!!!!!!!!!

0 Kudos
3,063 Views
EricNelson
Senior Contributor II

Hi Troy,

This guy named Kisky did the hard part: finding the magic sequence to make it break.

I just reviewed each of the UART registers looking for anything suspicious and found this bit that said "new autobaud" and flipped it to see what happened.

Oddly, "new" is a relative term, since this has been around and documented like that since i.MX3x.

0 Kudos
3,063 Views
EricNelson
Senior Contributor II

Also note that the register for this is listed in both U-Boot and Linux as UCR3_TIMEOUTEN, so this may be i.MX6-specific.

~/u-boot-imx6$ grep UCR3 drivers/serial/serial_mxc.c
...
#define  UCR3_TIMEOUTEN  (1<<7)
0 Kudos
3,063 Views
fabio_estevam
NXP Employee
NXP Employee

This bit exists for mx53 as well.

0 Kudos
3,063 Views
EricNelson
Senior Contributor II

Hi Fabio,

I checked the following reference manuals and found the bit present in all of them:

    i.MX35

    i.MX51

    i.MX53

    i.MX6DQ

    i.MX6DLS

    i.MX6SL

Are you in a position to test on i.MX5x or i.MX3x?

0 Kudos
3,063 Views
fabio_estevam
NXP Employee
NXP Employee

I have also checked here. The only imx chip that does not have ADNIMP is i.mx1.

I confirm that the same issue is seen on mx53qsb and setting ADNIMP fixes it as well.

0 Kudos
3,063 Views
EricNelson
Senior Contributor II

Thanks Fabio.

I submitted an RFC patch to the U-Boot ML:

             http://lists.denx.de/pipermail/u-boot/2014-May/thread.html#179513

0 Kudos
3,063 Views
fabio_estevam
NXP Employee
NXP Employee
0 Kudos
3,063 Views
george
Senior Contributor II

Hi, FabioEstevam

We see the same trouble on 6SX now.

And in 6SX, your Patch does not have a good effect.

We want not to change the Autobaud detection method and to disable Autobaud detection.

If possible, please tell me the method.

Best Regards,

George

0 Kudos
3,063 Views
fabio_estevam
NXP Employee
NXP Employee

Hi George,

The original thread is 4 years old. Please start a new one and put all details in it.

0 Kudos
3,063 Views
george
Senior Contributor II

Hi FabioEstevam‌,

I found the report of the same condition as it of us here.

i.MX6 infinite loop in uart driver(rx interrupt) 

This is seen to a behavior peculiar to UART used for i.MX.

Why doesn't it detect that STOP-Bit is not sent?

Best Regards,

George

0 Kudos
3,063 Views
fabio_estevam
NXP Employee
NXP Employee

Hi George,

As suggested previously, please start a new thread.

Does this patch help?

https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?h=next-20180320&id=45ca6... 

0 Kudos
3,063 Views
EricNelson
Senior Contributor II

Note that my example address for UCR3 is for UART2, which we use as the console on our boards.

For UART1 (used on SABRE SD), the register address is 0x02020088.

0 Kudos
3,063 Views
fabio_estevam
NXP Employee
NXP Employee

Nice finding, Eric! With ADNIMP set I cannot see the issue.

0 Kudos
3,063 Views
fabio_estevam
NXP Employee
NXP Employee

Yes, correct: I have reproduce this problem with U-boot on mx6qsabresd.

However, if I use barebox I am not able to reproduce it.

0 Kudos
3,063 Views
fabio_estevam
NXP Employee
NXP Employee

Ops, I have missed to apply your patch that prints "?". Now I see the problem in barebox as well.

0 Kudos
3,063 Views
EricNelson
Senior Contributor II

To elaborate on Troy's listing above, this is an attempt to minimize what we've seen under two separate OS's (Windows Embedded Compact 7 and Linux) on i.MX6.

For some reason, the bad data ('b' at 115200) being presented to the UART seems to put the hardware in a state where it thinks it receiving data continuously, and other bad data ('a' at 115200) causes the data to stop.

This has been observed on both UART1 and UART2 on our Nitrogen6_Lite board (i.MX6 Solo rev 1.1) and Nitrogen6X (i.MX6Q rev 1.2) boards, and UART1 on SABRE SDB (i.MX6Q).

0 Kudos