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):


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