pico-serial Line — phone-line modem stick (draft 0.1)¶
A USB modem for a real telephone line, in the shape of Apple's USB Modem: a stick about as long as a disposable lighter, with an RJ11 socket at one end and a USB-C receptacle at the other (Apple's had a captive USB-A cable).
It is a softmodem: the stick is the telephone-line interface (a DAA and its codec) with an RP2040 between it and USB. The modem itself, every modulation from V.21 to V.90, fax and voice, is D-Modem's open DSP running on whatever the stick is plugged into:
- Linux:
dmodemddrives it through libusb, as it drives Smart Link's SmartUSB56 today (§6). The modem appears as a pty. - Windows:
dmodemddrives it through libusb on WinUSB, which Windows binds by itself (Microsoft OS 2.0 descriptors: no INF). - Android: the D-Modem app gets a real telephone line beside SIP (§6.2).
So the stick has no modem firmware of its own to go out of date, and everything that makes the connection is open, from the line interface up.
Everything in SPEC.md about the RP2040 core (power, USB-C, flash, crystal, buttons, UF2 updates) still applies. There is no RS-232 side.
1. Requirements¶
| # | Requirement |
|---|---|
| L1 | USB-C device port, USB 2.0 Full Speed, powered from VBUS only, under 100 mA |
| L2 | One RJ11 socket (6P2C or 6P4C, the middle pair: TIP and RING), loop start lines |
| L3 | V.90 as the analogue modem: the line sampled at 9600 Hz (D-Modem's V.90 needs it, hardware.md "Modulations"); 8000 and 16000 Hz too |
| L4 | Hook control fast enough for pulse dialling (D-Modem times the pulses) and hook flash |
| L5 | Ring detection and caller ID (the line heard while on hook) |
| L6 | Isolation from the line: ≥ 1500 Vrms, the DAA's capacitive barrier; line surge protection and a telecom fuse |
| L7 | Driverless on Linux, Android and Windows: a vendor-class USB interface for libusb (no kernel driver; WinUSB by Microsoft OS 2.0 descriptors) |
| L8 | Firmware update over the same USB-C cable (UF2) |
| L9 | A stick about 82 mm long (a disposable lighter), RJ11 at one end, USB-C at the other |
| L10 | Every part normally stocked and buyable at qty 1 |
2. Block diagram¶
USB-C ── ESD ── RP2040 ──────── MCLK 48 MHz (GPOUT0) ──► Si3056 ═╪═ Si3018/19 ── bridge ── fuse ── RJ11
(UFP) │ PIO ◄─ SCLK, FSYNC, SDO ─┤ (system ║ (line hook
LDO 3.3 V │ PIO ── SDI ─────────────►│ side) C1,C2 side) switch,
flash, xtal │ GPIO ── OFHK, RESET, FC ►│ Y2 caps ring, CID
│ GPIO ◄─ RGDT, INT ───────┤ ║
└── LEDs (OH, RI) isolation barrier
3. The line interface: Si3056 + Si3018/19¶
Skyworks' (formerly Silicon Labs') Si3056 "Global Serial Interface
DAA" is the part made for softmodems: a codec with a serial port for a
modem DSP, at any sample rate from 7.2 to 16 kHz (Fs = FPLL2 / 5120).
Its line-side partner (Si3018 or Si3019) holds the hook switch, the DC and
AC termination, the ring detector and the caller-ID path, programmable for
every country's line (impedance, current limit, ring thresholds). The two
talk across two high-voltage capacitors: that is the isolation barrier.
Why not the alternatives: - Si3050 (Skyworks' voice DAA, same line side): its PCM highway runs at 8 kHz only. D-Modem's V.90 needs 9600 Hz (at 8000 Hz on a clock of its own it loses the PCM signal every few seconds). - Si2494/Si3018 ISOmodem: a complete modem chip; it would make the stick plug-and-play but closed, with no path for D-Modem. - A transformer DAA + codec: more parts, a relay or opto hook switch, and every country's termination done by hand.
3.1 Circuit¶
The datasheet's typical application (Si3056 datasheet rev 1.03, Figure 17, and its bill of materials), unchanged in topology:
| Ref (datasheet) | Value | Job |
|---|---|---|
| C1, C2 | 33 pF, Y2 | the isolation barrier (C1A/C1B, C2A/C2B) |
| C8, C9 | 680 pF, Y2 | TIP and RING to the system ground, EMI (across the barrier) |
| C3 | 10 nF, 250 V | line-side AC path |
| C4 | 1 µF, 50 V | RX/DCT filter |
| C5, C6, C50, C51 | 100 nF | VREG, VREG2, VD, VA |
| C7 | 2.7 nF, 50 V | |
| C10 | 10 nF | |
| D1, D2 | dual diodes, 300 V (or a bridge) | the line's polarity |
| FB1, FB2 | 600 Ω @ 100 MHz, ≥ 200 mA | EMI, on the protected side of RV1 |
| R15, R16 | 0 Ω (or ferrites) | |
| F (added) | 1.25 A telecom fuse in TIP | UL60950 overcurrent (datasheet appendix, Figure 37) |
| Q1, Q3 | MMBTA42 | hook switch, DC termination |
| Q2 | MMBTA92 | |
| Q4, Q5 | MMBT2484 (or MMBTA06) | |
| RV1 | sidactor, 275 V, 100 A | surge |
| R1 | 1.07 kΩ ½ W | R3: 3.65 kΩ ½ W; R4: 2.49 kΩ ½ W; R11: 73.2 Ω ½ W; R10: 536 Ω ¼ W |
| R2, R5, R6, R9 | 150 Ω, 100 kΩ, 100 kΩ, 1 MΩ | |
| R7, R8 | 20 MΩ | caller ID (the line heard on hook) |
| R12, R13 | 56.2 Ω | in series with C1, C2 |
| R51–R53 | 4.7 kΩ | pull-ups: RGDT, OFHK, INT |
| Z1 | 43 V zener |
The part numbers are in the netlist script (LINE_PARTS in
hardware/netlist/build_netlist.py; --variant line) and its BOM
(bom-jlc-line.csv), each checked against JLCPCB's stock on 2026-10-22.
The line side is the Si3018-F-FS (active; the Si3019 has the same pins
and a few more line-level options, at $2.60 more). Neither Skyworks chip is
stocked at LCSC: they come from DigiKey, and are fitted by hand or sent to
JLC as consigned parts, as is the through-hole RJ11.
3.2 Connections to the RP2040¶
| Si3056 pin | RP2040 | |
|---|---|---|
| 1 MCLK | GPIO21 (GPOUT0) | 48 MHz: the USB PLL, divider 1. PLL1: N = 125, M = 256 gives 98.304 MHz; FUP1 = 384 kHz ≥ 144 kHz (§5.25) |
| 2 FSYNC (out) | PIO | frame start, one per sample |
| 3 SCLK (out) | PIO | 256 × Fs: 2.4576 MHz at 9600 Hz |
| 5 SDO (out) | PIO | 16-bit samples, then control words in secondary frames |
| 6 SDI (in) | PIO | |
| 7 FC | GPIO | requests a secondary frame (16-bit TX mode, SB = 1) |
| 8 RESET | GPIO | |
| 11 AOUT/INT | GPIO | the Si3056's interrupt (programmed as INT), pulled up |
| 14 M0 | GPIO | serial mode, read at reset |
| 15 RGDT/M1 | GPIO | M1 = 0 driven through reset (master mode), then the ring detector (active low, pulled up) |
| 16 OFHK | GPIO | the hook: low = off hook, pulled up so the line stays free until the firmware runs |
The RP2040 is the serial port's slave: the Si3056 makes SCLK and FSYNC from MCLK, so the sample clock is the board's crystal through the USB PLL, and the USB side follows it (§5).
3.3 Layout rules (Skyworks AN67)¶
- No ground plane under the line side; the line-side parts close together, inside the barrier.
- The barrier: C1, C2, C8, C9 bridge it; nothing else does. Creepage and clearance across it at least 2.5 mm on every layer (UL60950 basic insulation for a telecom network at 250 V), wider where the board allows.
- RV1, the fuse and the ferrites right at the RJ11; TIP and RING short and wide.
4. Rest of the board¶
The RP2040 core of SPEC.md §4.2 (the chip, W25Q flash, 12 MHz crystal, AP2112K-3.3, USBLC6 ESD, the USB-C with its CC resistors, a polyfuse), plus: - two LEDs: OH (off hook) and RI (ringing); - the BOOTSEL and RESET buttons (inside; the stick also reboots to its UF2 loader on a vendor request); - test pads for SWD, 3.3 V and the serial port.
The RS-232 chips, the DB25 and their GPIOs are not fitted: the netlist
script's line variant leaves them out.
5. USB interface (firmware)¶
One vendor-class interface (class 0xFF), USB 2.0 Full Speed, VID
0x1209 (pid.codes) with a test PID until a real one is assigned. It is
shaped like the SmartUSB56's, so D-Modem's driver for that is the model
for this one:
| Endpoint | Type | |
|---|---|---|
| EP1 IN | isochronous, 1 ms | the line's samples: S16 little-endian, mono, at Fs. Each packet carries the samples the codec gave in that millisecond (9 or 10 at 9600 Hz): the host's clock is the stick's |
| EP1 OUT | isochronous, 1 ms | the modem's samples, the same format; the stick plays them at its codec's clock, a small buffer absorbing USB's timing |
| EP2 IN | interrupt, 8 ms | events: ring detector changes, line voltage/current alerts, overload, a polarity reversal, buffer underrun/overrun |
Vendor control requests (EP0): the stick's info and version; the sample
rate; the hook (off, on, a timed flash or pulse); the line monitor (on
hook, for caller ID); a Si3056/Si3018 register read and write (the host
sets the country's line from D-Modem's table); reset; reboot to UF2. The
exact numbers go in firmware/PROTOCOL.md with the firmware.
Samples run both ways from the moment the host starts them, on hook too, so ring and caller-ID detection can run on the samples as they do on ALSA codecs.
6. Host software¶
6.1 D-Modem (Linux)¶
A second device kind beside the SmartUSB56 in frontend/dmodemd/usb_line.cpp:
dmodemd --usb=auto finds either. The differences from the ST7554:
- samples at 9600 Hz by default (V.90);
- the hook and the line monitor by vendor request, not GPIO registers;
- caller ID (the ST7554's codec hears nothing on hook; this one does);
- the country's line settings written to the line side's registers.
6.2 The D-Modem app (Android)¶
The app gets the stick through Android's USB host API (a UsbDeviceConnection's
descriptor handed to libusb), so the same line code runs on the phone:
the modem on a real telephone line, beside SIP and the line to another
phone.
7. Mechanical¶
- Length about 82 mm, the length of a disposable lighter (a BIC classic is 81 mm), with a cross-section set by the RJ11 socket.
- RJ11 at one end, its latch toward the top; USB-C at the other.
- A 3D-printed shell in two halves (as the W hood: MJF PA12), the board held between them. Light pipes or thin windows for the two LEDs.
hardware/enclosure/stick.pymakes the shell, the board outline and the placement file, and checks the fit.
8. Compliance (only if you sell it)¶
- Connecting equipment to the telephone network is regulated: in the US, FCC Part 68 / TIA-968 registration (the ACTA database) and a ringer equivalence number; in Europe the radio and low-voltage rules with EN 62368-1 and the telecom network interface standards; elsewhere each country's own. The Si3056 is designed to meet them all ("globally compliant"), but the product still needs testing.
- Safety: UL/EN 62368-1 (formerly 60950) for the barrier and the overvoltage tests; the datasheet's appendix lists what passes.
- None of this applies to building your own, but use it on your own line and at your own risk.
9. Open questions¶
- The Si3056 is "not for new designs" at Skyworks (October 2026: DigiKey about 1,400 Si3056-D-FS and 2,600 on reel; Si3056-FS obsolete). Fine for building these; for a long run, buy ahead. The fallback is the Si3050 (active, same line side), at 8 kHz only: V.34 and below, no V.90.
- The RJ11 (Ckmtw R-RJ11R06P-A800, LCSC C189750) is 13 mm tall, so the stick is about 18-19 mm thick, against a lighter's 15. A mid-mount jack would save 3-4 mm.
- Whether to run the samples isochronous (as the SmartUSB56) or bulk: isochronous keeps D-Modem's driver as it is; bulk is simpler on Android without libusb.
10. Next steps¶
- Netlist and schematic (
--variant line). - The shell (
stick.py), then the PCB. - Firmware: the Si3056's serial port in PIO, the USB interface.
- D-Modem's driver, against a fake device first (as
fake_st7554).