Files

118 lines
3.8 KiB
Python
Raw Permalink Normal View History

2026-05-06 15:57:48 +01:00
"""Central configuration for the MIPI flicker investigation suite.
All IP addresses, register addresses, MIPI D-PHY spec minimums, and probe
calibration constants live here. This is the single tuning surface modules
should import from here rather than hard-coding values.
"""
# ---------------------------------------------------------------------------
# Network
# ---------------------------------------------------------------------------
TARGET_IP = "192.168.45.8"
TARGET_PORT = 5000
SCOPE_IP = "192.168.45.4"
PSU_IP = "192.168.45.3"
# ---------------------------------------------------------------------------
# Scope hardware
# ---------------------------------------------------------------------------
SCOPE_CHANNELS = {
"CLK_P": 1,
"CLK_N": 2,
"DAT0_P": 3,
"DAT0_N": 4,
}
PROBE_ATTENUATION = 19.2
SCOPE_TIMEBASE = 5e-9
SCOPE_POINTS = 500_000
TRIGGER_CHANNEL = 3
TRIGGER_LEVEL_V = 0.05
TRIGGER_SLOPE = "NEGative"
# ---------------------------------------------------------------------------
# PSU
# ---------------------------------------------------------------------------
PSU_CHANNEL_DISPLAY = 1
PSU_DISPLAY_VOLTAGE = 3.3
PSU_DISPLAY_CURRENT = 1.0
PSU_POWER_CYCLE_DELAY_S = 2.0
# ---------------------------------------------------------------------------
# Pixel clock & DSI parameters
# ---------------------------------------------------------------------------
PIXEL_CLOCK_HZ = 72_000_000
DSI_LANES = 4
BITS_PER_PIXEL = 24
def derive_clocks(pixel_clock_hz: int) -> dict:
"""Recompute DSI/byte clock and UI for a given pixel clock.
Used when --pixel-clock overrides the default UI feeds into several
DPHY_SPEC minimums, so they must be recomputed from the live value.
"""
dsi_clk_hz = pixel_clock_hz * BITS_PER_PIXEL // DSI_LANES
byte_clk_hz = dsi_clk_hz // 8
ui_ns = 1e9 / dsi_clk_hz
return {
"DSI_CLK_HZ": dsi_clk_hz,
"BYTE_CLK_HZ": byte_clk_hz,
"UI_NS": ui_ns,
}
_clocks = derive_clocks(PIXEL_CLOCK_HZ)
DSI_CLK_HZ = _clocks["DSI_CLK_HZ"]
BYTE_CLK_HZ = _clocks["BYTE_CLK_HZ"]
UI_NS = _clocks["UI_NS"]
def build_dphy_spec(ui_ns: float) -> dict:
"""Build the MIPI D-PHY v1.1 minimum-timing dict for a given UI."""
return {
"t_lpx": 50.0,
"t_clk_prepare": 38.0,
"t_clk_zero": 262.0,
"t_clk_prepare_plus_zero": 300.0,
"t_clk_trail": 60.0,
"t_clk_post": 60.0 + 52 * ui_ns,
"t_hs_prepare": 40.0 + 4 * ui_ns,
"t_hs_zero": 145.0 + 10 * ui_ns,
"t_hs_trail": max(8 * ui_ns, 60.0 + 4 * ui_ns),
"t_hs_exit": 100.0,
}
DPHY_SPEC = build_dphy_spec(UI_NS)
# ---------------------------------------------------------------------------
# SN65DSI83 I2C
# ---------------------------------------------------------------------------
SN65_I2C_ADDR = 0x2C
SN65_I2C_BUS = 4 # Spec §11 says 2; live hardware shows the bridge on bus 4
SN65_REG_IRQ = 0xE5
SN65_REG_PLL = 0x0A
SN65_REG_CLK = 0x0B
SN65_ERR_SYNCH = 1 << 3
SN65_ERR_SOT = 1 << 4
SN65_ERR_UNC = 1 << 6
SN65_FLICKER_MASK = SN65_ERR_SYNCH | SN65_ERR_SOT | SN65_ERR_UNC
# ---------------------------------------------------------------------------
# DSIM PHY timing registers (i.MX8M Mini, samsung-dsim)
# ---------------------------------------------------------------------------
DSIM_PHYTIMING_BASE = 0x32E100B4
DSIM_PHYTIMING1 = 0x32E100B8
DSIM_PHYTIMING2 = 0x32E100BC
# ---------------------------------------------------------------------------
# U-boot dsi-tweak bitmask (reference — not written from here)
# ---------------------------------------------------------------------------
TWEAK_BIT_FIFO_FLUSH = 1 << 0
TWEAK_BIT_ROUND_UP = 1 << 2
# ---------------------------------------------------------------------------
# Output
# ---------------------------------------------------------------------------
CAPTURE_ROOT = "captures"