izmit escort escort ankara adana escort

 FAQ •  Search •  Register •  Login 

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 14 posts ] 
Author Message
 Post subject: Data loss during read from USART
PostPosted: Wed Aug 02, 2017 1:26 pm 
Offline

Joined: Wed Aug 02, 2017 11:16 am
Posts: 8
I have problem with data loss during read from USART. Write data to USART are always OK. For test I using data block 32B - 512B. If I send more bytes, then more data lose. From data 512 bytes are lose 1, 2 or 3 bytes. Lost bytes are different for each transfer.
If I run communication only 2 x RS485, so reading is OK. But If also I run communication by I2C , then data are lost in each data block read from USART (100% error of read data block). If I change interrupts level for USART from 5 to 6 (by I2C) in dtsi file, then during reading USART data lose only cca 10%. If I run also CAN bus transfer, so the amount of lost data increases.
Also if I run transfer by GSM module and RS485, then data lose in each read data block from USART.

For testing I useing application in c language. Communication with each bus are in separate threads.

I measured inputs pins of USART with osciloskop and logic analyser, but all incomming data was OK. So hardver should be okay.

Property of my board:
- MCU AT91SAM9x25
- 4.4.26-linux4sam_5.5
- buildroot 2016.11.2
- 2 x ethernet
- 2 x CAN bus (by spi using MPC2515)
- 2 x I2C
- 2 x RS232 (USART1, UART0)
- 2 x RS485 (USART0, USART3)
- 1 x GSM module QUECTEL UC20 (connected by USB, ttyUSB0 - ttyUSB4)


Thank you in advance
Emil


Top
 Profile  
Reply with quote  
 Post subject: Re: Data loss during read from USART
PostPosted: Wed Aug 02, 2017 10:58 pm 
Offline

Joined: Thu Apr 19, 2007 10:15 pm
Posts: 1470
Location: USA
Emco wrote:
I have problem with data loss during read from USART.
You need to clarify what you mean by "data loss".
Is the application receiving fewer bytes than expected?
Are the values of the data not as expected?

Emco wrote:
Property of my board:
...
- 2 x RS232 (USART1, UART0)
- 2 x RS485 (USART0, USART3)
Your description is inconsistent.
You complain of issues with USART in general, but only mention results with RS-485 ports.
Are there issues with the other USART port?

Regards


Top
 Profile  
Reply with quote  
 Post subject: Re: Data loss during read from USART
PostPosted: Thu Aug 03, 2017 10:55 am 
Offline

Joined: Wed Aug 02, 2017 11:16 am
Posts: 8
"data loss" = the application receiving fewer bytes than expected
I have problem with all serial lines:
RS232_0 - USART1
RS232_1 - UART0
RS485_0 - USART0
RS485_1 - USART3

In one data transfer is expected 512 bytes.

Here are results of my tests:

Size of data block 512B.

LEGEND:
bus number_of_successful_transfer / number_of_error_transfer (number of read bytes in error transfer - OK is 512B)

RS232_0 1000/0 - successful
RS232_1 1000/0 - successful

RS485_0 1000/0 - successful
RS485_1 1000/0 - successful

RS232_0 & RS232_1 - two communications at the same time
RS232_0 1000/0 - successful
RS232_1 999/1(only read 511B) - failed

RS485_0 & RS485_1 - two communications at the same time
RS485_0 1000/0 - successful
RS485_1 1000/0 - successful

RS485_0 & RS485_1 & RS232_0 - three lines at the same time
RS485_0 1000/0 - successful
RS485_1 1000/0 - successful
RS232_0 997/3(only read 511B) - failed


RS485_0 & RS485_1 & RS232_1 - three lines at the same time
RS485_0 1000/0 - successful
RS485_1 1000/0 - successful
RS232_1991/9 (only read 511B) - failed

RS232_0 & RS232_1 & RS485_0 & RS485_1 - four lines at the same time
RS232_0 994/6 - failed
RS232_1 953/47(only read 511B) - failed
RS485_0 1000/0 - successful
RS485_1 999/1(only read 511B) - failed

I2C_0 & I2C_1 & RS232_0 & RS232_1 - four lines at the same time
I2C_0 1000/0 - successful
I2C_1 1000/0 - successful
RS232_0 0/1000(only read from 507B to 511B) - failed
RS232_1 0/1000(only read from 507B to 509B) - failed

I2C_0 & I2C_1 & RS485_0 & RS485_1 - four lines at the same time
I2C_0 1000/0 - successful
I2C_1 1000/0 - successful
RS485_0 0/1000(only read from 509B to 511B) - failed
RS485_1 0/1000(only read from 507B to 509B) - failed

I2C_0 & I2C_1 & RS232_0 & RS232_1 & RS485_0 & RS485_1 - six lines at the same time
I2C_0 1000/0 - successful
I2C_1 1000/0 - successful
RS232_0 0/1000(only read from 508B to 511B) - failed
RS232_1 0/1000(only read from 507B to 511B) - failed
RS485_0 0/1000(only read from 508B to 511B) - failed
RS485_1 0/1000(only read from 508B to 511B) - failed



Then I changed level of interrupts for all USART in dtsi files:
original: interrupts = <7 IQR_TYPE_LEVEL_HIGH 5>
new: interrupts = <7 IQR_TYPE_LEVEL_HIGH 6> - I2C have level of interrupts 6

I2C_0 & I2C_1 & RS232_0 & RS232_1 - four lines at the same time
I2C_0 1000/0 - successful
I2C_1 1000/0 - successful
RS232_0 992/8(only read 511B) - failed
RS232_10/1000(only read from 508B to 510B) - failed

