from pathlib import Path
import json,hashlib,zipfile
R=Path(__file__).resolve().parent;B=R.parent;H=B/'engineering_handoff_local';sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest();j=json.loads((R/'checks.json').read_text());assert j['ERC']==0 and not j['PCB_present']
refs={'NXP_PCA9956B':'https://www.nxp.com/docs/en/data-sheet/PCA9956B.pdf','local_NXP_sha256':sha(R/'NXP_PCA9956B_Rev1p2.pdf'),'address_pages':[7,8,9,10,11],'ST_G030_datasheet_target':'https://www.st.com.cn/resource/en/datasheet/stm32g030k6.pdf','ST_full_datasheet_local':'NOT_AVAILABLE; HTTP2 failure followed byHTTP1.1 timeout. Official-host attachment fetched a forum print PDF, not the MCU datasheet; excluded and not used as evidence','MCU_pin_AF_ownership':'NOT_CLOSED; no STM32 bus initialization written this turn'}
(R/'source_references.json').write_text(json.dumps(refs,indent=2)+'\n')
report=f'''# PCA灯具驱动原理图恢复与地址闭合 A47

状态：已恢复可读历史PCA原理图、定位本地符号库、重新导出网表并通过ERC0、地址/通道/接口核对。仍为历史子电路候选，所有封装未分配、无PCB，FABRICATION_HOLD。当前目标固件仍A46，无实际I²C回读或LED输出。三款20项功能效果仍0项实测确认。

## 改变后续动作的新证据

上轮旧v0.5网表读失败，不代表所有PCA源都不可获得。本轮stat先区别iCloud dataless文件，找到work/pcba-v128-current下完整83713字节的led_driver.kicad_sch，复制到nosync并从原理图重新导出新网表。没有把云端目录或旧xml当已读取源，也没有把旧版本认定为最终整机设计。

原始原理图字节未改，SHA256 `{j['source_sha256']}`。从嵌入定义导出本地Project符号库和库表，建立空项目设置后完整ERC为0；没有规则豁免。原注释明确子电路/NOT FOR FABRICATION，封装未分配。本轮验证证明恢复及网表结构，不证明布局或物理驱动板。

## 地址与通道

PCA9956B地址是三输入五态编码，不能按普通二进制绑带或测试0x20推断。本轮直接解析NXP Rev1.2第7–10页全部125行，核对7bit地址、写方向地址字节及编码公式，CSV可从实际PDF复现。

- U1 AD2/AD1/AD0=GND/VDD/GND，7bit0x15，逻辑通道0–23，populated mask0xFFFFFF。
- U2=GND/VDD/VDD，7bit0x19，逻辑通道24–47，mask0xFFFFFF。
- U3=VDD/GND/GND，7bit0x65，逻辑通道48–60，mask0x001FFF；本地13–23未使用，后续LEDOUT=OFF、PWM/IREF=0。

原图地址文字与实际网表绑带一致。三地址相互不同且避开默认ALLCALL0x70/SUBCALL0x77；这是候选原理图地址，不是实测ACK或焊接绑带验证。REXT三颗均1.80k1% PROVISIONAL，可满足厂商检测电阻候选条件，但电流/光学/热与实际安装LED未资格确认，不能因此宣称开短路检测可用或固化效果满足。

## 跨板接口

驱动J1.1–6与安全A39 J2.1–6逐脚对照：3.3V/GND/SDA/SCL/OE_N/RESET_N。驱动电源网名VDD_3V3与安全CTRL_3V3不同，在线束/系统接口中明确要求连接为同一控制电源，不能由不同标签文字自动认为已装配。驱动J1.7–8为VLED_GUARDED/GND，要求接A43受控电源输出；本轮没有装线或读实际电压。总61路LED输出及U3未用11路逐脚核对。

## 总线实现前仍要处理

A46监测器是每芯片8次单字节读取、首样本20ms候选时效。若三芯片串行按每毫秒1次读取，第三芯片结束时第一芯片首样本约23ms，不能把全银行当20ms内的新鲜数据。需要多银行轮询排程/完成时间和主机寄存器模拟，再实测真实I²C通信/CPU/红外采样间隔；不能直接复制单芯片测试结论。

STM32G030F6具体引脚/AF及同焊盘别名冲突保护尚未闭合。官方ST完整PDF下载HTTP2失败、HTTP1.1超时；另一个官方主机附件返回的是19页论坛打印PDF，内容核查后排除，没有把HTTP成功当芯片资料已取得。本轮没有写总线配置，也没有释放驱动复位。下一步使用可核对的MCU资料完成引脚/时钟/总线后端，再绑定此候选银行并做目标/主机测试。

此源是PCA9956B分支，与IS31分支协议/使能不同，不能混用。还需器件封装与布局、LED/光学/结构、NTC安装/整板校准、三款实际负载效果及每款1000台完整整机成本和实机验收。ERC0与恢复源不会替代上述目标。无采购、外联、烧录、通电或制造下单。

包内原理图/符号库/新网表、NXP官方PDF、地址解析核对、银行配置和跨板映射、SHA清单；run_native_checks.sh需KiCad10/Python3/PyMuPDF。comparison_only安全网表只用于接口比较；无Gerber、无制造放行。
'''
(R/'README.md').write_text(report);(H/'A47-lamp-PCA-source-and-addresses.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 p.suffix not in ['.pyc','.kicad_prl']]
manifest=''.join(f'{sha(p)}  {p.relative_to(R).as_posix()}\n' for p in sorted(files));(H/'A47-SHA256SUMS.txt').write_text(manifest)
z=H/'Lamp-PCA-source-address-audit-A47.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=j['status'],latest_report='A47-lamp-PCA-source-and-addresses.md',latest_machine_report='../lamp_driver_source_A47/checks.json',latest_manifest='A47-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_PCA_driver_schematic_A47']={'source':'../lamp_driver_source_A47/recovered_legacy_schematic/led_driver.kicad_sch','sha256':j['source_sha256'],'legacy_origin':'v1.28 source; not final-product PCB','ERC':0,'addresses_7bit':[21,25,101],'channel_count':61,'footprints_assigned':False,'PCB_present':False,'firmware_transport_bound':False,'physical_test_release':False}
idx['manufacturing_exclusions']['lamp_A47']='Recovered legacy PCA schematic and verified bank addresses61channel paths; all footprints absent/no PCB. STM32 pin/AF transport, runtime bank scheduling and physical validation not closed; FABRICATION_HOLD.'
ip.write_text(json.dumps(idx,ensure_ascii=False,indent=2)+'\n');print(json.dumps(e,indent=2))
