Hello,
I am using a linux kernel-3.10.17 and I'm trying to communicate between two UARTS on a i.MX6S CPU.
I am using RS485 adapters and the problem is that the RTS signal is always high when I transmit and receive.
Do I need any special setting to manage RTS/CTS?
This is my device tree excerpt
Thank you
uart2m {
pinctrl_uart2_m: uart2grp-m {
fsl,pins = <
MX6QDL_PAD_GPIO_7__UART2_RX_DATA 0x1b0b1 // new (ALT4)
MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1 // default
MX6QDL_PAD_EIM_D28__UART2_CTS_B 0x1b0b1 // new (ALT4)
MX6QDL_PAD_EIM_D29__UART2_RTS_B 0x1b0b1 // new (ALT4)
>;
};
};
uart3m {
pinctrl_uart3_m: uart3grp-m {
fsl,pins = <
MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1 // new (ALT2)
MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1 // new (ALT2)
MX6QDL_PAD_EIM_D23__UART3_CTS_B 0x1b0b1 // new (ALT2)
MX6QDL_PAD_EIM_D31__UART3_RTS_B 0x1b0b1 // new (ALT4)
>;
};
};
&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart2_m>;
fsl,uart-has-rtscts;
status = "okay";
};
&uart3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart3_m>;
fsl,uart-has-rtscts;
status = "okay";
};
Solved! Go to Solution.
In addition to the proper MUX settings, it was needed to properly manage manually the RTS signal during start_tx and stop_tx in the imx.c driver. The diriver as-is is not able to manage RS485 devices.
--
Marco Cavallini
Hi All,
We are using the imx6ULL processor MCIMX6Y2CVM05AA and RS485 transceiver IC ST485BDR in our design.We are facing a similar issue related to RS485 RTS signal as above.We are using the UART port 2 of the processor ( UART2_TX transmit function,UART2_RX for receive function,UART3_RXD pin for TX enable and RX enable of RS485 transceiver).We are using kernel version 4.1.x.x.
We were able to toggle the RTS line of UART2 by configuring it as a GPIO line but we are missing few bytes and not able to receive the complete data.
The transit enable from ULL processor is not going low immediately after the transmission is completed( Highlighted in green in attachment). We are losing few bytes as the delay between the Rx enable and Rx data is very small (Highlighted in Red in attachment).
How can we make the transmit enable signal go low immediately after the transmission is completed ???
In addition to the proper MUX settings, it was needed to properly manage manually the RTS signal during start_tx and stop_tx in the imx.c driver. The diriver as-is is not able to manage RS485 devices.
--
Marco Cavallini
Hi Marco.
Would you mind sharing the changes you made to the driver, please? I'm struggling with the same problem and I'm unable to make the RTS signal move at all.
Thanks in advance
Hi Marco.
Would you mind sharing the changes you made to the driver, please? I'm
struggling with the same problem and I'm unable to make the RTS signal
move at all.
Thanks in advance
Hi Carlos,
I am going to publish the patch here
http://www.koansoftware.com/it/content/add-rs485-support-freescale-imx6
Distinti Saluti / Best Regards
--
Marco Cavallini | KOAN sas | Bergamo - Italia
embedded and real-time software engineering
Phone:39-035-255.235 - Fax:39-178-22.39.748
Hi Marco,
I used the patch you provided. After test, I found the RTS GPIO stops before the TX data sending over. Which kernel branch you based on for this patch?
Thank you.
The patch is for kernel 3.10.17 as described in the link above.
FYI with the new kernel 4.9 I'm using now this feature is implemented by default (not using my patch though).
I am using this program to test RTS, but the signal is always high and not working.
Anyone have a hint about this?
TIA
/* bumprts.c */
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
static struct termios oldterminfo;
void closeserial(int fd)
{
tcsetattr(fd, TCSANOW, &oldterminfo);
if (close(fd) < 0)
perror("closeserial()");
}
int openserial(char *devicename)
{
int fd;
struct termios attr;
if ((fd = open(devicename, O_RDWR)) == -1) {
perror("openserial(): open()");
return 0;
}
if (tcgetattr(fd, &oldterminfo) == -1) {
perror("openserial(): tcgetattr()");
return 0;
}
attr = oldterminfo;
attr.c_cflag |= CRTSCTS | CLOCAL;
attr.c_oflag = 0;
if (tcflush(fd, TCIOFLUSH) == -1) {
perror("openserial(): tcflush()");
return 0;
}
if (tcsetattr(fd, TCSANOW, &attr) == -1) {
perror("initserial(): tcsetattr()");
return 0;
}
return fd;
}
int setRTS(int fd, int level)
{
int status;
if (ioctl(fd, TIOCMGET, &status) == -1) {
perror("setRTS(): TIOCMGET");
return 0;
}
if (level)
status |= TIOCM_RTS;
else
status &= ~TIOCM_RTS;
if (ioctl(fd, TIOCMSET, &status) == -1) {
perror("setRTS(): TIOCMSET");
return 0;
}
return 1;
}
int main()
{
int fd;
char *serialdev = "/dev/ttymxc1";
fd = openserial(serialdev);
if (!fd) {
fprintf(stderr, "Error while initializing %s.\n", serialdev);
return 1;
}
while (1) {
setRTS(fd, 0);
sleep(1); /* pause 1 second */
setRTS(fd, 1);
}
closeserial(fd);
return 0;
}
Hi Marco,
I see 2 RX here:
uart2m {
pinctrl_uart2_m: uart2grp-m {
fsl,pins = <
MX6QDL_PAD_GPIO_7__UART2_RX_DATA 0x1b0b1 // new (ALT4)
MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1 // default
MX6QDL_PAD_EIM_D28__UART2_CTS_B 0x1b0b1 // new (ALT4)
MX6QDL_PAD_EIM_D29__UART2_RTS_B 0x1b0b1 // new (ALT4)
>;
};
};
Also be sure the pinmux settings are really applied, sometime, if the pinmux config are not set in proper place, they are not really applied.
One way to be sure they are applied is to change them on the original dtsi.
Thank you, Angelo, for the help! I'm sure it will also help other community users.
Hi Angelo,
thanks for pointing me out this glaring oversight.
Inexplicably the transmission worked with that setting.
I have now modified but nothing changes course, because the cpu MX6 is not able to drive automatically the RTS signal, it must be driven by hand.
MX6QDL_PAD_GPIO_7__UART2_RX_DATA 0x1b0b1 | |||
MX6QDL_PAD_EIM_D27__UART2_TX_DATA 0x1b0b1 | |||
MX6QDL_PAD_EIM_D28__UART2_CTS_B 0x1b0b1 | |||
MX6QDL_PAD_EIM_D29__UART2_RTS_B 0x1b0b1 |
I'm customizing the driver imx.c
Ciao
--
Marco
Hi Marco,
please check my reply on your original post, hope it helps.