5b2ae25071
Idle on battery, the tablet suspends ~60 s after screen-off and only answers at its DHCP-renewal wakeups while the USB link stays up. Kept awake with a video, a PD unplug costs 3.1 s and then nothing. The earlier replug silences were the tablet waking from sleep. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
132 lines
8.1 KiB
Markdown
132 lines
8.1 KiB
Markdown
---
|
||
type: report
|
||
date: 2026-10-09
|
||
---
|
||
# USB Link to the Tablet (Orin as USB Network Gadget)
|
||
|
||
## Result
|
||
|
||
| Item | State |
|
||
|------|-------|
|
||
| Physical | USB-C ↔ USB-C, tablet (Redmi Pad SE 8.7 4G, Android 16) = **USB host**, Orin's USB-C port = **USB device** |
|
||
| Network | Orin `192.168.55.1` on `l4tbr0`, tablet gets `192.168.55.100` from the Orin's DHCP. Ping ~2.5 ms |
|
||
| Function used | **NCM** (`usb1`, ECM/NCM MAC). RNDIS (`usb0`) is offered but the tablet ignores it |
|
||
| Mass storage (`L4T-README`) | **Disabled** (`enable_ums=0`) |
|
||
| Tablet charging over this cable | **Not possible** (see below) |
|
||
|
||
## How it works (stock L4T, no install needed)
|
||
|
||
`nv-l4t-usb-device-mode.service` (package `nvidia-l4t-init`) builds a composite USB gadget on the USB-C port at boot.
|
||
It has RNDIS + NCM network functions bridged into `l4tbr0`, an ACM serial console, and (stock) a mass-storage drive.
|
||
When a host connects, a dedicated `dhcpd` hands out exactly one address. Settings live in
|
||
`/opt/nvidia/l4t-usb-device-mode/nv-l4t-usb-device-mode-config.sh`:
|
||
|
||
```
|
||
net_ip=192.168.55.1 net_dhcp_start=192.168.55.100 net_dhcp_end=192.168.55.100
|
||
net_ipv4_defroute_router=192.168.55.100 net_ipv4_defroute_metric=32766
|
||
```
|
||
|
||
The Orin also adds `default via 192.168.55.100 metric 32766`. This ranks below everything else, so it never takes traffic from Ethernet, WiFi or LTE.
|
||
|
||
## Android routes apps over it only when it is the default network
|
||
|
||
The tablet joins the USB network, but Android only sends ordinary app traffic over its *default* network, and an Ethernet network without
|
||
validated internet doesn't become default while WiFi or cellular is up. Tested: `http://192.168.55.1:5000` (camera-webui)
|
||
didn't load until the tablet's WiFi and cellular were off; then it did.
|
||
|
||
Consequence for the tablet app: request the Ethernet network explicitly
|
||
(`ConnectivityManager.requestNetwork` with `TRANSPORT_ETHERNET`) and bind its sockets to it. Then the link works no matter what the tablet's
|
||
internet is doing. The other option is NAT on the Orin so Android's check passes, but that would route the tablet's internet through
|
||
the Orin (and in the car, through the metered povo SIM). Not chosen.
|
||
|
||
## Mass storage disabled
|
||
|
||
`L4T-README` is NVIDIA's flashing-help drive and just causes prompts on the tablet.
|
||
|
||
```
|
||
D=/opt/nvidia/l4t-usb-device-mode
|
||
sudo cp -n $D/nv-l4t-usb-device-mode-config.sh $D/nv-l4t-usb-device-mode-config.sh.orig
|
||
sudo sed -i 's/^enable_ums=1$/enable_ums=0/' $D/nv-l4t-usb-device-mode-config.sh
|
||
sudo systemctl restart nv-l4t-usb-device-mode # link drops for a few seconds
|
||
ls /sys/kernel/config/usb_gadget/l4t/configs/*/ # acm.GS0, ncm.usb0, rndis.usb0. No mass_storage
|
||
```
|
||
|
||
⚠ The file is **not** a dpkg conffile, so an `nvidia-l4t-init` upgrade silently restores `enable_ums=1`. The only effect is that the drive
|
||
comes back. After a JetPack/L4T upgrade, check `grep ^enable_ums $D/nv-l4t-usb-device-mode-config.sh` and re-apply.
|
||
(`dpkg-divert` was rejected: it would also hide upstream changes to the file's format, which fails worse than a returning drive.)
|
||
|
||
RNDIS is left enabled. It's unused but harmless; `enable_rndis=0` would remove it the same way.
|
||
|
||
## Charging the tablet
|
||
|
||
With one port on the tablet, the data cable to the Orin is also its only charging path, and the Orin doesn't charge it.
|
||
|
||
**The Orin can't be the charger on this port, whatever the network protocol.** RNDIS vs NCM is irrelevant; power is separate from data:
|
||
|
||
- In USB-C, *data* role (host/device) and *power* role (source/sink) are negotiated separately. "Tablet is host but gets charged" is normal,
|
||
but it needs a power source that negotiates USB Power Delivery.
|
||
- The Orin's USB-C port controller is a **FUSB301**. It only detects attachment and orientation, has no PD, and is wired as the flashing/device port.
|
||
The kernel registers no USB-C port or PD device (`/sys/class/typec` is empty, there is no `usb_power_delivery` class).
|
||
So the port can't offer charging power to the tablet.
|
||
|
||
Options:
|
||
|
||
| Option | Charging | Notes |
|
||
|--------|----------|-------|
|
||
| **PD hub with one data port** (on hand) | Full PD from the car charger, through to the tablet | Tablet → hub's USB-C host/PD port, charger → hub's PD-in, Orin USB-C → hub's data port. Same gadget/NCM setup, nothing changes on the Orin. Some hubs briefly re-enumerate when PD power appears or disappears (ignition), so the app should reconnect |
|
||
| Reverse roles: Orin USB-A host + tablet USB tethering | ~4.5 W at most (5 V, USB-A) | Tablet becomes the router, tethering has to be enabled by hand on Android, and it needs `never-default` on the Orin so the Orin's traffic doesn't leave via the tablet |
|
||
|
||
The **PD hub** is the practical choice, and it's now in use.
|
||
|
||
### PD power cycling through the hub (tested 2026-10-09)
|
||
|
||
Setup: tablet → hub (USB-C host/PD), car-style charger → hub PD-in, Orin USB-C → hub data port.
|
||
Three PD unplug/replug cycles while pinging the tablet every 0.5 s:
|
||
|
||
| Cycle | USB-C detach (Orin) | Link stable again | Ping lost |
|
||
|-------|---------------------|-------------------|-----------|
|
||
| 1 | 00:14:29.3 | 00:14:36.1 | 3.1 s + 1.5 s |
|
||
| 2 | 00:14:38.5 | 00:14:43.6 | 3.1 s + 1.5 s |
|
||
| 3 | 00:14:51.4 | 00:15:02.0 | 11.8 s |
|
||
|
||
- **Each cycle caused exactly one full detach** (`fusb301_detach`), not one per transition. The separate-edge test below shows
|
||
it is the unplug.
|
||
- Each detach follows the same pattern: re-attach after about 0.5 s, then the `l4tbr0` bridge ports flap about three times over 5–10 s
|
||
(the tablet re-creating its USB network) before settling.
|
||
- Recovery is automatic every time: the same DHCP lease, normal ping (~3 ms) afterwards. Nothing needs fixing on the Orin.
|
||
|
||
#### Each edge separately (same day, one 60 s window each)
|
||
|
||
| | PD unplugged (00:23:04) | PD plugged back (~00:24:12) |
|
||
|---|---|---|
|
||
| USB-C detach on the Orin | **yes**, full detach and re-attach | **no** |
|
||
| Orin link (`l4tbr0` ports) | flapped twice, stable after 3.4 s | stayed up; one short gadget reconnect at 00:24:21.6 (0.7 s) |
|
||
| Ping lost | 3.1 s | 5.0 s while the Orin's link was **up**, then 0.3 s and 1.5 s |
|
||
| Total disruption | ~3.5 s | ~10 s |
|
||
|
||
- Unplug: the hub cuts its data port, so the Orin sees a real disconnect, and recovery is quick.
|
||
- Replug: no disconnect on the Orin's side. The tablet stops answering for about 5 s (most likely renegotiating power and switching to
|
||
charging), then re-creates its USB network once. **The Orin's interface state does not reveal this outage**, so only an
|
||
application-level heartbeat catches it.
|
||
- Exact replug time isn't known; the first failed ping is used as its marker.
|
||
- Repeat (plug-in at ~00:27:12): the tablet was silent for 7.8 s with the Orin's link up, then one gadget reconnect (00:27:25.1–27.0)
|
||
and a fresh `DHCPDISCOVER`; about **15 s** to stable. Replug consistently costs more than unplug (3.5 s).
|
||
#### The "silence" is Android sleeping, not the link
|
||
|
||
| Test (2026-10-09) | Tablet state after PD unplug | Result |
|
||
|---|---|---|
|
||
| Idle, 3 min window | screen times out | Clean for ~60 s, then pings answered only in brief bursts right at its 30 s DHCP renewals, then silent. **No kernel link events**: USB stayed up throughout |
|
||
| Video playing, 150 s window | kept awake | 3.1 s outage at the unplug, then **zero loss for 2 min+** |
|
||
|
||
- Off charger and idle, Android suspends about 60 s after the screen times out ("keep awake on charge" no longer applies). The USB gadget link
|
||
stays electrically up, but the tablet only wakes for timers (DHCP renewal every ~30 s).
|
||
- The earlier "replug silence" was the same thing. Those windows started with the tablet already asleep, so plugging power in woke it, and the
|
||
5–8 s was wake-up plus re-creating its USB network.
|
||
- So the hub's PD change costs **~3.5 s** (the unplug detach). Everything beyond that came from tablet sleep.
|
||
- To the Orin, a sleeping tablet is indistinguishable from a dead link, except by heartbeat.
|
||
|
||
- At ignition, accessory power drops during cranking, so a start is likely to produce both edges back to back (not tested in the car yet).
|
||
|
||
Consequence: in the car, expect a link outage of up to about 12 s at every ignition change. That is a requirement for the services
|
||
(failure detection and redelivery; project-yukart ARCHITECTURE decision 24), not something to fix in the host setup.
|