I2C_0 & I2C_1 & RS485_0 & RS485_1 - four lines at the same time
I2C_0 1000/0 - successful
I2C_1 1000/0 - successful
RS485_0 1000/0 - successful
RS485_1999/1(only read 511B) - failed

I2C_0 & I2C_1 & RS232_0 & RS232_1 & RS485_0 & RS485_1 - six lines at the same time
I2C_0 1000/0 - successful
I2C_1 1000/0 - successful
RS232_0 950/50(only read 511B) - failed
RS232_1 0/1000(only read from 509B to 511B) - failed
RS485_0 995/5(only read 511B) - failed
RS485_1990/10(only read 511B) - failed

Thank you


Top
 Profile  
Reply with quote  
 Post subject: Re: Data loss during read from USART
PostPosted: Fri Aug 04, 2017 1:05 am 
Offline

Joined: Thu Apr 19, 2007 10:15 pm
Posts: 1470
Location: USA
Clarification of what you mean by "data loss" and the test results explain the confusing "100% error of read data block".
Now you need to provide other salient details, such as the data rates involved (baudrates for the RS-232 and RS-485 interfaces and I2C speed), and what kernel version (since you mention using DT).
What Preemption Model does your kernel use?

Presumably you are using DMA on all interfaces?
Rather than tweak interrupt priorities, the Bus Matrix attributes may need tweaking (e.g. DMA burst size and/or priorities?).
Have you tried a gross test with PIO instead of DMA on one type of interface?

Presumably you have configured serial ports for non-canonical I/O?
If both parity and break conditions are ignored, then overrun errors are also ignored.
Instead you need to determine whether receive overruns are occurring.
The file /proc/tty/driver/atmel_serial should have statistics for the serial ports if the errors are not ignored.

Use of the internal SRAM can improve I/O performance (i.e. the SRAM has better availability than the DRAM).
There used to be patch to use the SRAM with the EMAC for Tx buffers.
Perhaps that patch can be adapted to divide up the SRAM among the USARTs for receive buffers.

Regards


Top
 Profile  
Reply with quote  
 Post subject: Re: Data loss during read from USART
PostPosted: Fri Aug 04, 2017 5:13 pm 
Offline

Joined: Wed Aug 02, 2017 11:16 am
Posts: 8
If I read less than 512B, this is an error of read data block.

For all serial ports:
BAUDRATE = 115 200
parrity - disabled
non-canonical mode
number_of_bits_of_one_char = 8

Here is inicialization RS-232:

fd_uart[uart_number] = open(path_buf, O_RDWR | O_NOCTTY | O_NDELAY);

tcflush(fd_uart[uart_number], TCIOFLUSH);

tcgetattr(fd_uart[uart_number], &options);

options.c_iflag &= ~(BRKINT | ISTRIP | INLCR | IGNCR | ICRNL | IUCLC | IXON | IXANY);
options.c_iflag |= (IGNBRK | IGNPAR | INPCK | IXOFF | IMAXBEL);

options.c_oflag &= ~(OPOST | OLCUC | ONLCR | OCRNL | ONLRET | OFILL | OFDEL);
options.c_oflag |= (ONOCR | NL0 | CR0 | TAB0 | BS0 | FF0 | VT0);


options.c_cflag &= ~(CSTOPB | PARENB | PARODD | CRTSCTS);
options.c_cflag &= ~(B0 | B50 | B75 | B110 | B134 | B150 | B200 | B300 | B600 | B1200 | B1800 | B2400 | B4800 | B9600|B19200|B38400 | B57600 | B115200 | B230400 | B460800 | B500000 | B576000 | B921600 | B1000000 | B1152000 | B1500000 | B2000000 | B2500000 | B3000000 | B3500000 | B4000000);

options.c_cflag |= BAUDRATE;
options.c_ispeed = BAUDRATE;
options.c_ospeed = BAUDRATE;

options.c_cflag &= ~(PARENB);

options.c_cflag &= ~(PARODD);

options.c_cflag |= number_of_bits_of_one_char;

options.c_lflag &= ~(ISIG | ICANON | XCASE | ECHO | ECHOE | ECHOK | ECHONL | NOFLSH | TOSTOP | ECHOPRT | IEXTEN);

tcsetattr(fd_uart[uart_number], TCSANOW, &options);


For RS-485 mode is add:
/* Enable RS485 mode: */
rs485conf.flags |= SER_RS485_ENABLED;

/* Set logical level for RTS pin equal to 1 when sending: */
rs485conf.flags |= SER_RS485_RTS_ON_SEND;
/* or, set logical level for RTS pin equal to 0 when sending: */
//rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);

/* Set logical level for RTS pin equal to 1 after sending: */
//rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
/* or, set logical level for RTS pin equal to 0 after sending: */
rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);

/* Set rts delay before send, if needed: */
rs485conf.delay_rts_before_send = 0;

/* Set rts delay after send, if needed: */
rs485conf.delay_rts_after_send = 0;

/* Set this flag if you want to receive data even whilst sending data */
// rs485conf.flags |= SER_RS485_RX_DURING_TX;

if (ioctl (fd_uart[uart_number], TIOCSRS485, &rs485conf) < 0) {
/* Error handling. See errno. */
printf("Error handling. See errno.");
}



Frequency of I2C = 98KHz

Kernel version: 4.4.26

Preemption Model: No Forced Preemption (server)
It is necessary "make clean" before compilation, if I change preemption mode?

