i.MX7D RS485 problems

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

i.MX7D RS485 problems

Jump to solution
329 Views
mischo5500
Contributor III

Hi,

I'm trying to get RS485 running on our custom i.MX7D based board.

I can write some data to RS485 correctly, but when any data is received, there are some random data automatically generated to the line probably by imx.c driver. I have tried to interconnect 2 RS485 lines, open them from C++ code and just write few bytes to one of them and it results in endless pinging of random data on the line.

Both RS485 are working in half-duplex mode with SN65HVD1780 chip, direction control using RTS as GPIO.

Devicetree (UARTS are aliased to ports 2,3):

&uart4 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_uart4>;
	assigned-clocks = <&clks IMX7D_UART4_ROOT_SRC>;
	assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>;
	
	rts-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>; //DIR control
	linux,rs485-enabled-at-boot-time;
	rs485-rts-delay = <1 1>;		// in milliseconds
	status = "okay";
};

&uart6 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_uart6>;
	assigned-clocks = <&clks IMX7D_UART6_ROOT_SRC>;
	assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>;
	
	rts-gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>; //DIR control
	linux,rs485-enabled-at-boot-time;
	rs485-rts-delay = <0 1>;		// in milliseconds
	status = "okay";
};

Part of testing code:

bool InitRS485(int fd)
{
	struct serial_rs485 rs485conf;
	rs485conf.flags |= SER_RS485_ENABLED; //Enable RS485 mode
	rs485conf.flags |= SER_RS485_RTS_ON_SEND; //Set logical level for RTS pin equal to 1 when sending
	rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND); //Set logical level for RTS pin equal to 0 after sending
	rs485conf.delay_rts_before_send = 1; //Set rts delay before send
	rs485conf.delay_rts_after_send = 1; //Set rts delay after send
	if(ioctl(fd, TIOCSRS485, (void*)&rs485conf) == 0)
	{
		struct termios tty; //Get current settings
		if(tcgetattr(fd, &tty) == 0)
		{
			tty.c_cflag &= ~PARENB;		//No Parity
			tty.c_cflag &= ~CSTOPB;		//1 Stop Bit
			tty.c_cflag &= ~CSIZE;
			tty.c_cflag |= CS8;			//8 Bits
			cfsetspeed(&tty, 19200); //Set baudrate
			if(tcsetattr(fd, TCSANOW, &tty) == 0) //Set settings to port
			{
				return true;
			}	
		}		
	}
	return false;
}

void rs485TaskTest1()
{
	int fd = open("/dev/ttymxc2", O_RDWR);
	if (InitRS485(fd))
	{
		const uint8_t data[] = { 0x11, 0x01, 0x02, 0x32, 0x00};
		write(fd, data, sizeof(data));
	}
	close(fd);
}

void rs485TaskTest2()
{
	int fd = open("/dev/ttymxc3", O_RDWR);
	if (InitRS485(fd))
	{
		while (1)
		{
			std::this_thread::sleep_for(100ms);
		}	
	}
	close(fd);
}

As you can see, I'm writing on first RS485 and just opening port on second with sleeping.

Result caught on analyzer (1 - DIR, 2 - RX, 3 -TX):

image.pngimage.png

As you can see, there is also problem, that on first transition with normal data, RTS delay before send (delay_rts_before_send) is not applied. On randomly generated transitions it is applied correctly.

Any ideas, what am I doing wrong, or I have hit some kind of bug?

I'm running kernel version 5.15.52. I have tried to backport changes in imx.c from 6.x kernel, but with same results.

Thanks in advance,

Michal Špánik

Tags (2)
0 Kudos
Reply
1 Solution
264 Views
AldoG
NXP TechSupport
NXP TechSupport

Hello,

Have you tried usin latest kernel instead of backporting?
Also, you may try using test code we have available under unit_test:
https://github.com/nxp-imx/imx-test/blob/lf-6.6.3_1.0.0/test/mxc_mcc_tty_test/mxc_mcc_tty_test.c

https://github.com/nxp-imx/imx-test/blob/lf-6.6.3_1.0.0/test/mxc_uart_test/mxc_uart_test.c

Best regards/Saludos,
Aldo.

View solution in original post

0 Kudos
Reply
3 Replies
302 Views
mischo5500
Contributor III

To simplify the usecase, this happens, when I

echo "12345" > /dev/ttymxc3

with interconnected port 2 and 3 (port 2 is with connected analyzer)

image.png

It seems OK. But when I run

cat /dev/ttymxc2

and

echo "12345" > /dev/ttymxc3

which opens the receiving port (but does not process data in any way), it looks like this:

image.png

It seems, that data is automatically echoed back to transmit after receive (even with correct RTS).

If I disable DMA, First byte is echoed immediately and rest of data is cut (because of direction change).

0 Kudos
Reply
265 Views
AldoG
NXP TechSupport
NXP TechSupport

Hello,

Have you tried usin latest kernel instead of backporting?
Also, you may try using test code we have available under unit_test:
https://github.com/nxp-imx/imx-test/blob/lf-6.6.3_1.0.0/test/mxc_mcc_tty_test/mxc_mcc_tty_test.c

https://github.com/nxp-imx/imx-test/blob/lf-6.6.3_1.0.0/test/mxc_uart_test/mxc_uart_test.c

Best regards/Saludos,
Aldo.

0 Kudos
Reply
240 Views
mischo5500
Contributor III

Hi,

I found call to

cfmakeraw()

in second test code, which seems to solve the issue. It was caused by ISIG flag, which is set by default and probably triggers on transferred data in our protocol/my test scenario.

Thank you very much for your support,

Michal Špánik