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

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

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

6,630 Views
yurirellosa
Contributor IV

Hi All,

Serial driver version: patched up to 4.1 (except for RS485 parts)

The error happens when the device connected to the serial module starts-up and sends a break signal.

The code endlessly loops at the code below, with USR2_RDR always on,

0xFF on the the RXD data register with no error bits.

while (readl(sport->port.membase + USR2) & USR2_RDR) {

Although 0xFF is being read on the data register, the connected device is not sending any signal

as checked from the oscilloscope.

Best Regards

Yuri

Labels (4)
10 Replies

4,725 Views
markwilliams
Senior Contributor I

If anyone stumbles upon this thread like I did, see how I resolved it here: https://community.nxp.com/message/1330180 

0 Kudos
Reply

4,725 Views
maxim1
Contributor I

If you are using the RS485, there may be noise in the line.
!!!!!!!! Bad incoming packet kills the processor !!!!!!!.
The ERRATA does not describe this.

0 Kudos
Reply

4,725 Views
Yuri
NXP Employee
NXP Employee

Hello,

  this is a feature of UART

Regards,

Yuri.

0 Kudos
Reply

4,725 Views
maxim1
Contributor I

UCR3_ADNIMP bit Always set.


USR1 = 0x2610
USR2 = 0x5089
UCR1 = 0x0221
UCR2 = 0x5067
UCR3 = 0x038C - UCR3_ADNIMP set
UCR4 = 0x4002
URXD0= 0x80B9

USR1 = 0x2610
USR2 = 0x5089
UCR1 = 0x0221
UCR2 = 0x5067
UCR3 = 0x038C
UCR4 = 0x4002
URXD0= 0xD000  - FRAME error

USR1 = 0x2600
USR2 = 0x5089
UCR1 = 0x0221
UCR2 = 0x5067
UCR3 = 0x038C - UCR3_ADNIMP set
UCR4 = 0x4002
URXD0= 0x80FF

USR1 = 0x2600
USR2 = 0x5089
UCR1 = 0x0221
UCR2 = 0x5067
UCR3 = 0x038C - UCR3_ADNIMP set
UCR4 = 0x4002
URXD0= 0x80FF

USR1 = 0x2600
USR2 = 0x5089
UCR1 = 0x0221
UCR2 = 0x5067
UCR3 = 0x038C - UCR3_ADNIMP set
UCR4 = 0x4002
URXD0= 0x80FF
URXD0= 0x80FF
.....

USR1 = 0x2600
USR2 = 0x5089
UCR1 = 0x0221
UCR2 = 0x5067
UCR3 = 0x038C - UCR3_ADNIMP set
UCR4 = 0x4002
URXD0= 0x80FF
URXD0= 0x80FF

0 Kudos
Reply

4,725 Views
Yuri
NXP Employee
NXP Employee

Hello,

  as for short start bit - from the i.MX6 D/Q RM :

"The start bit is validated when 0s are received for 7 consecutive 1/16 of bit times following the 1-to-0 transition."

  Being completely accurate, we cannot guarantee proper UART operations, when UART specs are violated.

The short start bit period must not be less, than 7/16 of bit time slot. 

Regards,

Yuri.

0 Kudos
Reply

4,725 Views
maxim1
Contributor I

I have the same problem!
linux 4.9.14
DMA is disabled.
UART speed 307200, 8n2.

The imx6 receive 10 zero bits and fixes the FRAME error.
Next, the imx6 receive a short start bit (1.2 usec) and goes nuts.
The processor starts to accept infinitely 0xFF.
Helps only software reset uart.

URXD0 = 80B9
URXD0 = D000 - FRAME error
URXD0 = 80FF
URXD0 = 80FF
URXD0 = 80FF
...
URXD0 = 80FF

Photo of oscillograph.

imx6_uart_error_infinite_rx.jpg

If the processor receives the normal start bit (3.2 usec), then there is no problem.

URXD0 = 8007
URXD0 = D000 - FRAME error
URXD0 = 80FF

Photo of oscillograph.

imx6_uart_not_error.jpg

//---------------------------
Path imx.c:

  if (unlikely(rx & URXD_ERR)) {
+     if (rx & (URXD_BRK | URXD_FRMERR))
+         imx_software_reset(sport);
      if (rx & URXD_BRK)       


+static void imx_software_reset(struct imx_port *sport)
+{
+    unsigned long temp;
+    int ubir, ubmr, uts;
+
+    ubir = readl(sport->port.membase + UBIR);
+    ubmr = readl(sport->port.membase + UBMR);
+    uts = readl(sport->port.membase + IMX21_UTS);
+
+    // Clear the SRST_B bit (UCR2[0])
+    temp = readl(sport->port.membase + UCR2);
+    temp &= ~UCR2_SRST;
+    writel(temp, sport->port.membase + UCR2);
+
+    // Wait for software reset complete: poll SOFTRST bit (UTS[0]) until it is 0.
+    while (!(readl(sport->port.membase + UCR2) & UCR2_SRST))
+        barrier();
+
+    // Re-program baud rate registers: Re-write UBIR and UBMR.
+    writel(ubir, sport->port.membase + UBIR);
+    writel(ubmr, sport->port.membase + UBMR);
+    writel(uts, sport->port.membase + IMX21_UTS);
+}

0 Kudos
Reply

4,725 Views
Yuri
NXP Employee
NXP Employee

Hello,

   You can try the following patch 

kernel/git/torvalds/linux.git - Linux kernel source tree 

Looks like this is known issue, You may create request for more details.

Sales and Support|NXP 

Regards,

Yuri.

0 Kudos
Reply

4,725 Views
igorpadykov
NXP Employee
NXP Employee

Hi

according to sect.64.4.3 General UART Definitions i.MX6DQ Reference Manual :
"BREAK-A frame in which all of the data bits, including the stop bit, are logic 0."
Also BREAK signal is handled by UART in sect.64.4.5.4 Receiving a BREAK Condition

http://cache.freescale.com/files/32bit/doc/ref_manual/IMX6DQRM.pdf

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply

4,724 Views
yurirellosa
Contributor IV

Hi Igor,

There is no problem with the BREAK signal/packet (It is logic) and we are able to pickup proper errors on that packet.

The problem is the infinite loop after this. The data register will register an always ready with no errors.

Is there a tolerance or time frame that the UART device should not receive a BREAK signal?

Best Regards

Yuri

0 Kudos
Reply

4,724 Views
igorpadykov
NXP Employee
NXP Employee

Hi Yuri

I would suggest to narrow down this issue, if this relates to hardware or

software, running bare metal test of i.MX6Q SabreSD reference board.

Best regards
igor

0 Kudos
Reply