In dtsi files are define DMA for all USART, but no for UART.
How can I change DMA burst size and/or priorities? Where are define?

"Have you tried a gross test with PIO instead of DMA on one type of interface?"
How can I disable DMA and test with PIO?
Is this OK?

usart0: serial@f801c000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xf801c000 0x200>;
interrupts = <5 IRQ_TYPE_LEVEL_HIGH 5>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usart0 &pinctrl_usart0_rts &pinctrl_usart0_cts>;
/*dmas = <&dma0 1 AT91_DMA_CFG_PER_ID(3)>,
<&dma0 1 (AT91_DMA_CFG_PER_ID(4) | AT91_DMA_CFG_FIFOCFG_ASAP)>;
dma-names = "tx", "rx";*/
clocks = <&usart0_clk>;
clock-names = "usart";
linux,rs485-enabled-at-boot-time;
rs485-rts-delay = <0 20>; // in milliseconds */
status = "disabled";
};



"Use SRAM can improve I / O performance (ie SRAM has better availability than DRAM).
There was a patch to use the SRAM with the EMAC for Tx buffers.
Perhaps that patch can be adapted to divide the SRAM among USARTs for receive buffers."
Where is a patch to use the SRAM with the EMAC for Tx buffers?

Read tty driver:
# cat /proc/tty/driver/atmel_serial
serinfo:1.0 driver revision:
0: uart:ATMEL_SERIAL mmio:0xFFFFF200 irq:16 tx:15364 rx:103 RTS|CTS|DTR|DSR|CD|RI
1: uart:ATMEL_SERIAL mmio:0xF801C000 irq:30 tx:2560 rx:2549 oe:11 DSR|CD|RI
2: uart:ATMEL_SERIAL mmio:0xF8020000 irq:31 tx:2560 rx:2544 oe:15 CTS|DSR|CD|RI
3: uart:ATMEL_SERIAL mmio:0xF8040000 irq:34 tx:2560 rx:2540 oe:16 CTS|DSR|CD|RI
4: uart:ATMEL_SERIAL mmio:0xF8028000 irq:37 tx:2560 rx:2548 oe:12 DSR|CD|RI


Top
 Profile  
Reply with quote  
 Post subject: Re: Data loss during read from USART
PostPosted: Sat Aug 05, 2017 1:11 am 
Offline

