import sys; sys.path.insert(0,'.') from gerb import * import matplotlib.pyplot as plt from matplotlib.patches import Rectangle, Circle, FancyArrowPatch base="../in/03-Architecture-Hardware/kicad/production" INDIGO="#2C3C5B"; TEAL="#17A08C"; BOARD="#1E3A2E" def zoom(ax, b, prod, win, net_colors, default="#9A9A9A", silk=True, mask=False, paste=False): cu,mac=parse(f"{base}/{prod}/hbox-watchdog-{b}-F_Cu.gtl") g=geoms_of(cu,mac,window=win) ax.add_patch(Rectangle((win[0],win[1]),win[2]-win[0],win[3]-win[1],facecolor=BOARD,zorder=0)) draw_geoms(ax,g,default,bg=BOARD,zorder=1,net_colors=net_colors) if silk: sk,m2=parse(f"{base}/{prod}/hbox-watchdog-{b}-F_Silkscreen.gto"); draw_geoms(ax,geoms_of(sk,m2,window=win),"#EDEDED",alpha=0.85,bg=BOARD,zorder=2) if paste: ps,m3=parse(f"{base}/{prod}/hbox-watchdog-{b}-F_Paste.gtp"); draw_geoms(ax,geoms_of(ps,m3,window=win),"#51F3DA",alpha=0.55,bg=BOARD,zorder=3) ax.set_xlim(win[0],win[2]); ax.set_ylim(win[3],win[1]); ax.set_aspect("equal"); ax.axis("off") # ---- Fig: RS1 Kelvin, both boards ---- fig,axs=plt.subplots(1,2,figsize=(13,6.2)) for ax,b,prod,ttl in ((axs[0],"v5","HBOX_v5_Rev6_PROD","V5.6"),(axs[1],"v57","HBOX_v5_Rev7_PROD","V5.7")): win=(146.5,110.5,160.5,121.5) zoom(ax,b,prod,win,{"/VEH5V":"#E9533A","/VIN_SW":"#F2A93B","/MAIN5V":"#2EA3F2","GND":"#5C6B5C"},default="#9A9A9A") ax.set_title(f"{ttl} — RS1 10 mΩ con sensado Kelvin (F.Cu)",color=INDIGO,fontsize=12,fontweight="bold",loc="left") # annotations ax.annotate("hilo de sensado\nU6.6 (VIN)",xy=(151.6,116.8),xytext=(147.2,112.3),color="white",fontsize=9,arrowprops=dict(arrowstyle="->",color="white",lw=1.2),bbox=dict(boxstyle="round",fc="#E9533A",ec="none")) ax.annotate("hilo de sensado\nU6.7 (CLN)",xy=(153.0,115.3),xytext=(155.5,119.9),color="white",fontsize=9,arrowprops=dict(arrowstyle="->",color="white",lw=1.2),bbox=dict(boxstyle="round",fc="#F2A93B",ec="none")) ax.annotate("entrada VEH5V:\n2 vías 0.6/0.3",xy=(150.75,116.2),xytext=(146.9,120.2),color="white",fontsize=9,arrowprops=dict(arrowstyle="->",color="white",lw=1.2),bbox=dict(boxstyle="round",fc="#C0392B",ec="none")) ax.annotate("RS1.2 → Q7 (VIN_SW)",xy=(153.3,117.9),xytext=(156.3,121.0),color="white",fontsize=9,arrowprops=dict(arrowstyle="->",color="white",lw=1.2),bbox=dict(boxstyle="round",fc="#B9770E",ec="none")) ax.text(146.7,111.0,"rojo = /VEH5V · naranja = /VIN_SW · azul = /MAIN5V (VSYS) · gris = GND",color="white",fontsize=8,va="top") fig.tight_layout(); fig.savefig("fig/fig-rs1-kelvin.png",dpi=200,facecolor="white"); plt.close(fig) # ---- Fig: U6 EP paste windows vs thermal vias ---- fig,axs=plt.subplots(1,2,figsize=(12,6.6)) for ax,b,prod,ttl in ((axs[0],"v5","HBOX_v5_Rev6_PROD","V5.6"),(axs[1],"v57","HBOX_v5_Rev7_PROD","V5.7")): win=(153.2,109.9,159.7,116.4) zoom(ax,b,prod,win,{"GND":"#5C6B5C","/MAIN5V":"#2EA3F2","/VEH5V":"#E9533A"},default="#9A9A9A",silk=False,paste=True) ax.add_patch(Rectangle((156.4475-1.325,113.12-1.825),2.65,3.65,fill=False,edgecolor="white",lw=1.2,ls="--",zorder=5)) vias={"v5":[(156.4475,112.935),(155.6,112.4),(157.2,112.4)],"v57":[(157.135,111.88),(156.45,112.5),(155.735,111.925)]}[b] for (vx,vy) in vias: ax.add_patch(Circle((vx,vy),0.3,facecolor="#C8A05A",edgecolor="white",lw=0.8,zorder=6)) ax.add_patch(Circle((vx,vy),0.15,facecolor=BOARD,edgecolor="none",zorder=7)) ax.annotate("vías térmicas 0.6/0.3\ndentro de la pasta",xy=vias[0],xytext=(157.4,115.6),color="white",fontsize=9,arrowprops=dict(arrowstyle="->",color="white",lw=1.1),bbox=dict(boxstyle="round",fc="#E9533A",ec="none"),zorder=8) ax.set_title(f"{ttl} — U6 LTC4040: pad térmico, pasta y vías",color=INDIGO,fontsize=12,fontweight="bold",loc="left") ax.text(153.4,110.1,"cian = ventanas de pasta (6 × 0.95×0.85 mm = 50 %)\nblanco punteado = pad térmico 2.65×3.65 mm\n3 vías 0.6/0.3 dentro de las ventanas → pedir «Epoxy Filled & Capped»",color="white",fontsize=8.5,va="top",bbox=dict(boxstyle="round",fc="#2C3C5B",ec="none",alpha=0.9)) fig.tight_layout(rect=(0,0,1,0.97)); fig.savefig("fig/fig-u6-pasta.png",dpi=200,facecolor="white"); plt.close(fig) # ---- Fig: V5.7 supply block ---- fig,ax=plt.subplots(figsize=(12,8.5)) win=(172,44,200,76) zoom(ax,"v57","HBOX_v5_Rev7_PROD",win,{"/24V":"#E9533A","/SW_PWRIN":"#F2A93B","/VEH5V":"#2EA3F2","GND":"#5C6B5C","/VIN_FUSED":"#C0392B","/FB_PWRIN":"#9B59B6"},default="#9A9A9A") ax.set_title("V5.7 — fuente a bordo U25 TPS54360B (F.Cu)",color=INDIGO,fontsize=13,fontweight="bold",loc="left") for (x,y,txt) in ((187.7,68.6,"U25"),(186.4,50.0,"L22 10 µH"),(188.4,61.0,"D34 B560C"),(180.9,62.1,"C22"),(179.0,67.0,"C149/C150"),(182.396,68.11,"vía única /24V\n(182.4, 68.1)")): ax.annotate(txt,xy=(x,y),xytext=(x-6.5,y+3.2) if "vía" in txt else (x+2.0,y-2.5),color="white",fontsize=9,arrowprops=dict(arrowstyle="->",color="white",lw=1.1),bbox=dict(boxstyle="round",fc="#2C3C5B",ec="none",alpha=0.9)) ax.text(172.3,44.3,"rojo = /24V · naranja = nodo SW · azul = /VEH5V (5.32 V) · morado = FB",color="white",fontsize=9,va="top") fig.tight_layout(); fig.savefig("fig/fig-v57-fuente.png",dpi=200,facecolor="white"); plt.close(fig) print("zooms done")