imx6q configuration WEIM bus for ST16C554 expand UART ,Resive data error

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

imx6q configuration WEIM bus for ST16C554 expand UART ,Resive data error

1,122 Views
1282497337
Contributor II

Hi,community

     I configuration the imx6q WEIM bus and connected the ST16C554 to expand 4 uart port , then I used the serial port to resive data,it's possible to get the wrong data such I send the data is "0x55",but i got the data "0x00"(if I got the error data it's always 0x00),most time i can get the correct data "0x55".

    My board is I.MX6Q,and the linux kernel is 3.14.52

    Someone met the same problem? and could you give me some idear

thanks very much!!

Alee

Labels (1)
0 Kudos
4 Replies

859 Views
igorpadykov
NXP Employee
NXP Employee

Hi Alee

one can try to adjust ST16C554 - EIM interface timings using

the dts timing array  "weim-cs-timing"

imx-weim.txt\bus\bindings\devicetree\Documentation - linux-imx - i.MX Linux kernel 

ST16C554 datasheet and sect.22.9 EIM Memory Map/Register Definition i.MX6DQ Reference Manual
https://www.nxp.com/docs/en/reference-manual/IMX6DQRM.pdf

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

0 Kudos

859 Views
1282497337
Contributor II

Hi, igor

thank you for your reply !

our hardware connect is

   ((~EIM_DA7) & EIM_CS0) to 554_CSA

   ((EIM_DA7) & EIM_CS0) to 554_CSB

   ((~EIM_DA7) & EIM_CS1 ) to 554_CSC

   ((EIM_DA7) & EIM_CS1 ) to 554_CSD

For details,see the picture "weim & ST16C554 HW connect" 

weim & ST16C554 HW connect.png

and the software we set the weim timing is

/*CSxGCR1, CSxGCR2, CSxRCR1,
CSxRCR2, CSxWCR1, CSxWCR2.*/

//cs0
writel(0x00660081, base + 0 * 0x18 + 0 * 4);
writel(0x00000001, base + 0 * 0x18 + 1 * 4);
writel(0x1C022000, base + 0 * 0x18 + 2 * 4);
writel(0x0000C000, base + 0 * 0x18 + 3 * 4);
writel(0x0C04A38E, base + 0 * 0x18 + 4 * 4);
writel(0x00000000, base + 0 * 0x18 + 5 * 4);

//cs1
writel(0x00660081, base + 1 * 0x18 + 0 * 4);
writel(0x00000001, base + 1 * 0x18 + 1 * 4);
writel(0x1C022000, base + 1 * 0x18 + 2 * 4);
writel(0x0000C000, base + 1 * 0x18 + 3 * 4);
writel(0x0C04A38E, base + 1 * 0x18 + 4 * 4);
writel(0x00000000, base + 1 * 0x18 + 5 * 4);

// EIM_WCR

writel(0x00000001, base + 0x90);

gpr :

u32 gprvals[4] = {
      05, /* CS0(128M) CS1(0M) CS2(0M) CS3(0M) */
      033, /* CS0(64M) CS1(64M) CS2(0M) CS3(0M) */
      0113, /* CS0(64M) CS1(32M) CS2(32M) CS3(0M) */
      01111, /* CS0(32M) CS1(32M) CS2(32M) CS3(0M) */
};

..............
regmap_update_bits(gpr, IOMUXC_GPR1, 0xfff, gprvals[1]);/* CS0(64M)  CS1(64M) CS2(0M)  CS3(0M) */

I used the I.Mx6 self ttymxc3 send 10000 Bytes(0xFF) and used the 554 serial port  ttySEX3 to resive , then I got an error Byte(0x00),others data is correct(0xFF),then I used the command "cat /proc/tty/driver/serial " the result is :

root@imx6qsabresd:/# cat /proc/tty/driver/serial
serinfo:1.0 driver revision:
0: uart:16550A mmio:0x08000080 irq:321 tx:0 rx:0 CTS|DSR|CD|RI
1: uart:16550A mmio:0x08000000 irq:322 tx:0 rx:0 DSR|CD|RI
2: uart:16550A mmio:0x0C000080 irq:323 tx:0 rx:0 CTS|DSR|CD|RI
3: uart:16550A mmio:0x0C000000 irq:324 tx:0 rx:99985 oe:1 RTS|CTS|DTR|DSR|CD|RI

I found the "oe:1" always equal to resive error data ,such as if I resive 10 error Bytes(0x00),the results "oe:10",could you tell me what's mean of the "oe"? and have some idea to locate this problem?thanks

Best Wish!! 

Alee

0 Kudos

859 Views
igorpadykov
NXP Employee
NXP Employee

Hi Alee

you can check eim timings with oscilloscope and compare with ST16C554 datasheet 

requirements. Just for test one can try to decrease EIM frequency.

Best regards
igor

0 Kudos

861 Views
1282497337
Contributor II

Hi igor

thank you !

I setted the EIM frequency to 66MHz(old value is 133MHz),but can't address this problem,

on the other hand , when I used the ST16C554 to receive the serial data,sometime the 554 FIFO will overrun,

then i will got the data "0x00". I used the standard serial port driver "kernel/driver/tty/serial/8250/8250_core.c" my kernel is 3.14.52.

I want to know what's reason cause the FIFO overrun(looks like IRQ responds not immedaitely),and what should I do to deal with this issue

Best regards
Alee

the function "serial8250_rx_chars" detail

unsigned char serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr)
{
............................

do {
if (likely(lsr & UART_LSR_DR))
       ch = serial_in(up, UART_RX);
else

............................
        ch = 0;

............................

if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) {
if (lsr & UART_LSR_BI) {
lsr &= ~(UART_LSR_FE | UART_LSR_PE);
port->icount.brk++;
if (uart_handle_break(port))
goto ignore_char;
} else if (lsr & UART_LSR_PE)
port->icount.parity++;
else if (lsr & UART_LSR_FE)
port->icount.frame++;
if (lsr & UART_LSR_OE)                   // UART_LSR_OE bit be  setted
            port->icount.overrun++;

............................
if (uart_handle_sysrq_char(port, ch))
      goto ignore_char;

uart_insert_char(port, lsr, UART_LSR_OE, ch, flag);        // at this function will send 0x00 to user space 

ignore_char:
lsr = serial_in(up, UART_LSR);
} while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0));
...................
}

0 Kudos