Joined: Thu Apr 19, 2007 10:15 pm
Posts: 1470
Location: USA
Since you figured out how to create bold text and change font size and color, you should also learn how to use the 'quote' and 'code' tags (they're in the same tool bar as the 'bold' button).

The contents of /proc/tty/driver/atmel_serial is most significant, as this seems to indicate the point of data loss.
The nonzero "oe" counts indicate receiver overrun errors are occurring.
But the terminal driver does not report such errors since your termios configuration has both parity and break condition ignored. The man page is not clear how such an overrun error would be conveyed to the caller.

You can perform tests to confirm correlation of this error count and lost bytes.
Before sending any data, take a snapshot of the file.
Perform a test to generate data loss.
Take a new snapshot of the file.
Calculate the change in the "rx" receive and "oe" overrun counts, and compare to your transfer and test results.

Presumably the overrun errors are occurring because the DMA channel is not reading the RXD register in time.
Apparently the DMAC is too busy to service all of its masters & clients all the time under the loads you have created.
There is no indication that there is anything amiss with the DMAC (e.g. that the DMAC could be losing the bytes).

Emco wrote:
fd_uart[uart_number] = open(path_buf, O_RDWR | O_NOCTTY | O_NDELAY);
Unless you also have an fcntl() somewhere to change access mode, you're performing non-blocking I/O on these serial terminals.
Is this a deliberate choice?
Have you programmed the read() and write() syscalls to properly use non-blocking mode as to not overburden the CPU?

You previously wrote that "communication with each bus are in separate threads".
Serial links are not buses.
Does each serial port have its own thread, or are all serial ports handled by just one thread?
If each serial port does have its own thread, then how do you justify using non-blocking I/O?

Your termios initialization can be improved and simplified.
Code:
    rc = tcgetattr(fd_uart[uart_number], &options);
    if (rc < 0) {
        /* handle error condition */
    }

    cfsetospeed(&options, (speed_t)BAUDRATE);
    cfsetispeed(&options, (speed_t)BAUDRATE);

    cfmakeraw(&options);

    options.c_iflag |= (IGNBRK | IGNPAR);  /* unconventional setting */

    options.c_cc[VMIN] = 1;    /* meaningless with non-blocking I/O */
    options.c_cc[VTIME] = 1;   /* meaningless with non-blocking I/O */

    options.c_cflag &= ~CSTOPB;     /* use one stop bit */
    options.c_cflag &= ~CRTSCTS;    /* no HW flow control */
    options.c_cflag |= CLOCAL | CREAD;

    tcflush(fd_uart[uart_number], TCIOFLUSH);
    rc = tcsetattr(fd_uart[uart_number], TCSANOW, &options);
    if (rc < 0) {
        /* handle error condition */
    }


Emco wrote:
It is necessary "make clean" before compilation, if I change preemption mode?
No.

Emco wrote:
How can I change DMA burst size and/or priorities? Where are define?
It's controlled by the Bus Matrix.
But there seems to be nothing in the kernel anymore that interfaces with it.
Might be easier to change matrix settings in U-Boot, before the kernel starts.

Emco wrote:
How can I disable DMA and test with PIO?
Is this OK?
Since the indication is that the data is being lost at the USART, such a test has little value now.

Emco wrote:
Where is a patch to use the SRAM with the EMAC for Tx buffers?
It's part of the 2.6.27-at91-exp.patch set mentioned at https://www.at91.com/linux4sam/bin/view/Linux4SAM/LegacyLinuxKernel#Linux4SAM_Experimental_Patches .

Regards


Top
 Profile  
Reply with quote  
 Post subject: Re: Data loss during read from USART
PostPosted: Mon Aug 07, 2017 6:28 pm 
Offline

Joined: Wed Aug 02, 2017 11:16 am
Posts: 8
Quote:
You can perform tests to confirm correlation of this error count and lost bytes.
Before sending any data, take a snapshot of the file.
Perform a test to generate data loss.
Take a new snapshot of the file.
Calculate the change in the "rx" receive and "oe" overrun counts, and compare to your transfer and test results.

Here are results of my test:
Code:
# cat /proc/tty/driver/atmel_serial
serinfo:1.0 driver revision:
0: uart:ATMEL_SERIAL mmio:0xFFFFF200 irq:16 tx:11800 rx:119 RTS|CTS|DTR|DSR|CD|RI
1: uart:ATMEL_SERIAL mmio:0xF801C000 irq:30 tx:2048 rx:2040 oe:8 DSR|CD|RI         (in my app loss 6 bytes)
2: uart:ATMEL_SERIAL mmio:0xF8020000 irq:31 tx:2048 rx:2038 oe:10 CTS|DSR|CD|RI      (in my app loss 8 bytes)
3: uart:ATMEL_SERIAL mmio:0xF8040000 irq:34 tx:2048 rx:2032 oe:14 CTS|DSR|CD|RI      (in my app loss 12 bytes)
4: uart:ATMEL_SERIAL mmio:0xF8028000 irq:37 tx:2048 rx:2038 oe:10 DSR|CD|RI         (in my app loss 7 bytes)
So number of loss bytes in my application was less than oe: (for each port).


Quote:
Unless you also have an fcntl() somewhere to change access mode, you're performing non-blocking I/O on these serial terminals.
Is this a deliberate choice?
Have you programmed the read() and write() syscalls to properly use non-blocking mode as to not overburden the CPU?

You previously wrote that "communication with each bus are in separate threads".
Serial links are not buses.
Does each serial port have its own thread, or are all serial ports handled by just one thread?
If each serial port does have its own thread, then how do you justify using non-blocking I/O?
I using non-blocking I/O, because I have also timeout counter in each thread.


Quote:
It's controlled by the Bus Matrix.
But there seems to be nothing in the kernel anymore that interfaces with it.
Might be easier to change matrix settings in U-Boot, before the kernel starts.
What should I change in uboot? Is it in settings, which I run push ctrl+c during start?

Quote:
It's part of the 2.6.27-at91-exp.patch set mentioned at https://www.at91.com/linux4sam/bin/view ... al_Patches .
I want to test tomorrow.

Thank you
Regards


Top
 Profile  
Reply with quote  
 Post subject: Re: Data loss during read from USART
PostPosted: Tue Aug 08, 2017 3:10 am 
Offline

Joined: Thu Apr 19, 2007 10:15 pm
Posts: 1470
Location: USA
Emco wrote:
In dtsi files are define DMA for all USART, but no for UART.
Exactly what do you have in the DT for each USART?
After reviewing the atmel_serial driver and the DT, it looks like that PIO is the default for SAM9x5 SoC boards.

If DMA is enabled through the DT, then the resulting properties for a USART would be something like:
Code:
# ls -l /proc/device-tree/ahb/apb/serial@f801c000
total 0
-r--r--r--    1 root     root             0 Jan  1 00:41 atmel,use-dma-rx
-r--r--r--    1 root     root             0 Jan  1 00:41 atmel,use-dma-tx
-r--r--r--    1 root     root             6 Jan  1 00:41 clock-names
-r--r--r--    1 root     root             4 Jan  1 00:41 clocks
-r--r--r--    1 root     root            24 Jan  1 00:41 compatible
-r--r--r--    1 root     root             6 Jan  1 00:41 dma-names
-r--r--r--    1 root     root            24 Jan  1 00:41 dmas
-r--r--r--    1 root     root            12 Jan  1 00:41 interrupts
-r--r--r--    1 root     root             7 Jan  1 00:41 name
-r--r--r--    1 root     root             4 Jan  1 00:41 pinctrl-0
-r--r--r--    1 root     root             8 Jan  1 00:41 pinctrl-names
-r--r--r--    1 root     root             8 Jan  1 00:41 reg
-r--r--r--    1 root     root             5 Jan  1 00:41 status
#

When DMA is enabled, you're reminded of it when you change the baudrate:
Code:
# stty -F /dev/ttyS1 115200
atmel_usart f801c000.serial: using dma0chan6 for rx DMA transfers
atmel_usart f801c000.serial: using dma0chan7 for tx DMA transfers
#


DMA can be enabled for a USART by adding two properties to its node at the board-level .dts or .dtsi file:
Code:
         usart0: serial@f801c000 {
+                atmel,use-dma-rx;
+                atmel,use-dma-tx;
                 status = "okay";
         };
Avoid modifying the SoC-level at91sam9x5.dtsi file.

The default use of PIO (instead of using DMA) is a simple explanation for your receiver overrun.

Regards


Top
 Profile  
Reply with quote  
 Post subject: Re: Data loss during read from USART
PostPosted: Tue Aug 08, 2017 4:05 pm 
Offline

Joined: Wed Aug 02, 2017 11:16 am
Posts: 8
Quote:
Exactly what do you have in the DT for each USART?
After reviewing the atmel_serial driver and the DT, it looks like that PIO is the default for SAM9x5 SoC boards.


Original state - probaly rx, tx DMA disable
Code:
# ls -l /proc/device-tree/ahb/apb/serial@f801c000
total 0
-r--r--r--    1 root     root             6 Jan 18 20:21 clock-names
-r--r--r--    1 root     root             4 Jan 18 20:21 clocks
-r--r--r--    1 root     root            24 Jan 18 20:21 compatible
-r--r--r--    1 root     root             6 Jan 18 20:21 dma-names
-r--r--r--    1 root     root            24 Jan 18 20:21 dmas
-r--r--r--    1 root     root            12 Jan 18 20:21 interrupts
-r--r--r--    1 root     root             0 Jan 18 20:21 linux,rs485-enabled-at-boot-time
-r--r--r--    1 root     root             7 Jan 18 20:21 name
-r--r--r--    1 root     root            12 Jan 18 20:21 pinctrl-0
-r--r--r--    1 root     root             8 Jan 18 20:21 pinctrl-names
-r--r--r--    1 root     root             8 Jan 18 20:21 reg
-r--r--r--    1 root     root             8 Jan 18 20:21 rs485-rts-delay
-r--r--r--    1 root     root             5 Jan 18 20:21 status
# ls -l /proc/device-tree/ahb/apb/serial@f8020000/
total 0
-r--r--r--    1 root     root             6 Jan 18 20:23 clock-names
-r--r--r--    1 root     root             4 Jan 18 20:23 clocks
-r--r--r--    1 root     root            24 Jan 18 20:23 compatible
-r--r--r--    1 root     root             6 Jan 18 20:23 dma-names
-r--r--r--    1 root     root            24 Jan 18 20:23 dmas
-r--r--r--    1 root     root            12 Jan 18 20:23 interrupts
-r--r--r--    1 root     root             7 Jan 18 20:23 name
-r--r--r--    1 root     root             4 Jan 18 20:23 pinctrl-0
-r--r--r--    1 root     root             8 Jan 18 20:23 pinctrl-names
-r--r--r--    1 root     root             8 Jan 18 20:23 reg
-r--r--r--    1 root     root             5 Jan 18 20:23 status
# ls -l /proc/device-tree/ahb/apb/serial@f8028000/
total 0
-r--r--r--    1 root     root             6 Jan 18 20:24 clock-names
-r--r--r--    1 root     root             4 Jan 18 20:24 clocks
-r--r--r--    1 root     root            24 Jan 18 20:24 compatible
-r--r--r--    1 root     root             6 Jan 18 20:24 dma-names
-r--r--r--    1 root     root            24 Jan 18 20:24 dmas
-r--r--r--    1 root     root            12 Jan 18 20:24 interrupts
-r--r--r--    1 root     root             0 Jan 18 20:24 linux,rs485-enabled-at-boot-time
-r--r--r--    1 root     root             7 Jan 18 20:24 name
-r--r--r--    1 root     root            12 Jan 18 20:24 pinctrl-0
-r--r--r--    1 root     root             8 Jan 18 20:24 pinctrl-names
-r--r--r--    1 root     root             8 Jan 18 20:24 reg
-r--r--r--    1 root     root             8 Jan 18 20:24 rs485-rts-delay
-r--r--r--    1 root     root             5 Jan 18 20:24 status
# ls -l /proc/device-tree/ahb/apb/serial@f8040000/
total 0
-r--r--r--    1 root     root             6 Jan 18 20:25 clock-names
-r--r--r--    1 root     root             4 Jan 18 20:25 clocks
-r--r--r--    1 root     root            24 Jan 18 20:25 compatible
-r--r--r--    1 root     root            12 Jan 18 20:25 interrupts
-r--r--r--    1 root     root             7 Jan 18 20:25 name
-r--r--r--    1 root     root             4 Jan 18 20:25 pinctrl-0
-r--r--r--    1 root     root             8 Jan 18 20:25 pinctrl-names
-r--r--r--    1 root     root             8 Jan 18 20:25 reg
-r--r--r--    1 root     root             5 Jan 18 20:25 status


Quote:
When DMA is enabled, you're reminded of it when you change the baudrate:
Code:
# stty -F /dev/ttyS1 115200
#

Quote:
DMA can be enabled for a USART by adding two properties to its node at the board-level .dts or .dtsi file:

Enable rx DMA and tx DMA:
Code:
# ls -l /proc/device-tree/ahb/apb/serial@f801c000
total 0
-r--r--r--    1 root     root             0 Jan 19 03:54 atmel,use-dma-rx
-r--r--r--    1 root     root             0 Jan 19 03:54 atmel,use-dma-tx
-r--r--r--    1 root     root             6 Jan 19 03:54 clock-names
-r--r--r--    1 root     root             4 Jan 19 03:54 clocks
-r--r--r--    1 root     root            24 Jan 19 03:54 compatible
-r--r--r--    1 root     root             6 Jan 19 03:54 dma-names
-r--r--r--    1 root     root            24 Jan 19 03:54 dmas
-r--r--r--    1 root     root            12 Jan 19 03:54 interrupts
-r--r--r--    1 root     root             0 Jan 19 03:54 linux,rs485-enabled-at-boot-time
-r--r--r--    1 root     root             7 Jan 19 03:54 name
-r--r--r--    1 root     root            12 Jan 19 03:54 pinctrl-0
-r--r--r--    1 root     root             8 Jan 19 03:54 pinctrl-names
-r--r--r--    1 root     root             8 Jan 19 03:54 reg
-r--r--r--    1 root     root             8 Jan 19 03:54 rs485-rts-delay
-r--r--r--    1 root     root             5 Jan 19 03:54 status
# ls -l /proc/device-tree/ahb/apb/serial@f8020000/
total 0
-r--r--r--    1 root     root             0 Jan 19 03:54 atmel,use-dma-rx
-r--r--r--    1 root     root             0 Jan 19 03:54 atmel,use-dma-tx
-r--r--r--    1 root     root             6 Jan 19 03:54 clock-names
-r--r--r--    1 root     root             4 Jan 19 03:54 clocks
-r--r--r--    1 root     root            24 Jan 19 03:54 compatible
-r--r--r--    1 root     root             6 Jan 19 03:54 dma-names
-r--r--r--    1 root     root            24 Jan 19 03:54 dmas
-r--r--r--    1 root     root            12 Jan 19 03:54 interrupts
-r--r--r--    1 root     root             7 Jan 19 03:54 name
-r--r--r--    1 root     root             4 Jan 19 03:54 pinctrl-0
-r--r--r--    1 root     root             8 Jan 19 03:54 pinctrl-names
-r--r--r--    1 root     root             8 Jan 19 03:54 reg
-r--r--r--    1 root     root             5 Jan 19 03:54 status
# ls -l /proc/device-tree/ahb/apb/serial@f8028000/
total 0
-r--r--r--    1 root     root             0 Jan 19 03:54 atmel,use-dma-rx
-r--r--r--    1 root     root             0 Jan 19 03:54 atmel,use-dma-tx
-r--r--r--    1 root     root             6 Jan 19 03:54 clock-names
-r--r--r--    1 root     root             4 Jan 19 03:54 clocks
-r--r--r--    1 root     root            24 Jan 19 03:54 compatible
-r--r--r--    1 root     root             6 Jan 19 03:54 dma-names
-r--r--r--    1 root     root            24 Jan 19 03:54 dmas
-r--r--r--    1 root     root            12 Jan 19 03:54 interrupts
-r--r--r--    1 root     root             0 Jan 19 03:54 linux,rs485-enabled-at-boot-time
-r--r--r--    1 root     root             7 Jan 19 03:54 name
-r--r--r--    1 root     root            12 Jan 19 03:54 pinctrl-0
-r--r--r--    1 root     root             8 Jan 19 03:54 pinctrl-names
-r--r--r--    1 root     root             8 Jan 19 03:54 reg
-r--r--r--    1 root     root             8 Jan 19 03:54 rs485-rts-delay
-r--r--r--    1 root     root             5 Jan 19 03:54 status
# ls -l /proc/device-tree/ahb/apb/serial@f8040000/
total 0
-r--r--r--    1 root     root             6 Jan 19 03:55 clock-names
-r--r--r--    1 root     root             4 Jan 19 03:55 clocks
-r--r--r--    1 root     root            24 Jan 19 03:55 compatible
-r--r--r--    1 root     root            12 Jan 19 03:55 interrupts
-r--r--r--    1 root     root             7 Jan 19 03:55 name
-r--r--r--    1 root     root             4 Jan 19 03:55 pinctrl-0
-r--r--r--    1 root     root             8 Jan 19 03:55 pinctrl-names
-r--r--r--    1 root     root             8 Jan 19 03:55 reg
-r--r--r--    1 root     root             5 Jan 19 03:55 status
Code:
# stty -F /dev/ttyS1 115200
atmel_usart f801c000.serial: using dma0chan4 for rx DMA transfers
atmel_usart f801c000.serial: using dma0chan5 for tx DMA transfers
Code:
# cat /proc/tty/driver/atmel_serial
serinfo:1.0 driver revision:
0: uart:ATMEL_SERIAL mmio:0xFFFFF200 irq:16 tx:48106 rx:489 RTS|CTS|DTR|DSR|CD|RI
1: uart:ATMEL_SERIAL mmio:0xF801C000 irq:30 tx:7680 rx:0 DSR|CD|RI
2: uart:ATMEL_SERIAL mmio:0xF8020000 irq:31 tx:372224 rx:371200 CTS|DSR|CD|RI
3: uart:ATMEL_SERIAL mmio:0xF8040000 irq:34 tx:172032 rx:172008 oe:24 CTS|DSR|CD|RI
4: uart:ATMEL_SERIAL mmio:0xF8028000 irq:37 tx:7680 rx:0 DSR|CD|RI

USART0: RS485_0 - write OK, read 0 bytes!
USART1: RS232_0 - write OK, read OK
UART0: RS232_1 - write OK, read - oe:24
USART3: RS485_1 - write OK, read 0 bytes!

In my application lines RS485 do not read data. But if I tested lines RS485 in console by commands echo and cat, so then both RS485 lines write OK also read OK.


Then I enabled only rx DMA:

Code:
# ls -l /proc/device-tree/ahb/apb/serial@f801c000
total 0
-r--r--r--    1 root     root             0 Jan 19 04:04 atmel,use-dma-rx
-r--r--r--    1 root     root             6 Jan 19 04:04 clock-names
-r--r--r--    1 root     root             4 Jan 19 04:04 clocks
-r--r--r--    1 root     root            24 Jan 19 04:04 compatible
-r--r--r--    1 root     root             6 Jan 19 04:04 dma-names
-r--r--r--    1 root     root            24 Jan 19 04:04 dmas
-r--r--r--    1 root     root            12 Jan 19 04:04 interrupts
-r--r--r--    1 root     root             0 Jan 19 04:04 linux,rs485-enabled-at-boot-time
-r--r--r--    1 root     root             7 Jan 19 04:04 name
-r--r--r--    1 root     root            12 Jan 19 04:04 pinctrl-0
-r--r--r--    1 root     root             8 Jan 19 04:04 pinctrl-names
-r--r--r--    1 root     root             8 Jan 19 04:04 reg
-r--r--r--    1 root     root             8 Jan 19 04:04 rs485-rts-delay
-r--r--r--    1 root     root             5 Jan 19 04:04 status
# ls -l /proc/device-tree/ahb/apb/serial@f8020000/
total 0
-r--r--r--    1 root     root             0 Jan 19 04:04 atmel,use-dma-rx
-r--r--r--    1 root     root             6 Jan 19 04:04 clock-names
-r--r--r--    1 root     root             4 Jan 19 04:04 clocks
-r--r--r--    1 root     root            24 Jan 19 04:04 compatible
-r--r--r--    1 root     root             6 Jan 19 04:04 dma-names
-r--r--r--    1 root     root            24 Jan 19 04:04 dmas
-r--r--r--    1 root     root            12 Jan 19 04:04 interrupts
-r--r--r--    1 root     root             7 Jan 19 04:04 name
-r--r--r--    1 root     root             4 Jan 19 04:04 pinctrl-0
-r--r--r--    1 root     root             8 Jan 19 04:04 pinctrl-names
-r--r--r--    1 root     root             8 Jan 19 04:04 reg
-r--r--r--    1 root     root             5 Jan 19 04:04 status
# ls -l /proc/device-tree/ahb/apb/serial@f8028000/
total 0
-r--r--r--    1 root     root             0 Jan 19 04:04 atmel,use-dma-rx
-r--r--r--    1 root     root             6 Jan 19 04:04 clock-names
-r--r--r--    1 root     root             4 Jan 19 04:04 clocks
-r--r--r--    1 root     root            24 Jan 19 04:04 compatible
-r--r--r--    1 root     root             6 Jan 19 04:04 dma-names
-r--r--r--    1 root     root            24 Jan 19 04:04 dmas
-r--r--r--    1 root     root            12 Jan 19 04:04 interrupts
-r--r--r--    1 root     root             0 Jan 19 04:04 linux,rs485-enabled-at-boot-time
-r--r--r--    1 root     root             7 Jan 19 04:04 name
-r--r--r--    1 root     root            12 Jan 19 04:04 pinctrl-0
-r--r--r--    1 root     root             8 Jan 19 04:04 pinctrl-names
-r--r--r--    1 root     root             8 Jan 19 04:04 reg
-r--r--r--    1 root     root             8 Jan 19 04:04 rs485-rts-delay
-r--r--r--    1 root     root             5 Jan 19 04:04 status
# ls -l /proc/device-tree/ahb/apb/serial@f8040000/
total 0
-r--r--r--    1 root     root             6 Jan 19 04:04 clock-names
-r--r--r--    1 root     root             4 Jan 19 04:04 clocks
-r--r--r--    1 root     root            24 Jan 19 04:04 compatible
-r--r--r--    1 root     root            12 Jan 19 04:04 interrupts
-r--r--r--    1 root     root             7 Jan 19 04:04 name
-r--r--r--    1 root     root             4 Jan 19 04:04 pinctrl-0
-r--r--r--    1 root     root             8 Jan 19 04:04 pinctrl-names
-r--r--r--    1 root     root             8 Jan 19 04:04 reg
-r--r--r--    1 root     root             5 Jan 19 04:04 status

# stty -F /dev/ttyS1 115200
atmel_usart f801c000.serial: using dma0chan4 for rx DMA transfers
#

# cat /proc/tty/driver/atmel_serial
serinfo:1.0 driver revision:
0: uart:ATMEL_SERIAL mmio:0xFFFFF200 irq:16 tx:73206 rx:352 RTS|CTS|DTR|DSR|CD|RI
1: uart:ATMEL_SERIAL mmio:0xF801C000 irq:30 tx:521216 rx:520704 DSR|CD|RI
2: uart:ATMEL_SERIAL mmio:0xF8020000 irq:31 tx:587141 rx:586752 CTS|DSR|CD|RI
3: uart:ATMEL_SERIAL mmio:0xF8040000 irq:34 tx:12288 rx:12225 oe:62 CTS|DSR|CD|RI
4: uart:ATMEL_SERIAL mmio:0xF8028000 irq:37 tx:524288 rx:524288 DSR|CD|RI

USART0: RS485_0 - write OK, read OK
USART1: RS232_0 - write OK, read OK
UART0: RS232_1 - write OK, read - oe:62
USART3: RS485_1 - write OK, read OK

If I use only rx DMA, so all USART works OK (write OK, read OK), but UART0 (RS232_1) write OK, read - oe:62.
Is it possible use DMA also for UART (probably not).

Thank you
Regards


Top
 Profile  
Reply with quote  
 Post subject: Re: Data loss during read from USART
PostPosted: Wed Aug 09, 2017 4:26 am 
Offline

Joined: Thu Apr 19, 2007 10:15 pm
Posts: 1470
Location: USA
Emco wrote:
Enable rx DMA and tx DMA:
Code:
# cat /proc/tty/driver/atmel_serial
serinfo:1.0 driver revision:
0: uart:ATMEL_SERIAL mmio:0xFFFFF200 irq:16 tx:48106 rx:489 RTS|CTS|DTR|DSR|CD|RI
1: uart:ATMEL_SERIAL mmio:0xF801C000 irq:30 tx:7680 rx:0 DSR|CD|RI
2: uart:ATMEL_SERIAL mmio:0xF8020000 irq:31 tx:372224 rx:371200 CTS|DSR|CD|RI
3: uart:ATMEL_SERIAL mmio:0xF8040000 irq:34 tx:172032 rx:172008 oe:24 CTS|DSR|CD|RI
4: uart:ATMEL_SERIAL mmio:0xF8028000 irq:37 tx:7680 rx:0 DSR|CD|RI

USART0: RS485_0 - write OK, read 0 bytes!
USART1: RS232_0 - write OK, read OK
UART0: RS232_1 - write OK, read - oe:24
USART3: RS485_1 - write OK, read 0 bytes!
This result is inconsistent with what I see on a SAM9X35; receive is functional with rx and tx DMA channels, just like your USART1.
Your results indicate that the serial driver has received no data nor has it detected any overrun errors.
If the receiver was always disabled for USART0 and USART3 then you would get the exact same results.
You could investigate if there's a conflict with RS-485 mode and DMA regarding receiver enable (i.e. you don't enable SER_RS485_RX_DURING_TX, so the receiver is disabled during tx).
Or have asymmetric tx-PIO/rx-DMA on those two ports.

