RS485 with CBB-Serial-r02

I’m trying to get RS485 communication on BeagleBone Black with CBB-Serial-r02, but yet unable…

I can’t get RS485 to work because the RTS-signal (P8.33) is driven active low, and the CBB-cape needs it high when using RS485 (coupled to DE/RE).

UART4 TX (P9.13) is signaling so the UART as such is working. If I force DE/RE line high, the RS485 is in fact transmitting.

Timing between RTS and TX is critical, so I cannot rely on userspace to do this - Should be in the driver itself.

I’ve made the tests with

stty -F /dev/ttyO4 9600 crtscts; while true; do echo Hi >/dev/ttyO4; sleep 1; done

also tried

./linux-serial-test -b 9600 -p /dev/ttyO4 -S -e -q 4 -c

One strange thing I noticed is that when using “echo”, the RTS becomes active for each echo-transmission (passive between each loop iteration) if the CBB-cape is configured for RS232, but RTS becomes active for the entire loop-session when the cape is configured for RS485. I presume this has something to do with CTS and RX, which are electrical active on the cape when in RS232 mode.

Using image: bone-debian-9.5-iot-armhf-2018-10-07-4gb.img.xz flashed and booting of internal flash.
Fully APT-upgraded.

/dev/ttyO4 → /dev/ttyS4
dmesg: 481a8000.serial: ttyS4 at MMIO 0x481a8000 (irq = 34, base_baud = 3000000) is a 8250

Tried quite a few combinations of:
*) uboot_overlay_addr0=/lib/firmware/cape-CBB-Serial-r01.dtbo
*) uboot_overlay_addr0=/lib/firmware/CBB-UART4-RS485-00A0.dtbo
*) uboot_overlay_addr0=/lib/firmware/BB-UART4-RTSCTS-00A0.dtbo
(different addresses when combined).

Only BB-UART4-RTSCTS-00A0.dtbo appears to make a difference - Enables the use of RTS.

I have a logic-analyser and an oscilloscope coupled to the system to see what happens.

I need to have RTS P8.33 (alternatively P9.15) active high during a transmission (multiple characters), then go passive low within 3.5 character time (ModBus). I presume this just means that it should go passive low after the last character in the queue has been transmitted.
The RS485 transmitter is active when RTS is high, and passive when RTS is low.

I hope someone can help me out here?


Also Im trying to get rs485 work over gpio with active high when transmitting. Can anyone help? Ive creqtet a net dts with the gpios for enabling the transmitter. Fo i need to patch the kernel for rs485 or is it alreqdy included in the omap driver?

I spent ages trying to get RS485 to work. Maybe it’s possible, but if you give up I found that RS485-USB devices that use FDDI drivers work really well out of the box. For example, this works well:

Can someone explain me why we can’t use the rts signal for the rs485 ?

RS-485 is a multi-drop bus using 2 or 4 wires. It does not include hardware flow control and hence the RTS signal is not used. If you have a device that needs RTS, it is probably RS-232. Look at any wiring diagram for RS-485 connections.

My understanding (and someone can PLEASE) correct me if I’m wrong) is that although there is a user space interface to RS485 via ioctl, the drivers may not support it. At best you have to recompile the kernel with the “other” driver, but that does not support DMA. There seem to be hooks to specify which GPIO pin sets the direction of the transceiver, like in the device tree overlay files, but it’s impossible to see if or where this is made available in the kernel for a driver to use. I gave up and just went with a RS485-USB device and never looked back.

yes and no; those signals have no native meaning in rs485.

but if you've got a 2-wire rs485 bus then you're half-duplex with
no more than one transmitter allowed active at any time. in all likelihood
your rs485 line driver chip will need to be told that its transmitter
is to be enabled (the DE aka driver output enable pin on your garden
variety max488 etc.)

the kernel
does mention that for some wiring setups & drivers that output enabling
can be done via one of the flow control signals.


In my C++ project I get RS485 2,5 MBod speed by using GPIO controlling of DE/RE and its work like a charm.