The application transmits bytes on UART1, but P9.19 never drives the RS-485 transceiver enable input. The request originates in the application, passes through the Linux serial interface and UART driver, reaches the UART1 peripheral, and then stops if the overlay is inactive or the pin remains assigned to I2C2. Follow the packet from the physical pin back to the application.
Where does the transmit-enable request travel?
Automatic direction control requires every element in the path to agree that P9.19 is UART1 RTS. A correct application call cannot overcome an inactive overlay or the wrong pin-multiplexer function.
| Path element | Required configuration | Failure indication |
|---|---|---|
| Application | Enable Linux RS-485 mode with TIOCSRS485
|
RTS remains under ordinary modem-control semantics |
| Serial driver | Accept SER_RS485_ENABLED and the selected RTS polarity |
ioctl() returns an error or readback lacks the flag |
| UART1 | Transmit on UART1 and generate RTS through its hardware function | TXD operates, but RTS does not follow transmission |
| Pin multiplexer | Assign P9.19 to uart1_rtsn with MUX_MODE0
|
The pin appears as I2C2 or a generic GPIO |
| Header and transceiver | Connect P9.19 to the transceiver direction-control input with the correct polarity |
RTS changes at the header, but the RS-485 driver does not switch |
The first commissioning check is physical: probe P9.19 while transmitting. If the line never changes, inspect pin ownership before changing protocol logic.
Is P9.19 wired and biased correctly?
P9.19 can serve different peripheral functions. MUX_MODE0 selects uart1_rtsn; MUX_MODE7 selects GPIO. Use mode 0 for kernel-controlled UART RTS. Mode 7 is appropriate only when application logic intentionally controls a GPIO outside the UART driver.
| P9.19 setting | Owner | Control method | Automatic UART direction control |
|---|---|---|---|
MUX_MODE0 |
UART1 | Serial driver and UART RTS function | Yes, after enabling RS-485 mode |
MUX_MODE7 |
GPIO subsystem | GPIO application interface | No |
| Default I2C2 assignment | I2C2 or its pinmux helper | I2C subsystem | No |
The default configuration gives P9.19 a weak internal pull-up. If the RS-485 driver-enable input is active high, add an external 1 kΩ pulldown or select another suitable pin whose default state is a pulldown. This prevents an unintended transmitter-enable state during boot, before Linux applies the overlay. Check that the added load does not interfere with bootloader use of the pin.
Confirm the electrical polarity at the transceiver input. The application must select active-high or active-low behavior to match that input; changing the polarity flags cannot correct a pin still owned by I2C2. The check passes when the inactive boot state keeps the line driver disabled.
Which function owns P9.19 and P9.20?
An overlay and config-pin are mutually exclusive ownership methods for a pin. Once an overlay has successfully claimed P9.19, do not use config-pin to query or change it. Conversely, if config-pin -q P9.19 still reports a configurable default mode, treat that as evidence that the overlay did not claim the pin.
Reports such as the following show that the path stops at pin multiplexing:
P9.20 ... i2c 2 sda ... (pinmux_P9_20_default_pin)
P9.19 ... i2c 2 scl ... (pinmux_P9_19_default_pin)
The UART1 overlay must disable the existing pinmux helper nodes before its own pin group can claim those pads. Use quoted device-tree status strings:
P9_24_pinmux { status = "disabled"; }; /* uart1_txd */
P9_26_pinmux { status = "disabled"; }; /* uart1_rxd */
P9_19_pinmux { status = "disabled"; }; /* uart1_rtsn */
P9_20_pinmux { status = "disabled"; }; /* uart1_ctsn */
An unquoted status = disabled; entry produces a device-tree syntax error; the observed build stopped at src/arm/BB-UART1-00A0.dts:41.28-29. The check passes when the overlay compiles with status = "disabled";.
How is the UART1 overlay built and activated?
Adding RTS to BB-UART1-00A0.dts, compiling it, and installing it does not activate it for the next boot. The bootloader must also be told to load the resulting overlay.
- Edit the overlay pin group so TXD, RXD, RTS, and optional CTS use their UART1 functions:
bb_uart1_pins: pinmux_bb_uart1_pins { pinctrl-single,pins = < BONE_P9_24 (PIN_OUTPUT | MUX_MODE0) /* uart1_txd */ BONE_P9_26 (PIN_INPUT | MUX_MODE0) /* uart1_rxd */ BONE_P9_19 (PIN_OUTPUT | MUX_MODE0) /* uart1_rtsn */ BONE_P9_20 (PIN_INPUT | MUX_MODE0) /* uart1_ctsn */ >; }; - Disable the corresponding pinmux helpers, including
P9_19_pinmuxandP9_20_pinmuxwhen both pins are included. - Bind the pin group to UART1 with
pinctrl-names = "default";andpinctrl-0 = <&bb_uart1_pins>;, and set UART1 status to"okay". - Run
makeandsudo make install. - Configure the installed overlay path in one unused
uboot_overlay_addr4throughuboot_overlay_addr7entry in/boot/uEnv.txt. - Reboot so the bootloader loads the overlay and the kernel applies its pin group.
Do not edit 8250_omap.yaml as a runtime configuration step. A YAML binding describes valid device-tree properties; it does not load the overlay or enable RS-485 mode for an open serial port. The activation check is the boot-time pin assignment, not a successful build alone.
Does the kernel own the requested UART pins?
Use /opt/scripts/device/bone/show-pins.pl after reboot. Do not use config-pin as the acceptance test for overlay-owned pins. A working assignment identifies UART1, its controller, and the overlay pin group:
P9.20 ... uart 1 cts serial@48022000 (pinmux_bb_uart1_pins)
P9.19 ... uart 1 rts serial@48022000 (pinmux_bb_uart1_pins)
P9.26 ... uart 1 rxd serial@48022000 (pinmux_bb_uart1_pins)
P9.24 ... uart 1 txd serial@48022000 (pinmux_bb_uart1_pins)
| Observed result | Cause | Next action |
|---|---|---|
P9.19 still shows I2C2 SCL |
Overlay was not loaded or failed to claim the helper-owned pin | Check /boot/uEnv.txt, the selected overlay address entry, and the disabled helper node |
P9.19 shows UART1 RTS |
Overlay owns the pad in mode 0 | Proceed to serial-port RS-485 configuration |
| TXD and RXD show UART1, but RTS shows I2C2 | The base UART overlay lacks the added RTS pin definitions or helper release | Recheck P9_19_pinmux and BONE_P9_19
|
config-pin can still reconfigure the pin |
The overlay did not successfully establish exclusive ownership | Return to boot overlay activation |
RS-485 direction control does not use CTS. Configure P9.20 only when UART1 CTS is needed for another operating mode, such as RTS/CTS flow control for RS-232. The check passes when show-pins.pl reports P9.19 as UART1 RTS.
How does the application enable automatic direction control?
Pinmux establishes the physical route, but it does not turn on Linux RS-485 behavior for the open port. Configure the serial file descriptor with TIOCGRS485 and TIOCSRS485. Read the current structure first so unrelated driver-provided fields are preserved.
#include <sys/ioctl.h>
#include <linux/serial.h>
int uart_get_rs485_config(int fd, struct serial_rs485 *config)
{
return ioctl(fd, TIOCGRS485, config);
}
int uart_set_rs485_config(int fd,
const struct serial_rs485 *config)
{
return ioctl(fd, TIOCSRS485, config);
}
int uart_enable_rs485(int fd, bool active_low)
{
struct serial_rs485 config;
int result = uart_get_rs485_config(fd, &config);
if (result < 0)
return result;
if (active_low) {
config.flags &= ~SER_RS485_RTS_ON_SEND;
config.flags |= SER_RS485_RTS_AFTER_SEND;
} else {
config.flags |= SER_RS485_RTS_ON_SEND;
config.flags &= ~SER_RS485_RTS_AFTER_SEND;
}
config.flags |= SER_RS485_ENABLED;
return uart_set_rs485_config(fd, &config);
}
Select active_low from the transceiver enable-input polarity. After setting the structure, call TIOCGRS485 again and verify that SER_RS485_ENABLED and the intended RTS-state flags read back.
| Direction method | Release trigger | Timing characteristic |
|---|---|---|
Kernel RS-485 mode with zero delay_rts_after_send
|
UART transmit-complete interrupt after the FIFO and serializer are empty | Release follows actual hardware completion |
Kernel RS-485 mode with nonzero delay_rts_after_send
|
High-resolution timer scheduled from the UART interrupt handler | Release occurs after the configured post-send delay |
| Application-controlled RTS using transmitted-data echo | Application receives its final transmitted byte | The tested loop released RTS within 1–3 milliseconds at 9600 and 19.2 kbps
|
Ordinary manual modem control remains useful for a diagnostic. TIOCMBIS and TIOCMBIC can prove that the UART-owned RTS route reaches P9.19. Use kernel RS-485 mode for production direction control because its completion interrupt observes the FIFO and serializer rather than merely the application write completing.
What proves the complete RS-485 path?
- Run
show-pins.pland confirmP9.24,P9.26, andP9.19belong to UART1 underpinmux_bb_uart1_pins. - Read the port configuration with
TIOCGRS485and confirmSER_RS485_ENABLEDplus the intended RTS polarity flags. - Probe UART1 TXD and
P9.19together. RTS must enter the transmit-enable state before data leaves TXD. - Observe the last transmitted character. With no post-send delay, RTS must leave the transmit-enable state only after the FIFO and serializer complete. With
delay_rts_after_sendconfigured, verify the added interval against that configured value. - Probe the transceiver enable input. If
P9.19switches but the input does not, inspect wiring, loading, and polarity between the header and transceiver. - Send a frame to another RS-485 node and verify correct reception without truncating the final character or holding the bus driven after completion.
FAQ
Can UART1 automatically control RS-485 Tx-enable?
Yes. Mux P9.19 to UART1 RTS with MUX_MODE0, load the overlay at boot, and enable SER_RS485_ENABLED through TIOCSRS485.
Does P9.19 use mode 0 or mode 7 for automatic RTS?
Use MUX_MODE0 for uart1_rtsn. MUX_MODE7 makes the pad a GPIO and removes it from automatic UART direction control.
Can config-pin verify that the UART1 overlay owns P9.19?
No. Use /opt/scripts/device/bone/show-pins.pl; successful ownership appears as UART1 RTS under pinmux_bb_uart1_pins.
Does RS-485 require UART1 CTS on P9.20?
No. CTS is not part of RS-485 direction control. After enabling kernel RS-485 mode, make the final verification by probing TXD, P9.19, and the transceiver enable input through the last transmitted character.