cartridge/kicad_sym.py
2023-06-19 17:57:22 +00:00

150 lines
3.6 KiB
Python

from itertools import chain, takewhile, dropwhile, filterfalse
POWER_SIGNALS = {'GND', 'VDD', 'VCC'}
SOURCE_SIGNALS = {'VDD', 'VCC'}
SINK_SIGNALS = {'GND'}
def split_power(lines):
source = []
sink = []
other = []
for pin, signal, type in lines:
if signal in SOURCE_SIGNALS:
source.append((pin, signal, type))
elif signal in SINK_SIGNALS:
sink.append((pin, signal, type))
else:
other.append((pin, signal, type))
return source, sink, other
def make_pin_left(lines, half_width):
for ix, (number, name, type) in enumerate(lines):
x = u(-half_width)
y = u((-ix + 0) * 2)
r = 0
yield pin(x, y, r, number, name, type)
def make_pin_right(lines, half_width):
for ix, (number, name, type) in enumerate(lines):
x = u(half_width)
y = u((-ix + 0) * 2)
r = 180
yield pin(x, y, r, number, name, type)
def make_pin_top(lines):
for ix, (number, name, type) in enumerate(lines):
x = u((ix) * 2)
y = u(6)
r = 270
yield pin(x, y, r, number, name, type)
def make_pin_bottom(lines, height):
for ix, (number, name, type) in enumerate(lines):
x = u((ix) * 2)
y = u(-((height + 2) * 2))
r = 90
yield pin(x, y, r, number, name, type)
def pin_sort_key(s):
is_not_numeric = lambda c: not (ord(c) >= ord('0') and ord(c) <= ord('9'))
h = ''.join(takewhile(is_not_numeric, s))
t = ''.join(dropwhile(is_not_numeric, s))
return h, int(t) if t else -1
def assert_valid(lines):
pins = set()
signals = set()
types = set([
"power_in",
"power_out",
"bidirectional",
"input",
"output"
])
for pin, signal, type in lines:
assert type in types, type
assert pin not in pins, pins
pins.add(pin)
if signal not in POWER_SIGNALS:
assert signal not in signals, signal
signals.add(signal)
def read_txt(filename):
with open(filename) as f:
lines = [l.split() for l in f.read().split('\n') if l]
assert_valid(lines)
return lines
_lib = """
(kicad_symbol_lib (version 20220914) (generator kicad_sym)
{symbols}
)
""".strip('\n')
_symbol = """
(symbol "{name}" (in_bom yes) (on_board yes)
(property "Reference" "U" (at 0 -7.62 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "{value}" (at 0 -10.16 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "{name}_0_1"
(rectangle (start {x0} {y0}) (end {x1} {y1})
(stroke (width 0) (type default))
(fill (type none))
)
)
(symbol "{name}_1_1"
{pins}
)
)
""".strip('\n')
_pin = """
(pin {type} line (at {x:.02f} {y:.02f} {r}) (length {length})
(name "{name}" (effects (font (size 1.27 1.27))))
(number "{number}" (effects (font (size 1.27 1.27))))
)
""".strip('\n')
def lib(symbols):
return _lib.format(
symbols="\n".join(symbols)
)
def symbol(name, value, pins, x0, y0, x1, y1):
return _symbol.format(
name=name,
value=value,
pins="\n".join(pins),
x0=x0,
y0=y0,
x1=x1,
y1=y1
)
def pin(x, y, r, number, name, type, length=4):
return _pin.format(
x=x - u(length) if x < 0 else x + u(length),
y=y,
r=r,
name=name,
type=type,
number=number,
length=u(length)
)
def u(n):
mul = 1.27
return n * mul