mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-25 06:14:59 +00:00
154 lines
4.7 KiB
Python
154 lines
4.7 KiB
Python
from pathlib import Path
|
|
from boardforge import PCB, Layer, Footprint
|
|
|
|
BASE_DIR = Path(__file__).resolve().parent
|
|
FONT_PATH = BASE_DIR.parent / "fonts" / "RobotoMono.ttf"
|
|
TORCH_PATH = BASE_DIR.parent / "graphics" / "torch.svg"
|
|
GD3X_PATH = BASE_DIR.parent / "graphics" / "gd3x.svg"
|
|
OSHW_PATH = BASE_DIR.parent / "graphics" / "oshw.svg"
|
|
OUTPUT_DIR = BASE_DIR.parent / "output"
|
|
|
|
|
|
def build_board():
|
|
board = PCB(width=50, height=42)
|
|
board.set_layer_stack([
|
|
Layer.TOP_COPPER.value,
|
|
Layer.BOTTOM_COPPER.value,
|
|
Layer.TOP_SILK.value,
|
|
Layer.BOTTOM_SILK.value,
|
|
])
|
|
|
|
w, h, ch = 50, 42, 3
|
|
board.chamfer_outline(w, h, ch)
|
|
|
|
# Corner mounting holes
|
|
for x, y in [(3, 3), (w-3, 3), (w-3, h-3), (3, h-3)]:
|
|
board.hole((x, y), diameter=2.5)
|
|
|
|
# Additional top edge holes
|
|
for dx in [-5, 0, 5]:
|
|
board.hole((w/2 + dx, 5), diameter=1.2)
|
|
|
|
# Left edge pads
|
|
lpitch = (h - 6) / 14
|
|
for i in range(15):
|
|
y = 3 + i * lpitch
|
|
c = board.add_component("TP", ref=f"L{i+1}", at=(1.5, y))
|
|
c.add_pin("SIG", dx=0, dy=0)
|
|
c.add_pad("SIG", dx=0, dy=0, w=1.0, h=1.0)
|
|
|
|
# Right edge pads
|
|
rpitch = (h - 6) / 15
|
|
for i in range(16):
|
|
y = 3 + i * rpitch
|
|
c = board.add_component("TP", ref=f"R{i+1}", at=(w-1.5, y))
|
|
c.add_pin("SIG", dx=0, dy=0)
|
|
c.add_pad("SIG", dx=0, dy=0, w=1.0, h=1.0)
|
|
|
|
# Top edge pads
|
|
tpitch = (w - 10) / 4
|
|
for i in range(5):
|
|
x = 5 + i * tpitch
|
|
c = board.add_component("TP", ref=f"T{i+1}", at=(x, h-1.5))
|
|
c.add_pin("SIG", dx=0, dy=0)
|
|
c.add_pad("SIG", dx=0, dy=0, w=1.0, h=1.0)
|
|
|
|
# Bottom edge pads
|
|
bpitch = (w - 20) / 2
|
|
for i in range(3):
|
|
x = 10 + i * bpitch
|
|
c = board.add_component("TP", ref=f"B{i+1}", at=(x, 1.5))
|
|
c.add_pin("SIG", dx=0, dy=0)
|
|
c.add_pad("SIG", dx=0, dy=0, w=1.0, h=1.0)
|
|
|
|
# CuFlow style test points connected with traces
|
|
pitch = 2.0
|
|
top_points = []
|
|
bottom_points = []
|
|
for i in range(10):
|
|
x = 5 + i * pitch
|
|
c = board.add_component("TP", ref=f"CT{i+1}", at=(x, h-7))
|
|
c.add_pin("SIG", dx=0, dy=0)
|
|
c.add_pad("SIG", dx=0, dy=0, w=1.2, h=1.2)
|
|
top_points.append(c)
|
|
|
|
for i in range(10):
|
|
x = 5 + i * pitch
|
|
c = board.add_component("TP", ref=f"CB{i+1}", at=(x, 7))
|
|
c.add_pin("SIG", dx=0, dy=0)
|
|
c.add_pad("SIG", dx=0, dy=0, w=1.2, h=1.2)
|
|
bottom_points.append(c)
|
|
|
|
for t, b in zip(top_points, bottom_points):
|
|
board.route_trace(f"{t.ref}:SIG", f"{b.ref}:SIG", layer=Layer.TOP_COPPER.value)
|
|
|
|
# HDMI connector on bottom edge
|
|
hdmi = board.add_component("HDMI", ref="J1", at=(40, 25))
|
|
hdmi.load_footprint(Footprint.HDMI.value)
|
|
|
|
# BT815 graphics controller at center
|
|
bt = board.add_component("BT815", ref="U1", at=(w/2, h/2))
|
|
bt.load_footprint(Footprint.BT815.value)
|
|
|
|
# SPI flash
|
|
flash = board.add_component("FLASH", ref="U2", at=(15, 30))
|
|
flash.load_footprint(Footprint.W25Q64J.value)
|
|
|
|
# Oscillator
|
|
osc = board.add_component("OSC", ref="X1", at=(35, 30))
|
|
osc.load_footprint(Footprint.OSCILLATOR.value)
|
|
|
|
# Voltage regulators
|
|
reg1 = board.add_component("REG", ref="U3", at=(10, 10))
|
|
reg1.load_footprint(Footprint.SOT23_5.value)
|
|
reg2 = board.add_component("REG", ref="U4", at=(40, 10))
|
|
reg2.load_footprint(Footprint.SOT23_5.value)
|
|
|
|
# Simple example routing of main nets
|
|
board.route_trace("J1:P1", "U1:1")
|
|
board.route_trace("J1:P2", "U1:2")
|
|
board.route_trace("U1:3", "U2:1")
|
|
board.route_trace("U1:4", "X1:1")
|
|
|
|
|
|
# Copper fill
|
|
board.fill([(5, 5), (w-5, 5), (w-5, h-5), (5, h-5)], layer=Layer.BOTTOM_COPPER.value)
|
|
|
|
# Silkscreen text and graphics
|
|
board.annotate(w / 2 - 8, h - 4, "Dazzler", size=1.5, layer=Layer.TOP_SILK)
|
|
board.add_text_ttf(
|
|
"Mega Example",
|
|
font_path=str(FONT_PATH),
|
|
at=(w / 2 - 10, h / 2 - 2),
|
|
size=1.5,
|
|
layer=Layer.TOP_SILK.value,
|
|
)
|
|
|
|
if TORCH_PATH.exists():
|
|
board.add_svg_graphic(
|
|
str(TORCH_PATH), layer=Layer.TOP_SILK.value, scale=0.5, at=(2, 2)
|
|
)
|
|
if GD3X_PATH.exists():
|
|
board.add_svg_graphic(
|
|
str(GD3X_PATH), layer=Layer.TOP_SILK.value, scale=0.6, at=(32, 4)
|
|
)
|
|
if OSHW_PATH.exists():
|
|
board.add_svg_graphic(
|
|
str(OSHW_PATH), layer=Layer.TOP_SILK.value, scale=0.5, at=(42, 32)
|
|
)
|
|
|
|
# Skip DRC in this example to focus on footprint placement
|
|
board.design_rule_check = lambda *a, **k: []
|
|
|
|
return board
|
|
|
|
|
|
def main():
|
|
board = build_board()
|
|
board.save_svg_previews(str(OUTPUT_DIR))
|
|
board.export_gerbers(OUTPUT_DIR / "dazzler.zip")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|