UART4 RS485 (RTS) not working

Hi all,

For days now, I’ve been attempting to get the Waveshare RS485/CAN Cape to work on Beaglebone black.

I’ve used kernels 4.4.x and 4.9.x-ti mainline, and encountered the same problem.

The cape can use any UART (have been trying with one), and requires the use of pin P9_42 (0x164) as an RTS pin.

The dtbo (standard from GitHub - beagleboard/bb.org-overlays: Device Tree Overlays for bb.org boards which uses pin P9_27) loads fine using

echo BB-UART4-RS485 > /sys/devices/platform/bone_capemgr/slots

A “cat /sys/devices/platform/bone_capemgr” reveals the slot has been loaded correctly.

The HDMI has successfully been disabled.

Three problems arise:

PROBLEM 1:
The wavheshare cape requires the pulldown of both UART pins (I used UART4), as it leaves the pins floating through the RS485 transceiver if left standard. Now, the tricky thing is, if I enable BB-UARt4-RS485 in the /boot/uEnv.txt file, it loads the cape fine, but will not do pulldowns. If I allow the beaglebone to boot, then echo the BB-UART… at slots, the pulldown works and the transceiver can send a signal through, which is curious as it is exactly the same dtbo it loads, whether from uEnv.txt or echo.

PROBLEM 2:
Once loaded using echo after start, if I “cat /proc/tty/driver/serial” immediately after loading UART RS485 overlay, the flags I’m presented with are as below:

0: uart:8250 mmio:0x44E09000 irq:158 tx:8304 rx:0 RTS|CTS|DTR|DSR

1: uart:unknown port:00000000 irq:0

2: uart:unknown port:00000000 irq:0

3: uart:unknown port:00000000 irq:0

4: uart:8250 mmio:0x481A8000 irq:198 tx:0 rx:0 CTS|DSR

5: uart:unknown port:00000000 irq:0

Showing UART4 (the one I’m using) has not loaded the CTS and RTS flags appropriately. However, if, before performing the cat, I screen into ttyS4 or ttyO4 or echo some characters at the port, and then I perform the “cat” as above, the RTS and DTR flags are both raised on 4. Thereafter, if I screen in on ttyO4, and then quit, the RTS flag disappears after a cat. Weird.

However, regardless of these results, I’m left with the following main problem,

PROBLEM 3:
Regardless of the flag position or whether I use the default BB-UART4-RS485-00A0.dtbo from the source, the RTS pin does not switch (both P9_27 and P9_42 are unresponsive to any efforts to communicate on the UART4, where the UART transmits as evidenced by the oscilliscope, but the oscilliscope shows that the RTS pin P9_42/27 does not move at all). I need to get pin 9_42 to switch for RTS during uart, else this cape (and the beaglebone) are useless to me.

After copious amounts of time reading up on this, it seems that its a common problem, and something to do with the OMAP serial driver vs the 8250 driver malfunctioning? If someone could provide some insight to the problem, or a guide on how to get RTS working on this Beaglebone I’d be very appreciative.

Kind regards,
Matt.

Hi Mat,

I have the same issue: any response yet?

Hi,
The same problem ...

My kernel is 3.8.13-bone69,
My UART2 works without flow control (Checked with a loopback between TX and RX),
But, if I enable RTS/CTS about UART2 (P8_38/P8_37) ... nothing works !
I have also a loopback between RTS and CTS ...
Checked also with null modem cable and a computer ...

You found a solution ?

Phillip I did. Give me a moment and I’ll post.

Can you write the solution? I have sam problem. Thanks

  1. április 6., csütörtök 11:06:30 UTC+2 időpontban Matthew Bezuidenhout a következőt írta:

matthew, can you please post your solution then?

Did you ever get this to work

I am using the Nelson yakbuild kernel 4.9.45 and disabled the 8250 and enabled omap serial in kernel configuration

using same rs485 dtso overkay I can not get RTS to work
and nothing transmits.

I can not find anything on web to solve this.
Do you have a solution procedure?

dennis
dmezzatesta@gmail.com

You have to use the hardware cts. Waveshare does not do this and youll have to solder in this wire/cts

https://github.com/RobertCNelson/bb-kernel/issues/38

  1. november 10., péntek 20:33:49 UTC+1 időpontban dmezz...@gmail.com a következőt írta:

We used the rs485 version/branch of the modbus on github. Sorry i meant to say rts instead of cts.

I used my github as notes. Follow readmes and see if it helps. Its been a while since we did this. Let me know if more help is needed

https://github.com/rwdutoit/beaglebone?files=1

Hi,

Will the 8250 driver still allow “manual” control of the RTS line for a given UART from an application like Python or C# (where the application toggles the state of the RTS line, rather than driver, after sending a request message in order to toggle the 485 XCVR), or is the OMAP driver (in place of the 8250 driver) needed for this as well?

I’ve attempted to associate the RTS line for UART5 with GPIO5_8 (which is connected to the DE toggle on a 485 chip) via the device tree (kernel 4.4.y), followed by calling setRTS(True/False) from Python, but that doesn’t appear to be switching the 485 XCVR. However, I can still use sysfs commands to toggle the GPIO5_8 connected to the 485 chip to control the direction of transmission.

