UART Mux
The uart_mux component lets one hardware UART be used either by a
CDC-ACM UART Bridge or by other components on the device, switching between the
two at runtime. A typical use is a device with a radio module on its UART: while a computer is connected over USB the
module is exposed to it as a serial port, and when no computer is connected the device’s own firmware talks to the
module instead.
Other components do not use the UART directly. They use the mux as their UART, and the mux forwards their traffic to the hardware UART only while it is routed to them. Components that check whether their UART is connected, such as Z-Wave Proxy, see the route change as the connection going away and coming back, and recover on their own.
The component is available on the ESP32-P4, ESP32-S2 and ESP32-S3, the same variants as the bridge. It requires a CDC-ACM UART Bridge; see that page for setting up the bridge, its UART and its USB CDC-ACM interface.
# Example configuration entryuart_mux: - id: radio_mux bridge_id: radio_bridge
zwave_proxy: uart_id: radio_muxConfiguration variables
Section titled “Configuration variables”- bridge_id (Required, ID): The CDC-ACM UART Bridge whose UART is shared. The mux takes the UART from the bridge, so it is not configured here.
- initial_route (Optional, string): Who gets the UART at boot:
bridgeorlocal. Defaults tobridge. See Following a USB host for when to uselocal. - id (Optional, ID): Manually specify the ID for this component.
NOTE
A bridge refuses to share its UART with any other component, and that still holds with a mux in place: other
components must use the mux as their UART, never the hardware UART itself, and the UART still cannot use the debug
option. Each bridge can have one mux; put every local consumer of that UART on the same mux.
Routing
Section titled “Routing”The mux is in one of two routes:
- bridge: the bridge forwards between the UART and the USB serial port. Components using the mux see a disconnected UART: nothing is available to read, and anything they write is discarded.
- local: the bridge is paused and components using the mux talk to the UART. The bridge restores the UART’s configured baud rate and framing before handing it over, and re-applies the host’s settings when it takes it back.
Switching to the local route takes a moment. The bridge finishes any write that is already in progress, which at low baud rates can be a fraction of a second, and only then is the UART handed over. Anything received on the UART during that hand-over is discarded, so switch while the attached device is idle where possible.
uart_mux.select_local Action
Section titled “uart_mux.select_local Action”Routes the UART to the components using the mux.
on_...: then: - uart_mux.select_local: radio_muxuart_mux.select_bridge Action
Section titled “uart_mux.select_bridge Action”Routes the UART back to the bridge.
on_...: then: - uart_mux.select_bridge: radio_muxuart_mux.is_local Condition
Section titled “uart_mux.is_local Condition”Passes while the UART is routed to the components using the mux and the hand-over has completed.
on_...: then: - if: condition: uart_mux.is_local: radio_mux then: - logger.log: The device owns the UARTFollowing a USB host
Section titled “Following a USB host”The mux does not watch USB itself. Wire it to the TinyUSB on_mount and on_unmount
automations, which run when a computer connects to the device and when it disconnects. Set initial_route: local:
a device that powers up without a computer never sees an on_unmount, so it must start on the local route, and a
computer that is present at boot mounts within a moment and on_mount switches to the bridge.
tinyusb: on_mount: - uart_mux.select_bridge: radio_mux on_unmount: - uart_mux.select_local: radio_mux
uart_mux: - id: radio_mux bridge_id: radio_bridge initial_route: localA device powered only from its USB port does not need on_unmount at all, since unplugging it turns it off. A device
with its own power supply needs vbus_monitor_pin on the tinyusb component for on_unmount to fire; see
Reacting to a USB host for the details.