RTS not working on i.MX6 UART

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

RTS not working on i.MX6 UART

Jump to solution
6,351 Views
marcocavallini
Contributor V

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";

};

Tags (4)
1 Solution
3,036 Views
marcocavallini
Contributor V

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

View solution in original post

0 Kudos
11 Replies
3,036 Views
roshandsouza
Contributor II

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

1.bmp

How can we make the transmit enable signal go low immediately after the transmission is completed ???

0 Kudos
3,037 Views
marcocavallini
Contributor V

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

0 Kudos
3,036 Views
csotoalonso
Contributor III

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

0 Kudos
3,036 Views
marcocavallini
Contributor V

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

http://www.KoanSoftware.com

0 Kudos
3,036 Views
lonsn
Contributor I

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.

0 Kudos
3,036 Views
marcocavallini
Contributor V

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

0 Kudos
3,036 Views
marcocavallini
Contributor V

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;

}

0 Kudos
3,036 Views
angelo_d
Senior Contributor I

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.

3,036 Views
gusarambula
NXP TechSupport
NXP TechSupport

Thank you, Angelo, for the help! I'm sure it will also help other community users.

0 Kudos
3,036 Views
marcocavallini
Contributor V

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

3,036 Views
angelo_d
Senior Contributor I

Hi Marco,

please check my reply on your original post, hope it helps.

0 Kudos