rbpu_datasheet/doc_builder/render_registers.py

116 lines
3.8 KiB
Python
Raw Normal View History

2026-07-19 20:56:15 +08:00
"""Register definition (ids.json) → HTML tables."""
import json
from html import escape
MODULE_ORDER = [
'SYS_REG', 'SYS_ANA', 'SYS_PLL',
'DAQ_REG', 'DAQ_PAR', 'DAQ_FLT',
'AWG_REG', 'TRIG_CTRL', 'PUMP_REG', 'MIXER_REG',
]
MODULE_DESC = {
'SYS_REG': '系统控制寄存器', 'SYS_ANA': '模拟配置寄存器',
'SYS_PLL': 'PLL 配置寄存器', 'DAQ_REG': 'DAQ 控制寄存器',
'DAQ_PAR': 'DAQ 读出参数配置', 'DAQ_FLT': 'DAQ 匹配滤波器系数',
'AWG_REG': 'AWG 控制寄存器', 'TRIG_CTRL': '触发控制寄存器',
'PUMP_REG': 'Pump 控制寄存器', 'MIXER_REG': '混频器控制寄存器',
}
def eh(s):
return escape(str(s))
def _bits_str(bits):
if not bits:
return ''
if len(bits) == 1 or bits[0] == bits[-1]:
return f'[{bits[0]}]'
return f'[{bits[0]}:{bits[-1]}]'
def _range_str(r):
if not r or not r.get('value'):
return ''
t, v = r.get('type', 'str'), r.get('value', '')
if t == 'str':
if v == 'ANY':
return '<em>任意</em>'
if v == 'NA':
return '<em>—</em>'
return eh(str(v))
if t == 'list' and isinstance(v, list):
return f'{v[0]} ~ {v[1]}'
if t == 'set' and isinstance(v, list):
return ', '.join(str(x) for x in v)
return eh(str(v))
def _perm_badge(p):
badges = {
'RW': '<span class="perm-rw">RW</span>',
'RO': '<span class="perm-ro">RO</span>',
'WC': '<span class="perm-wc">WC</span>',
}
return badges.get(p, eh(p))
def render(json_path):
"""Load ids.json and render all register tables as HTML."""
with open(json_path, encoding='utf-8') as f:
data = json.load(f)
modules = data.get('Modules', {})
html = []
for mod_name in MODULE_ORDER:
if mod_name not in modules:
continue
entries = modules[mod_name]
desc = MODULE_DESC.get(mod_name, '')
html.append(
f'<h3 id="reg-{mod_name.lower()}">{mod_name}{desc}</h3>'
)
html.append(f'<p>共 {len(entries)} 个寄存器/存储段。</p>')
for seg_name, seg in entries.items():
addr = seg.get('OffsetAddress', '')
perm = seg.get('Permission', '')
sd = seg.get('SegDescription', '')
fields = seg.get('Fields', [])
html.append(
f'<h4 id="reg-{seg_name}">{seg_name.upper()}</h4>'
)
html.append(
f'<p class="reg-summary">'
f'<strong>偏移地址:</strong><code>{eh(addr)}</code> '
f'<strong>权限:</strong>{_perm_badge(perm)} '
f'<strong>描述:</strong>{eh(sd)}</p>'
)
if fields:
html.append(
'<table class="compact"><thead><tr>'
'<th style="width:11%">Bits</th>'
'<th style="width:18%">Field Name</th>'
'<th style="width:14%">Reset Value</th>'
'<th style="width:12%">Range</th>'
'<th>Description</th>'
'</tr></thead><tbody>'
)
for f in fields:
b = f.get('Bits', [])
html.append(
f'<tr>'
f'<td class="bits">{_bits_str(b)}</td>'
f'<td class="text-mono">{eh(f.get("FieldName", ""))}</td>'
f'<td class="reset-val">{eh(f.get("ResetValue", ""))}</td>'
f'<td>{_range_str(f.get("Range"))}</td>'
f'<td>{eh(f.get("FieldDescription", ""))}</td>'
f'</tr>'
)
html.append('</tbody></table>')
html.append('')
return '\n'.join(html)