Emco wrote:
Is it possible use DMA also for UART (probably not).
Yes, the datasheet specifies DMA channels assigned to the UARTs.
You'll just have to write a patch longer than 2 lines for each UART's DT node.

Regards


Top
 Profile  
Reply with quote  
 Post subject: Re: Data loss during read from USART
PostPosted: Wed Aug 09, 2017 12:40 pm 
Offline

Joined: Wed Aug 02, 2017 11:16 am
Posts: 8
Quote:
Yes, the datasheet specifies DMA channels assigned to the UARTs.
You'll just have to write a patch longer than 2 lines for each UART's DT node.
I write patch for DMA of UART.
Now I using only rx DMA for UART (UART0) and for all USARTs (USART0, USART1 and USART2) and now all communications are OK!

Code:
# cat /proc/tty/driver/atmel_serial
serinfo:1.0 driver revision:
0: uart:ATMEL_SERIAL mmio:0xFFFFF200 irq:16 tx:1562202 rx:232 RTS|CTS|DTR|DSR|CD|RI
1: uart:ATMEL_SERIAL mmio:0xF801C000 irq:30 tx:8890409 rx:8888322 DSR|CD|RI
2: uart:ATMEL_SERIAL mmio:0xF8020000 irq:31 tx:10215189 rx:10212352 CTS|DSR|CD|RI
3: uart:ATMEL_SERIAL mmio:0xF8040000 irq:34 tx:10506334 rx:10503168 CTS|DSR|CD|RI
4: uart:ATMEL_SERIAL mmio:0xF8028000 irq:37 tx:8867246 rx:8864771 DSR|CD|RI
USART0: RS485_0 - write OK, read OK
USART1: RS232_0 - write OK, read OK
UART0: RS232_1 - write OK, read OK
USART3: RS485_1 - write OK, read OK

