This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

66AK2G12: Linux RS485 Support

Part Number: 66AK2G12

Hello,

I am working on a Linux design that uses UART1 (/dev/ttyS1) for RS-485 communication on PSDK 6.3. The current implementation is using the RTS and CTS pins, pinmuxed as GPIO, to control the tri-state RS-485 buffer.

For a few reasons, we'd like to move the bus control signals out of userspace and into kernelspace.  Due to the nature of our bus, the control signals must be tightly coupled with the transmit start/finish coming from the K2G.  I've been doing some reading and have discovered that the Linux Kernel has some support for RS485, referenced in Documentation/serial/serial-rs485.txt in the kernel source.

The generic 8250 driver includes some code to support RS485 emulation using the RTS line, but this is not enabled by default.  I made some tweaks to 8250_port.c to add this for the DA830 8250 driver (listed as the compatible K2G driver) but have not had success getting it to work. The RTS line blips when calling the function serial8250_em485_rts_after_send, but I never see it idle low as I would expect on a bus waiting for receive.

I have seen mention of the omap_serial driver having support for RS485 and have seen recommendations to use that driver with the AM335X processors, but have seen no mention of the compatibility of that driver with K2G -- except in the online SDK docs where it is mentioned, but not explicitly listed as compatible with K2G.  I have also seen that the omap_serial driver is old and may have been replaced by 8250_omap.c.  I used the omap_8250_rs485_config function from 8250_omap.c to model my modifications to the 8250_port driver, but it seems that the RTS line isn't toggling when expected.  I did change the pinmux to enable the RTS pin, and I do see it blip occasionally.

I'm not certain that this is the best solution anyway, since we have two separate lines controlling the TX_EN and nRX_EN lines.  Unless we were to hog the nRX_EN line low and ignore receive data while transmitting, we would need control of both pins, and the hardware doesn't support setting CTS as an output, nor does the driver support GPIO RTS when in RS485 mode.

Alternatively, I could write a line discipline driver that can be installed by our application and takes control of the two GPIO pins, toggling them just before and just after a transmit.  Since I've already written one of those to use a UART for thermal data, it would be straightforward.

I am wondering if there are any recommendations for using the kernel drivers for RS485 on K2G, and if so, if there are any examples I can look at to get a feel for how this should work.  If there is not a driver that will do what I need, I'll probably just write the ldisc and be done with it, but I'd love to have the 8250 driver do the work, maybe even have OF/DTS configuration options for it.

Thanks,

Jeff

  • Hi Jeff,

    The kernel 8250 serial core and 8250_omap.c driver support using RTS line (not in gpio mode) to control the DE pin on the RS-485 transceiver. I don't recommend to use serial_omap driver, it is no longer maintained.

    Why do you need to use two pins to control the RS-485 transceiver? I am not sure kernel supports it.

  • The short answer is that we have hardware in production that is connected that way, but I can work around that.

    Is the 8250_omap.c driver compatible with K2G?  Or do I need to use the generic 8250 driver?

    The RS485 emulation in the generic driver seems to require some driver modifications, as it appears that the 485 functions are not "hooked" into the port structure by default.  After making some changes I was able to have the driver handle the RS485 IOCTLs, but I was not able to get the RTS line (muxed as the RTS line, not GPIO), to toggle and go low when receiving.

    I can modify drivers if I need to, but I was mostly wondering if TI had a recommended solution for RS485 on K2G, regardless of my needs to toggle two pins.  If the 8250_omap driver will work on K2G I'll give that a try.  Otherwise, I'll stick to modifying the generic driver.

  • Hi Jeff,

    Sorry I spoke too soon. K2G doesn't use 8250-omap driver, rather 8250_of.c.

    Looking at keystone-k2g.dtsi, the UART nodes have compatible "ti,da830-uart", which corresponds to 8250-of driver.

    By looking at 8250_of.c, I don't think it supports RS-485 DE control, the driver doesn't define rs485_config callback in &port8250.port struct.

    But I don't it is difficult to add RS485 support in 8250_of.c. Please refer to omap_8250_rs485_config() in 8250_omap.c to add a callback to port8250.up.rs485_config in of_platform_serial_probe() in8250_of.c. I think this is the only piece missing for RS485 suport in 8250_of.c.

  • Hi Jeff,
    I have a similar situation. The temporary solution was to replace the rs485 transmitter with a rs485 transmitter with auto-detection (in my case MAX13487)
    But it didn't completely solve my problem. If I understand correctly, K2G uses the 8250 driver and does not support DE control. Does it need to be added manually? Or can another driver be used?
    Could you share a solution to this problem?