285 lines
8.4 KiB
Python
285 lines
8.4 KiB
Python
#!/usr/bin/env python3
|
|
|
|
# QFN/QFP-style packages with ground plane
|
|
# version 0.0.7
|
|
|
|
# added solder mask parameter
|
|
# added optional indicator circle
|
|
# added ground pad
|
|
# made ground pad optional
|
|
# fix silkscreen pin 1 marker
|
|
# added rounded pads option
|
|
# added reference designator to fab layer
|
|
# make fab layer pin drawing optional
|
|
# added TI's weird ground pad extensions
|
|
# v0.0.5
|
|
# added indicator marker to fab layer
|
|
# v0.0.6
|
|
# removed TI extensions
|
|
# converted for use in QFN/QFP packages
|
|
# - add pads for QFN/QFP
|
|
# - add fab pad drawings for QFN/QFP
|
|
# - fix silkscreen
|
|
# v0.0.7
|
|
# - add ground pad offset
|
|
|
|
PARTNAME = "TI-RGZ-48"
|
|
|
|
total_pins = 48
|
|
num_per_edge = total_pins // 4
|
|
|
|
M1 = 0.2 # silkscreen margin
|
|
M2 = 0.05 # fab outline margin
|
|
M3 = 0.3 # courtyard margin
|
|
|
|
Z = 6.8 + 0.6 # distance across outer edges of pads
|
|
G = 6.8 - 0.6 # distance across inner edges of pads
|
|
|
|
X = (Z+G)/2. # distance between pad centers
|
|
C = 0.5 # footprint pad spacing
|
|
w = 0.24 # footprint pad width
|
|
h = (Z-G)/2. # footprint pad length
|
|
|
|
show_fab_pads = False
|
|
H = 7.0 # distance from physical pad end to opposite pad end
|
|
e = C # physical pad spacing, same as above
|
|
b = 0.24 # physical pad width
|
|
L1 = -0.4 # physical pad length
|
|
|
|
D1 = 7.0 # package width
|
|
E1 = 7.0 # package height
|
|
|
|
has_ground_pad = True
|
|
G1 = 4.60 # ground pad width
|
|
H1 = 4.975 # ground pad height
|
|
I1 = 0.0 # ground pad x offset
|
|
J1 = 0.188 # ground pad y offset
|
|
ground_pad_num = 0
|
|
|
|
# NOTE: need to test with SMD footprints
|
|
# need to make sure pad size adjustment works
|
|
# nsmd = positive
|
|
solder_mask_margin = 0.10
|
|
indicator_circle_dia = 0.3
|
|
|
|
pad_radius = 0.05
|
|
|
|
if solder_mask_margin < 0.0:
|
|
w -= 2.0*solder_mask_margin
|
|
h -= 2.0*solder_mask_margin
|
|
G1 -= 2.0*solder_mask_margin
|
|
H1 -= 2.0*solder_mask_margin
|
|
|
|
import math
|
|
|
|
import time
|
|
gen_time = hex(int(time.time()))[2:].upper()
|
|
|
|
|
|
prologue = """(module {} (layer F.Cu) (tedit {})
|
|
(fp_text reference REF** (at 0.0 0.0) (layer F.SilkS)
|
|
(effects (font (size 1 1) (thickness 0.15)))
|
|
)
|
|
(fp_text user %R (at 0.0 0.0) (layer F.Fab)
|
|
(effects (font (size 1 1) (thickness 0.15)))
|
|
)
|
|
(fp_text value %V (at 0 -0.5) (layer F.Fab) hide
|
|
(effects (font (size 1 1) (thickness 0.15)))
|
|
)
|
|
"""
|
|
|
|
prologue = prologue.format(PARTNAME, gen_time, PARTNAME)
|
|
epilogue = """)"""
|
|
|
|
print(prologue)
|
|
|
|
# print silkscreen outline
|
|
inner_edge = C*(num_per_edge/2 - 0.5) + w/2 + M1
|
|
x = D1/2 + M1
|
|
y = E1/2 + M1
|
|
for x, y, nx, ny in [
|
|
(-x, -inner_edge, -inner_edge, -y),
|
|
|
|
(-x, y, -x, inner_edge), (-inner_edge, y, -x, y),
|
|
(inner_edge, y, x, y), (x, y, x, inner_edge),
|
|
(x, -inner_edge, x, -y), (x, -y, inner_edge, -y)]:
|
|
print(""" (fp_line (start {} {}) (end {} {}) (layer F.SilkS) (width 0.15))""".
|
|
format(x, y, nx, ny))
|
|
|
|
if indicator_circle_dia is not None:
|
|
x = D1/2 + M1 #+ 0.5*indicator_circle_dia
|
|
y = E1/2 + M1 #+ 0.5*indicator_circle_dia
|
|
# add indicator circle
|
|
print(""" (fp_circle (center {} {}) (end {} {}) (layer F.SilkS) (width 0.15))""".
|
|
format(-x, -y, -x, -y - indicator_circle_dia/2.0))
|
|
|
|
|
|
# draw package outline in fab layer
|
|
FC = 0.3
|
|
fab_points = [(-D1/2 - M2 + FC, -E1/2 - M2),
|
|
(D1/2 + M2, -E1/2 - M2),
|
|
(D1/2 + M2, E1/2 + M2),
|
|
(-D1/2 + -M2, E1/2 + M2),
|
|
(-D1/2 + -M2, -E1/2 - M2 + FC)]
|
|
|
|
nx, ny = fab_points[-1]
|
|
for x, y in fab_points:
|
|
print(""" (fp_line (start {} {}) (end {} {}) (layer F.Fab) (width 0.15))""".
|
|
format(x, y, nx, ny))
|
|
nx, ny = x, y
|
|
|
|
if show_fab_pads:
|
|
for i in range(num_per_edge):
|
|
x_pos = -D1/2 - M2
|
|
y_pos = C*(i-(num_per_edge/2-0.5))
|
|
print(""" (fp_line (start {} {}) (end {} {}) (layer F.Fab) (width 0.15))""".
|
|
format(x_pos, y_pos - b/2 - M2, x_pos - L1, y_pos - b/2 - M2))
|
|
print(""" (fp_line (start {} {}) (end {} {}) (layer F.Fab) (width 0.15))""".
|
|
format(x_pos - L1, y_pos - b/2 - M2, x_pos - L1, y_pos + b/2 + M2))
|
|
print(""" (fp_line (start {} {}) (end {} {}) (layer F.Fab) (width 0.15))""".
|
|
format(x_pos - L1, y_pos + b/2 + M2, x_pos, y_pos + b/2 + M2))
|
|
|
|
for i in range(num_per_edge):
|
|
x_pos = C*(i-(num_per_edge/2-0.5))
|
|
y_pos = E1/2 + M2
|
|
print(""" (fp_line (start {} {}) (end {} {}) (layer F.Fab) (width 0.15))""".
|
|
format(x_pos - b/2 - M2, y_pos, x_pos - b/2 - M2, y_pos + L1))
|
|
print(""" (fp_line (start {} {}) (end {} {}) (layer F.Fab) (width 0.15))""".
|
|
format(x_pos - b/2 - M2, y_pos + L1, x_pos + b/2 + M2, y_pos + L1))
|
|
print(""" (fp_line (start {} {}) (end {} {}) (layer F.Fab) (width 0.15))""".
|
|
format(x_pos + b/2 + M2, y_pos + L1, x_pos + b/2 + M2, y_pos))
|
|
|
|
for i in range(num_per_edge):
|
|
x_pos = D1/2 + M2
|
|
y_pos = -C*(i-(num_per_edge/2-0.5))
|
|
print(""" (fp_line (start {} {}) (end {} {}) (layer F.Fab) (width 0.15))""".
|
|
format(x_pos, y_pos + b/2 + M2, x_pos + L1, y_pos + b/2 + M2))
|
|
print(""" (fp_line (start {} {}) (end {} {}) (layer F.Fab) (width 0.15))""".
|
|
format(x_pos + L1, y_pos + b/2 + M2, x_pos + L1, y_pos - b/2 - M2))
|
|
print(""" (fp_line (start {} {}) (end {} {}) (layer F.Fab) (width 0.15))""".
|
|
format(x_pos + L1, y_pos - b/2 - M2, x_pos, y_pos - b/2 - M2))
|
|
|
|
for i in range(num_per_edge):
|
|
x_pos = -C*(i-(num_per_edge/2-0.5))
|
|
y_pos = -E1/2 - M2
|
|
print(""" (fp_line (start {} {}) (end {} {}) (layer F.Fab) (width 0.15))""".
|
|
format(x_pos + b/2 + M2, y_pos, x_pos + b/2 + M2, y_pos - L1))
|
|
print(""" (fp_line (start {} {}) (end {} {}) (layer F.Fab) (width 0.15))""".
|
|
format(x_pos + b/2 + M2, y_pos - L1, x_pos - b/2 - M2, y_pos - L1))
|
|
print(""" (fp_line (start {} {}) (end {} {}) (layer F.Fab) (width 0.15))""".
|
|
format(x_pos - b/2 - M2, y_pos - L1, x_pos - b/2 - M2, y_pos))
|
|
|
|
|
|
# print courtyard outline
|
|
inner_x = D1/2 + M3
|
|
outer_x = X/2 + h/2 + M3/2
|
|
inner_y = C*(num_per_edge/2-0.5) + b/2 + M3/2
|
|
outer_y = E1/2 + M3
|
|
pts = [
|
|
(-inner_x, -outer_y),
|
|
(inner_x, -outer_y),
|
|
(inner_x, -inner_y),
|
|
(outer_x, -inner_y),
|
|
(outer_x, inner_y),
|
|
(inner_x, inner_y),
|
|
(inner_x, outer_y),
|
|
(-inner_x, outer_y),
|
|
(-inner_x, inner_y),
|
|
(-outer_x, inner_y),
|
|
(-outer_x, -inner_y),
|
|
(-inner_x, -inner_y)
|
|
]
|
|
nx, ny = pts[-1]
|
|
for px, py in pts:
|
|
x, y, nx, ny = nx, ny, px, py
|
|
print(""" (fp_line (start {} {}) (end {} {}) (layer F.CrtYd) (width 0.15))""".
|
|
format(x, y, nx, ny))
|
|
|
|
|
|
padtype = "rect"
|
|
padext = ""
|
|
if pad_radius is not None:
|
|
padtype = "roundrect"
|
|
padext = "(roundrect_rratio {})".format(pad_radius/min(h, w))
|
|
|
|
for i in range(0, num_per_edge):
|
|
print(""" (pad {} smd {} (at {} {}) (size {} {}) (layers F.Cu F.Paste F.Mask)
|
|
{} (solder_mask_margin {}))""".
|
|
format(
|
|
i+1,
|
|
padtype,
|
|
-X/2,
|
|
C*(i-(num_per_edge/2-0.5)),
|
|
h,
|
|
w,
|
|
padext,
|
|
solder_mask_margin))
|
|
|
|
for i in range(0, num_per_edge):
|
|
print(""" (pad {} smd {} (at {} {}) (size {} {}) (layers F.Cu F.Paste F.Mask)
|
|
{} (solder_mask_margin {}))""".
|
|
format(
|
|
i+1+1*num_per_edge,
|
|
padtype,
|
|
C*(i-(num_per_edge/2-0.5)),
|
|
X/2,
|
|
w,
|
|
h,
|
|
padext,
|
|
solder_mask_margin))
|
|
|
|
for i in range(0, num_per_edge):
|
|
print(""" (pad {} smd {} (at {} {}) (size {} {}) (layers F.Cu F.Paste F.Mask)
|
|
{} (solder_mask_margin {}))""".
|
|
format(
|
|
i+1+2*num_per_edge,
|
|
padtype,
|
|
X/2,
|
|
-C*(i-(num_per_edge/2-0.5)),
|
|
h,
|
|
w,
|
|
padext,
|
|
solder_mask_margin))
|
|
|
|
for i in range(0, num_per_edge):
|
|
print(""" (pad {} smd {} (at {} {}) (size {} {}) (layers F.Cu F.Paste F.Mask)
|
|
{} (solder_mask_margin {}))""".
|
|
format(
|
|
i+1+3*num_per_edge,
|
|
padtype,
|
|
-C*(i-(num_per_edge/2-0.5)),
|
|
-X/2,
|
|
w,
|
|
h,
|
|
padext,
|
|
solder_mask_margin))
|
|
|
|
|
|
if has_ground_pad:
|
|
if pad_radius is None:
|
|
# add ground pad
|
|
print(""" (pad {} smd {} (at {} {}) (size {} {}) (layers F.Cu F.Paste F.Mask)
|
|
(solder_mask_margin {}))""".
|
|
format(
|
|
ground_pad_num,
|
|
"rect",
|
|
I1,
|
|
J1,
|
|
G1,
|
|
H1,
|
|
solder_mask_margin))
|
|
else:
|
|
print(""" (pad {} smd {} (at {} {}) (size {} {}) (layers F.Cu F.Paste F.Mask)
|
|
(roundrect_rratio {}) (solder_mask_margin {}))""".
|
|
format(
|
|
ground_pad_num,
|
|
"roundrect",
|
|
I1,
|
|
J1,
|
|
G1,
|
|
H1,
|
|
pad_radius/min(G1, H1),
|
|
solder_mask_margin))
|
|
|
|
print(epilogue)
|