116 lines
3.8 KiB
Python
116 lines
3.8 KiB
Python
|
|
"""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)
|