from pathlib import Path
import json,hashlib,zipfile,shutil,csv
R=Path(__file__).resolve().parent;B=R.parent;H=B/'engineering_handoff_local';T=R/'firmware/固件/lamp_target';sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest()
build=json.loads((T/'build/build_verification.json').read_text());assert build['nominal_voltage_current_diagnostics_bound'] and build['VREFINT_factory_cal_read_bound'] and not build['led_output_enabled'] and not build['ADC_calibrated_safety_permissions_bound']
power=B/'lamp_frontend_pair_A43/power_board/lamp_buck_lmr51450_a4_frontend.kicad_pcb';safety=B/'lamp_IR_PCB_A39/board/lamp_safety_evt_a3_IR_PCB.kicad_pcb'
assert sha(power)=='d96198a142fff179bc75898b4f653f3d09d4759298364e727cf2eb8ab1bd23f1' and sha(safety)=='28d30b5912cce3053ae881a847a66ca13b682c405096475c5e9af943584e2686'
assert 'PASS: 36855' in (R/'actual_measurement_test.log').read_text() and 'Assertion' in (R/'wrong_3p3_factory_reference_measurement_test.log').read_text()
shutil.copy2(B/'lamp_ADC_target_A42/ST_ll_adc_reference.h',R/'ST_ll_adc_reference.h')
refs={'ST_datasheet':'https://www.st.com.cn/resource/en/datasheet/stm32g030k6.pdf','ST_LL':'https://raw.githubusercontent.com/STMicroelectronics/stm32g0xx-hal-driver/master/Inc/stm32g0xx_ll_adc.h','ST_LL_local_sha256':sha(R/'ST_ll_adc_reference.h'),'literal_lines':[258,261],'factory_cal_address':'0x1FFF75AA','factory_cal_voltage_mV':3000,'scope':'STM32G030 factory reference value/address/formula; not actual calibration word read or real analog validation'}
(R/'source_references.json').write_text(json.dumps(refs,indent=2)+'\n')
checks={'status':'A44_LAMP_FACTORY_REFERENCE_NOMINAL_DIAGNOSTICS_LOCAL_PASS_FABRICATION_HOLD','build':build,'numerical_oracle_cases':36855,'ADC_delay_wrap_integration_cases':72,'negative_controls':['wrong3.3V factory reference rejected','skippedCCRDY rejected','wrongPC14 rejected','oldboot alias rejected'],'calibration_sanity_words':'All uint16 words outside1000..2000 rejected; broad diagnostic credibility guard, not ST factory acceptance spec','diagnostic_VDDA_bounds_uV':[2700000,3600000],'raw_frame_age_limit_ms':20,'current_out_of_gain_window_quality_flag':True,'NTC_rail_proximity_flags':[16,4079],'temperature_curve_bound':False,'physical_frontend_calibration':False,'physical_ADC_validation':False,'outputs_enabled':False,'power_PCB_sha256':sha(power),'safety_PCB_sha256':sha(safety),'physical_verified_requirements':0,'reference_requirements':20,'sanitizers':'ASAN_UBSAN_PASS'}
(R/'checks.json').write_text(json.dumps(checks,indent=2)+'\n')
with (R/'physical_calibration_measurements_blank.csv').open('w',newline='') as f:
 w=csv.writer(f);w.writerow(['case_id','scope','intended_stimulus','DMM_VDDA_V','DMM_LED_V','reference_current_A','factory_cal_word','vrefint_raw','LED_V_raw','LED_I_raw','diagnostic_LED_uV','diagnostic_LED_uA','NTC_raw','reference_temperature_C','quality_flags','physical_status'])
 for i,item in enumerate(['no_load_zero','low_current_0p05A','low_current_0p25A','current_0p5A','current_1A','current_2p5A','current_4A','voltage_4p5V','voltage_5V','load_step','warm_drift','NTC_near_short','NTC_near_open'],1):
  w.writerow([f'A44-{i:02d}','A43+A39+A44_candidate',item]+['']*12+['NOT_RUN_REQUIRES_BOARD_BENCH_RELEASE'])
