Skip to content

h4rm0n1c/EBD_IPKVM

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

200 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EBD_IPKVM - Everything But Disks, IP KVM

DEMO

Work-in-progress “IP KVM” for a Macintosh Classic using an RP2040 (Pico W): Tap raw 1-bpp video + sync, capture with PIO+DMA, and stream to a host UI.

Above output is current project output as of PR #19.

Highlights

  • RP2040 PIO captures 512 pixels per line (1 bpp) on PIXCLK edges.
  • Lines are queued and streamed over the USB vendor bulk interface with a compact per-line header (optional RLE).
  • Host test helper (src/host_recv_frames.py) reconstructs frames into PGM images (default).

Signal/pin map (current firmware)

  • GPIO0 — PIXCLK (input, PIO)
  • GPIO1 — VSYNC (input, SIO GPIO, active-low, IRQ on falling edge)
  • GPIO2 — HSYNC (input, PIO, active-low)
  • GPIO3 — VIDEO (input, PIO, 1 bpp data)
  • GPIO6, GPIO12 — Reserved for future SPI to external ADB controller
  • GPIO9 — ATX PS_ON (output via ULN2803, GPIO high asserts PSU on)

⚠️ Upstream signals may be 5V TTL; ensure proper level shifting before the Pico.

Capture geometry

  • Active video: 512×342 (1 bpp)
  • Horizontal offset: 175 PIXCLK cycles after the selected HSYNC edge (PIO skip + 18-cycle delay after phase-lock)
  • Vertical offset: 28 HSYNCs after VSYNC fall
  • Capture window: 370 HSYNCs total (28 VBL + 342 active)
  • Line capture begins on the selected HSYNC edge.

USB interfaces

The firmware exposes one vendor bulk interface for video plus one CDC ACM function for control/debug:

  • BULK0 (vendor): binary line packets (video data).
  • CDC ACM (control/debug): ASCII commands + status text.

Note: a single CDC ACM function appears as two USB interfaces in lsusb -t (Communication + Data). That is normal and still maps to one /dev/ttyACM* control/debug port.

See docs/protocol/usb_cdc_stream.md for details on interfaces and commands.

Stream packet format (BULK0)

Each line is emitted as a packet with a compact header:

0..1   magic       0xEB 0xD1
2..3   frame_id    little-endian
4..5   line_id     little-endian (0..341)
6..7   payload_len little-endian (bit 15 indicates RLE)
8..N   line payload (64 bytes raw, or up to 128 bytes RLE)

RLE payloads expand to 64 bytes on the host; firmware may still emit raw lines if RLE does not compress.

Host capture helper

python3 src/host_recv_frames.py frames --ctrl-device=/dev/ttyACM0

This test script:

  • Uses USB bulk for video ingest and CDC for debug/control (--ctrl-device= overrides CDC autodetect).
  • Optionally asserts P (power on) before capture; use --no-boot to skip.
  • Sends X to stop any prior run before arming (use --no-stop to skip).
  • Resets counters and arms capture by sending R then S (use --no-reset to skip).
  • Adjust the boot wait with --boot-wait=SECONDS if needed.
  • Use --diag-secs=SECONDS to briefly print ASCII status before arming capture.
  • Reassembles lines into full 512×342 frames.
  • Writes PGM files to frames/ (0/255 grayscale) by default; use --pbm for packed 1-bpp PBM.
  • Optionally emits a continuous 8-bit raw stream with --stream-raw or --stream-raw=/path/to/pipe (runs until you stop it).
  • Firmware defaults to continuous ~60 fps capture; send M to toggle to the ~30 fps test cadence.
  • Edge toggles for testing: send H to flip HSYNC edge, K to flip PIXCLK edge, V to flip VSYNC edge (capture stops/clears when toggled).

Example: stream raw 512×342 8-bit frames to ffplay on stdout:

python3 src/host_recv_frames.py frames --stream-raw \
  | ffplay -f rawvideo -pixel_format gray -video_size 512x342 -framerate 60 -

Repo layout

  • src/ firmware sources (Pico SDK)
    • classic_line.pio: PIO program for per-line capture.
    • main.c: USB bulk video + CDC control firmware.
    • host_recv_frames.py: host-side test program for reassembling frames.
  • docs/
    • PROJECT_STATE.md: living status summary.
    • protocol/: wire format documentation.
    • agent/: running notes + decisions for Codex/agents.
    • PDFs: helper datasheets used during bring-up.

Attribution

This project relies on documentation and reference implementations from the following sources.

Classic Mac video timing + signaling references (docs/)

/opt references

  • /opt/MacDevDocs — Apple developer notes + hardware references used to cross-check classic Mac timing and connector pinouts (see the Apple Developer Documentation Archive).
  • /opt/Pico-SDK — RP2040 PIO/DMA/USB SDK structure and build expectations.
  • /opt/PicoHTTPServer — Pico W HTTP server, captive portal flow, and incremental response patterns for future on-device UI work.
  • /opt/SigrokPico — USB CDC transport patterns and RLE compression ideas for low-entropy line data.
  • /opt/picovga — multi-core video pipeline patterns for RP2040 video workloads.
  • /opt/adb/hootswitch — RP2040 ADB bus implementation (PIO + DMA + state machine) used as the reference for our ADB device emulation plan. Use scripts/setup_opt_references.sh to install the above corpora under /opt if you need local copies.

Build (typical Pico SDK)

Set your Pico SDK path, then build out-of-tree in build/.

About

RP2040/Pico W PIO+DMA capture for Macintosh Classic 1bpp video (future ADB/ATX KVM)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors