RS485

      Dear Support Team,

      has anyone succesfully used an UART as RS485 port? I tried with UART B (/dev/ttymxc1) and a SN65HVD10 driver circuit. I'm able to send data but I'm not able to receive data. RS485 support in general is included in kernel /drivers/tty/serial/imx.c.
      (armstonea9r2dl with software release 3.0)

      CTS is wired to circuits RE/DE pins. This seems to work OK. Maybe the problem may come from levels of RX/TX lines before setting RE/DE to low for reading?

      Here some pieces of code from my application:

      Source Code

      1. #define TIOCSRS485 0x542F
      2. struct termios termAttr;
      3. int fdRTU;
      4. ...
      5. fdRTU = open("/dev/ttymxc1", O_RDWR | O_NOCTTY | O_NONBLOCK);
      6. if (fdRTU==-1) {
      7. printf("Unable to open RTU port\n");
      8. return(-1);
      9. }
      10. fcntl(fdRTU, F_SETFL, FASYNC);
      11. fcntl(fdRTU, F_SETOWN, getpid());
      12. tcgetattr(fdRTU,&termAttr);
      13. cfsetispeed(&termAttr,B19200);
      14. cfsetospeed(&termAttr,B19200);
      15. termAttr.c_cflag &= ~PARENB;
      16. termAttr.c_cflag &= ~CSTOPB;
      17. termAttr.c_cflag &= ~CSIZE;
      18. termAttr.c_cflag |= CS8;
      19. termAttr.c_cflag |= (CLOCAL | CREAD);
      20. termAttr.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG | IEXTEN);
      21. termAttr.c_oflag &= ~OPOST;
      22. tcsetattr(fdRTU,TCSANOW,&termAttr);
      23. struct serial_rs485 rs485conf;
      24. rs485conf.flags |= SER_RS485_ENABLED;
      25. rs485conf.flags |= SER_RS485_RTS_ON_SEND;
      26. rs485conf.flags &= ~SER_RS485_RTS_AFTER_SEND;
      27. rs485conf.delay_rts_before_send = 0x0001;
      28. rs485conf.delay_rts_after_send = 0x0001;
      29. rs485conf.flags &= ~SER_RS485_RX_DURING_TX;
      30. if (ioctl (fdRTU, TIOCSRS485, &rs485conf) < 0) {
      31. printf("Error RS484\n");
      32. }
      33. modOutData[0]=35;
      34. modOutData[1]=2;
      35. modOutData[2]=0;
      36. modOutData[3]=0;
      37. modOutData[4]=0;
      38. modOutData[5]=1;
      39. modOutData[6]=0xBF;
      40. modOutData[7]=0x48;
      41. write(fdRTU,modOutData,8);
      42. size=read(fdRTU,modInData,8);


      I also tried to find some newer versions of /drivers/tty/serial/imx.c but without success (at least while compiling the kernel).

      Anyone any idea?
      Thanks.
      As far as I can see the way you are doing it is totally correct. So there may be some problem with the RS485 driver. We have to check this.

      Your F&S Support Team
      F&S Elektronik Systeme GmbH
      As this is an international forum, please try to post in English.
      Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.
      That would be nice to have this working because it's one of the last things to complete our hardware around the armstone. I also had a look at some imx6 forums and found some (maybe old) issues but it was impossible for me to get them into the kernel for now.

      Thanks
      OK, I have checked this again. RS485 depends on using RTS as a signal to switch between sending and receiving. So you need pin 19 (UART_B_RTS) of the connector, not pin 21 (UART_B_CTS).

      Please not that there is a naming confusion on i.MX6 CPUs. The reference manuals mix up RTS and CTS, and therefore our RTS signal is internally the CTS signal of the i.MX6 UART port. So in the device driver they are talking about CTS, but the official name of the outgoing handshaking signal is RTS and we use the correct name in all our documentation. Therefore you need to take our RTS pin.

      Your F&S Support Team
      F&S Elektronik Systeme GmbH
      As this is an international forum, please try to post in English.
      Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.
      Yes, that's clear now. I tried both pins (RTC/CTS) anyway.
      When I check the RTS line with an OSCI I can see the level going from 0V to 3.3V and going back to 0V after sending the data.
      This RTS is connected to the SN65HVD10 RE/DE pins. That seems to be working so far.

      But it's not possible for me to read or write data to a Modbus RTU Relais module with this configuration.
      When I wire the RE/DE pins to 3.3V directly I can write data without problems and switch some relais. But of course it's not possible to read back data with RE/DE on high level.

      The problem seems to be when the RTS line will be set to 0V. Then the RS485 receiver will discard the sent data (RED error led).
      Maybe the problem is caused by levels of RX/TX lines before setting RE/DE to low for reading?
      Maybe the problem is a timing issue because

      Source Code

      1. rs485conf.delay_rts_before_send = 64;
      2. rs485conf.delay_rts_after_send = 64;

      values seem not to be used inside the imx6 driver.

      I tried many things beginning from driving the RE/DE with an GPIO instead of RTS to using different new versions of /drivers/tty/serial/imx.c from the NXP/Freescale imx6 kernel branches. All without success.

      Can anyone confirm this or has anyone RS485 working in both directions?

      Thanks for any hint.
      Dear Mr. Schubert,

      sorry for my late response. Normally the rs485 should work. I tried it with UART1 (Connector Pin 18/20/22), in user-space its ttymxc0. I converted the signal with the SN75HVD12D to rs485.
      I didn't change anything in the device tree or kernel driver. I wrote a small c-file which get access to the device, set different options and send/receive data.
      At the opposite point of the armstonea9r2 i have a picocoma5. I can send and receive data between these 2 boards without problems.

      Did you have added the 120 Ohm terminating resistor?

      Your F&S Support Team
      F&S Elektronik Systeme GmbH
      As this is an international forum, please try to post in English.
      Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.
      Dear fs-support_PJ,

      thank you very much for checking this issue. I'm facing the same problems when using the terminating resistor. As soon as the RTS line will be drawn to low level the Modbus package will be refused by the receiver. When holding RTS on high level all the time it's possible to write at least. I will try using UART1 instead of UART2 now. Is it possible to get your little c program just to exclude software issues on my side.

      I guess the different RS485 transceiver SN65HVD10 should be no problem - there are no significant differences: ti.com/product/SN75HVD12

      Thanks again.
      Hi...this is the same case as i faced with my heat pump. If heat pump does not receive acknowledge in certain time period, pump will raise an alarm and alarm mode is activated. Actions on alarm mode can be configured. The different alternatives are that the Heat pump stops producing hot water and/or reduces the room temperature.