report=f'''# 灯具出厂参考校准与名义诊断换算 A44

状态：本地主机数值/寄存器集成测试及ARM完整构建通过，FABRICATION_HOLD。A43电源板+A39安全板对应固件候选A44；校正参考电压并输出名义电压/电流/NTC电阻诊断，尚未完成实际前端校准、温度曲线或LED授权控制。三款20项功能效果仍0项实测确认。

## 已实际接入

main读取STM32G030的16bit VREFINT_CAL出厂字，地址0x1FFF75AA，参考校准电压3.0V。ARM反汇编核对main调用读取函数和16bit访问地址；实际设备字未读过，主机输入的是模拟校准字。

主循环/完整串口消息前的安全采样路径在A42完整原始帧有效时调用`lamp_measurement_from_frame`，计算VDDA=3.0V×cal/rawVref。实际A43电压分压100k/100k对应倍数2，电流10mR×INA180A1增益20对应0.2V/A；使用64bit整数一次舍入，保留微伏/微安诊断，避免先把VDDA或ADC输入截断到mV再扩大误差。NTC只按10k上拉同CTRL_3V3供电比例求名义电阻，没有套假定B值计算温度。

函数只输出“数字换算成功”，不输出temperature_ok/supply_ok/led_driver_ok或LED许可。出厂参考校准不等于整板分压/分流/放大器/热漂校准。诊断限定估算VDDA2.7–3.6V（其中2.7V涵盖INA180最低供电条件），出厂校准字1000–2000为宽松可信度筛查，不是ST工厂验收规格；ADC夹顶或越界、VREF为0、零序号、首/末时间不合理、最早样本超过20ms均拒绝，失败不改调用者结果。

电流输出不在0.5V到VS-0.5V增益误差保证区间内时标记`CURRENT_OUTSIDE_GAIN_WINDOW`，仍可看名义估算但不能声称该精度。NTC raw≤16或≥4079分别标记近短路/近开路且不给电阻值，这些仅为候选诊断阈值，没有实机断线/过温鉴定。NTC raw4095可报告近开路；电压/电流raw4095拒绝，不能把ADC饱和读数换算为正常值。

调试器可读`lamp_debug_measurement_valid/status/measurement`和原始帧/校准字。每次采样先清valid，仅完整成功后设置；失败时旧结构可能保留，必须看valid和时间戳。多字段调试快照没有给异步外部协议提供原子发布，本轮没有改变UART协议或宣称SoC已接收这些值。

## 当前证据

- 36,855组数值对照：3种模拟校准字×3种参考供电情景×4095个未夹顶采样码，独立浮点物理公式核对参考/电压/电流/电阻，误差在最终单位四舍五入的0.5范围内；32bit时间回绕、质量标志和帧元数据验证。
- 遍历全部uint16校准字，对可信度区间外的字拒绝并保留原输出；空参数、0/满量程/越界raw、参考供电范围、20/21ms边界、未来/部分帧时间和零序号处理通过。它们是数学/软件范围检查，不是实体ADC范围或传感器质量证明。
- 72组真实驱动源代码的ADC寄存器模拟已加入实际换算函数，通道1/5/6/13完整帧→3.3V情景VDDA/名义读数/低电流质量标志测试通过；校准/就绪/转换故障仍拒绝有效帧。硬件W1C/准备/转换时序依然为模型。
- 故意用3.3V替代3.0V出厂参考的合成负对照被物理公式断言拒绝，跳过CCRDY/错IR脚/旧启动别名负对照与原有guard、IR、票据、UART/UI、输出适配器全部回归通过，ASan/UBSan通过。
- ARM完整编译链接及main到出厂字读取/ADC/诊断换算的调用可达性静态核对通过。BIN {build['flash_binary_bytes']} B，FLASH16140/32768，RAM2824/8192（静态链接统计，未测运行栈/CPU峰值）。BIN SHA256 `{build['sha256_bin']}`。

## 仍未闭合

A43电压两级滤波最慢时间常数约10.25ms，5τ约51.25ms；20ms帧时间不能代表模拟输入已跟随负载。电流高侧共模、PSRR/CMRR、失调、低端非线性、Kelvin铜压降、分流器热漂和ADC误差未校准，没有以名义读数授予供电正常。精确NTC曲线与安装/热耦合、驱动器状态回读、输出闭环及整机负载/光学/AI链路仍缺实机证据，LED输出继续关断。相同目标仍包含电磨/吸尘器两款、每款1000台整机BOM成本与功能效果验证，不能由本轮诊断数学代替。

配对电源A43 SHA256 `{sha(power)}`、安全A39 SHA256 `{sha(safety)}`，本轮只核对本地文件hash，不修改或重跑CAD。本轮BOM无增加，无采购、外联、烧录、通电或制造下单。

下一步选择精确NTC并落实曲线/热测配置，再接驱动状态回读与校准安全判据。包内测量CSV全部实測字段留空，只是后续受控台架记录模板，不是已执行测试。完整可编辑源码、ELF/BIN/MAP、测试/日志和SHA清单包含在包内；运行`sh run_checks.sh`需要cc/Python3/arm-none-eabi工具链。
'''
(R/'README.md').write_text(report);(H/'A44-lamp-reference-and-diagnostics.md').write_text(report)
files=[p for p in R.rglob('*') if p.is_file() and p.name!='package.py' and not p.name.startswith('.') and all(x not in p.parts for x in ['host_test','adc_host_test','measurement_host_test']) and p.suffix in ['.c','.h','.s','.ld','.sh','.py','.md','.json','.log','.txt','.csv','.elf','.bin','.map']]
manifest=''.join(f'{sha(p)}  {p.relative_to(R).as_posix()}\n' for p in sorted(files));(H/'A44-SHA256SUMS.txt').write_text(manifest)
z=H/'Lamp-reference-nominal-diagnostics-review-A44.zip'
with zipfile.ZipFile(z,'w',zipfile.ZIP_DEFLATED) as a:
 for p in files:a.write(p,p.relative_to(R).as_posix())
 a.writestr('SHA256SUMS.txt',manifest)
