Files
MiPi_Investigation/CLAUDE.md
david rice 0edb95d7e1 Updates
2026-05-06 15:57:48 +01:00

4.7 KiB
Raw Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project status

Greenfield. The repository currently contains only README.md and MIPI_FLICKER_SPEC.md — no Python source, no requirements.txt, no tests. All implementation work is driven from the spec. Read MIPI_FLICKER_SPEC.md before making any non-trivial change; it is the source of truth for module boundaries, REST endpoints, register layouts, and timing thresholds.

When the user asks to "build" or "implement" something, follow the layout in MIPI_FLICKER_SPEC.md §3 rather than inventing a new structure.

Purpose

A two-host test harness that hunts for a MIPI D-PHY flicker/blackout fault on a custom PCB driven by an i.MX 8M Mini → TI SN65DSI83 (DSI→LVDS) bridge. The fault is hypothesised to be timing-violation rounding in the mainline samsung-dsim driver that drops several D-PHY parameters below MIPI v1.1 minimums.

The harness loops: power-cycle the display rail, arm the scope, restart video, capture 4-channel waveforms + bridge/SoC registers, decode timings + DSI Lane 0 packets, log a verdict.

Architecture (from spec §2, §3)

Three top-level concerns; keep them in separate packages:

  • hardware/ — instrument I/O only. scope.py (DSO80204B over VXI-11), psu.py (Siglent SPD3303X-E over VXI-11), target.py (HTTP REST client to the i.MX). Each is a thin controller class; no analysis logic.
  • analysis/ — pure functions over captured data. waveform.py extracts D-PHY timings and decodes Lane 0 DSI packets from CSVs; registers.py parses SN65 + DSIM register dumps; report.py writes per-run artefacts.
  • server/app.py — Flask REST server that runs on the i.MX target, not the host PC. It shells out to memtool, i2cget, and /sys/kernel/debug/regmap/... and exposes /registers, /sn65_registers, /sn65_settling, /display, /video. The host-side hardware/target.py is just a requests wrapper around it.
  • master_loop.py — orchestrator only. Reset → arm scope → stimulate → wait for trigger → capture → analyse → save. See spec §9.

config.py centralises all IPs, register addresses, MIPI spec minimums, and probe attenuation. Treat it as the single tuning surface.

Non-obvious invariants

These will silently break the experiment if violated:

  1. Cache-bypass before every SN65 read. The server must echo 1 > /sys/kernel/debug/regmap/4-002c/cache_bypass before reading IRQ_STAT (0xE5), every time. Without it, reads return the last-written cached value, not hardware state — flicker events become invisible. Spec §7.2, §15.4. (Note: spec §7/§11 says bus 2; live hardware on this board has the bridge on bus 4 — i2cdetect confirms UU at 0x2c on bus 4 only. Code uses bus 4.)
  2. Scope channels are 50 Ω DC, not 1 MΩ. The 910R+50R probe divider only gives the documented 19.2× attenuation with 50 Ω termination. Any code that configures the scope must set :CHANnel<N>:INPut DC50 explicitly. Spec §15.12.
  3. Probe attenuation 19.2× is baked into thresholds. All voltage thresholds in analysis/waveform.py are post-attenuation values (e.g. LP-high > 40 mV ≈ 770 mV on wire). Don't "correct" them back to wire voltages.
  4. UI depends on pixel clock. UI_NS = 1e9 / DSI_CLK_HZ and several spec minimums are f(UI). If --pixel-clock is overridden at runtime, recompute DPHY_SPEC rather than using stale module-level constants. Spec §15.5.
  5. DSIM PHY_TIMING bit-field layout is undocumented in the i.MX 8M Mini reference manual. The parser must log raw hex and decoded cycle counts so they can be cross-checked against kernel dmesg. Don't assume the layout in spec §10 is correct without dmesg verification. Spec §15.6.
  6. Packet-level decode is the ground truth, not the SN65 error registers. A flicker can be confirmed only by decoding Lane 0 bytes (Fault A: first long packet payload is all 0x00; Fault B: lane stalls in LP-11 for ~20 ms). The SN65 IRQ_STAT bits are a hint, not a verdict. Spec §1 (Falcon prior art), §13.

Network topology

Host PC talks to three fixed IPs on the bench LAN — these are wired into config.py and the spec, not discovered:

  • 192.168.45.3 — Siglent PSU (VXI-11)
  • 192.168.45.4 — Keysight DSO80204B scope (VXI-11)
  • 192.168.45.8:5000 — i.MX target Flask server (HTTP)

Commands

No build/test/lint commands exist yet — the project hasn't been scaffolded. Spec §4 lists the dependency set (python-vxi11, requests, flask, numpy, pandas, matplotlib) when a requirements.txt is created. Spec §9.3 lists the eventual master_loop.py CLI surface (--max-runs, --timeout, --pixel-clock, --note, --no-video, --output-dir).