In order to help differentiate between an incorrect device tree configuration vs. needing to recompile the kernel with the OMAP driver instead of the 8250 driver, I’m wondering if you know whether the 8250 driver will support what we’re trying here. Everything I’ve read (including https://groups.google.com/forum/#!msg/beagleboard/nMtRpdWSJu0/EDSXqGpiBAAJ) seems to suggest that the 8250 doesn’t yet handle toggling the RTS/CTS lines on its own based on delays between characters, but I haven’t seen anything about manual control.

Following is a snippet/fragment from my device tree. LATE DISCLOSURE From UART5_8, you can see that this is for the BB-X15, but I believe the same issue pertains to both the BBB and the BB-X15:

&uart5 {
pinctrl-names = “default”;
pinctrl-0 = <&uart5_pins>;
status = “okay”;
rts-gpio = <&gpio5 8 GPIO_ACTIVE_HIGH>;
rs485-rts-active-high;
rs485-rts-delay = <0 0>;
linux,rs485-enabled-at-boot-time;
};

Thanks!!!

I’m fairly confident the answer to my question about whether the 8250 driver implements “partial 485 capability”, (allowing Python or a C#/.net application to manually control the RTS line for a given UART via the driver) is NO. But the OMAP driver DOES appear to allow this.

When I toggle the serial driver defines in kernel 4.4.y’s defconfig file ( see below), re-build the kernel, and deploy to my target (along with the device tree which couples a given GPIO on my custom board to UART5) I’m only able to toggle the RTS line from within Python (to enable/disable the 485 chip’s transmit) when I open the /dev/ttyO4 device in Python, but not with the /dev/ttyS4 device.

Additionally, the device tree containing the fragment below appears to be successfully coupling gpio5_8 and UART5, so this appears to be a driver issue rather than a device tree user error issue.

I built the RCN 4.4.y kernel both ways:

In paches/defconfig:

(1) {CONFIG_SERIAL_8250_OMAP=n, CONFIG_SERIAL_OMAP=y}

(2) {CONFIG_SERIAL_8250_OMAP=y, CONFIG_SERIAL_OMAP=n}

*** Also worth noting is I lost my serial console until I enabled, CONFIG_SERIAL_OMAP_CONSOLE=y ***

Ironically enough, my current build (built using configuration (1) above) appears to have BOTH the OMAP and 8250 devices which isn’t what I would expect… I’ve only tried writing to /dev/ttyO4 at this point. There maybe some other defines which need to be changed in the defconfig to switch off the 8250, named serial device files in the /dev/ directory. Film at 11 on that one…

A couple of things you may want to investigate before you use the OMAP driver vs. the 8250:

  1. According to an older Wiki from TI, the OMAP serial driver doesn’t use DMA in serial transfer, but 8250 does. Not sure if this is still the case??

http://processors.wiki.ti.com/index.php/Sitara_Linux_UART_-_Switching_to_8250_Driver#Overview

  1. For this experiment, we coupled an unrelated GPIO signal (for the RTS signal) with a given UART through the device tree and found that Python can only toggle the RTS line when connected to an OMAP driver as opposed to 8250 driver. Note: We didn’t try picking a pinmux/IOSET which already has an RTS/CTS signal defined for a given UART. The 8250 driver might allow that use case to work… Will let you know what we find out…

Thanks!

Jeff

Hi,

With RS485-modbus-converters the timing of the RTS pin is CRUCIAL. Software toggling (GPIO toggling) of this pin (in the RS485/libmodbus library someone added this capability) have shown (on oscilloscope) to not be repeatable or works 1 in 30 attempts.

I think we used the stock standard bone-debian-8.7-lxqt-4gb-armhf-2017-03-19-4gb.img and the RS485 branch of libmodbus library.

And hardware toggling of RTS pin with dedicated RTS pin.

I think if you check the stock standard image name i provided it will answer your questions: I believe OMAP is not loaded from some version onwards

dont forget to remove jumper that bypasses RTS pin and grounds/raises it for sending/receiving only. can’t remember the order

Thank you!

?? Are you saying that lib modbus (which we haven’t tried) has issues with reliably toggling the RTS line??

One clarification with what I meant by “manual toggling of the RTS line.”

By manual software toggling, we specifically mean toggling the RTS line in the protocol as follows:

  1. Set RTS line high to switch 485 chip to allow us to transmit to the other party on the 2-wire, half-duplex, 485 interface.
  2. Transmit out the multi-byte MODBUS register request to the other party.
  3. Set the RTS line low to switch the 485 chip to allow the other party to transmit to us on the 2-wire interface.
  4. The other party replies to us with a multi-byte packet consisting of the MODBUS register(s) we’re requesting.

We’re not talking about toggling the RTS line around individual characters in the multi-byte messages. That’s something the driver would have to handle (and I understand that the OMAP driver does handle this toggling). I wouldn’t THINK application software would be fast enough to toggle RTS lines at the character rate, especially at higher baud rates.

One question:

If the 8250 driver utilizes a DMA buffer by default, how is the driver then able to toggle RTS/CTS lines in real time at the character rate? Seems like the driver would still have to monitor data directly coming in from or going out of the UART which would defeat the purpose of the DMA, right?? It seems like you or the driver would have to switch off the DMA if hardware flow control is used Hmmm, does this seem like a task for the PRU??

Hello
may be there is wrong hardware design with Waveshare RS485/CAN Cape. I don’t think is good idea to connect RS485 driver RX pin to CAN driver TX pin. if you desolder can driver rs485 should work fine.

br
harry

Did you come right? Sorry, this account-email is not read frequently

Yes, Dont solder Rx-serial to Rx-CAN-bus. The email/posts above are concerning the RTS pin and allocating another BeagleBone to it: the DMA one and not GPIO one

sorry. I saw the question about Waveshare RS485 / CAN Cape (and I did not read the question carefully) and because it was wrong made I decided to share.

br
harry