with zipfile.ZipFile(z) as a:
 assert a.testzip() is None
 for line in manifest.splitlines():
  digest,name=line.split('  ',1);assert hashlib.sha256(a.read(name)).hexdigest()==digest
 count=len(a.namelist())
ip=H/'LOCAL-PACKAGES.json';idx=json.loads(ip.read_text());idx.update(status=checks['status'],latest_report='A44-lamp-reference-and-diagnostics.md',latest_machine_report='../lamp_measurement_A44/checks.json',latest_manifest='A44-SHA256SUMS.txt')
e={'archive':z.name,'sha256':sha(z),'bytes':z.stat().st_size,'zip_entries':count,'manifest_entries':len(files),'zip_crc':'PASS','manifest_readback':'PASS','manufacturing_status':'FABRICATION_HOLD'}
idx['packages']=[p for p in idx['packages'] if p.get('archive')!=z.name]+[e]
idx['latest_lamp_safe_firmware_A44']={'source':'../lamp_measurement_A44/firmware/固件/lamp_target','binary_sha256':build['sha256_bin'],'board_pair':'A43 power+A39 safety','VREFINT_factory_cal_read_bound':True,'nominal_voltage_current_diagnostics_bound':True,'calibrated_safety_permissions_bound':False,'outputs_enabled':False,'physical_test_release':False}
idx['latest_lamp_power_frontend_A43']['firmware_pair']='A44 factory-reference corrected nominal diagnostics only'
idx['latest_lamp_IR_hardware_A39']['bound_firmware_candidate']='../lamp_measurement_A44/firmware/固件/lamp_target'
idx['latest_lamp_IR_policy_A35']['linked_candidate']='../lamp_measurement_A44/firmware/固件/lamp_target'
idx['lamp_clean_build']={'report':'../lamp_measurement_A44/firmware/固件/lamp_target/build/build_verification.json','binary_sha256':build['sha256_bin'],'physical_validation':'NOT_RUN_NO_SAMPLE','led_output_enabled':False,'scope':'A44 PCA branch hard-off image with IR/rawADC/factory-reference nominal diagnostics; temperature curve and safety/output closure incomplete'}
idx['manufacturing_exclusions']['lamp_A44']='Factory-reference nominal diagnostic formulas implemented and MMIO/numerical/target-link checked; actual device calibration word/analog calibration, NTC curve/mounting, driver/output and physical validation remain absent; FABRICATION_HOLD.'
ip.write_text(json.dumps(idx,ensure_ascii=False,indent=2)+'\n');print(json.dumps(e,indent=2))