Thank you very much for your help.

Regards
Emco


Top
 Profile  
Reply with quote  
 Post subject: Re: Data loss during read from USART
PostPosted: Thu Aug 17, 2017 12:19 pm 
Offline

Joined: Wed Oct 03, 2007 9:31 am
Posts: 18
Location: EUROPE
I have similar problem (I am using 3 USARTS and two uarts together with all DMA on, and have overruns, I also intensively use SPI with 4Bytes messages to FPGA - so SPI don't use DMA).
Please, in your working mode, do you use DMA only on rx side for all ports, or only for UART0 (and other ports use also tx DMA)? Which kernel version do you use?
Thanks.


Top
 Profile  
Reply with quote  
 Post subject: Re: Data loss during read from USART
PostPosted: Thu Aug 17, 2017 10:18 pm 
Offline

Joined: Thu Apr 19, 2007 10:15 pm
Posts: 1470
Location: USA
misarm wrote:
I have similar problem (I am using 3 USARTS and two uarts together with all DMA on, and have overruns,
Seems like you didn't fully read this thread ("Which kernel version do you use?" is already answered), and apparently you have a different issue.
The original issue turned out to be receive overruns at the U[S]ARTs because programmed I/O was employed instead of DMA.
You're claiming that you are using DMA (are you sure?) and have (receive) overruns. That's a new issue that was never reported by the OP in this thread.

When the OP did enable DMA (for both transmit and receive), a new problem was only with RS-485.
The USART receiver is disabled prior to transmits in RS-495 mode, and the driver neglects to enable the receiver after the transmits are over.
But there were no receive overruns (detected by the USART), since no data was ever received (by the USART).

Regards


Top
 Profile  
Reply with quote  
 Post subject: Re: Data loss during read from USART
PostPosted: Fri Aug 18, 2017 9:40 am 
Offline

Joined: Wed Oct 03, 2007 9:31 am
Posts: 18
Location: EUROPE
Sorry, I have read kernel version just after my post, my original issue is described on this url: http://www.at91.com/discussions/viewtopic.php?f=12&t=22595.

Thank you
I have missing
Code:
        atmel,use-dma-rx;
        atmel,use-dma-tx;

in the device tree, so u(s)arts didn't use DMA...
Now it seems to work.
Thanks


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron