Skip to content
This repository has been archived by the owner on Dec 10, 2024. It is now read-only.

Add: JLCPCB header picker #78

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions src/faebryk/library/Header.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,17 @@ def __init__(
vertical_pin_count: int,
) -> None:
super().__init__()
self.horizontal_pin_count = horizonal_pin_count
self.vertical_pin_count = vertical_pin_count
self._horizontal_pin_count = horizonal_pin_count
self._vertical_pin_count = vertical_pin_count

def __preinit__(self):
self.pin_count_horizonal.merge(self.horizontal_pin_count)
self.pin_count_vertical.merge(self.vertical_pin_count)
self.pin_count_horizonal.merge(self._horizontal_pin_count)
self.pin_count_vertical.merge(self._vertical_pin_count)

pin_pitch: F.TBD[Quantity]
mating_pin_lenght: F.TBD[Quantity]
conection_pin_lenght: F.TBD[Quantity]
spacer_height: F.TBD[Quantity]
pin_type: F.TBD[PinType]
pad_type: F.TBD[PadType]
angle: F.TBD[Angle]
Expand All @@ -46,7 +49,13 @@ def __preinit__(self):
pin_count_vertical: F.TBD[int]

@L.rt_field
def unnamed(self):
return times(self.horizonal_pin_count * self.vertical_pin_count, F.Electrical)
def contact(self):
return times(
self._horizontal_pin_count * self._vertical_pin_count, F.Electrical
)

designator_prefix = L.f_field(F.has_designator_prefix_defined)("J")
designator_prefix = L.f_field(F.has_designator_prefix_defined)(
F.has_designator_prefix.Prefix.J
)

attach_to_footprint: F.can_attach_to_footprint_symmetrically
2 changes: 1 addition & 1 deletion src/faebryk/library/_F.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@
from faebryk.library.XtalIF import XtalIF
from faebryk.library.has_pin_association_heuristic import has_pin_association_heuristic
from faebryk.library.Common_Mode_Filter import Common_Mode_Filter
from faebryk.library.Header import Header
from faebryk.library.PJ398SM import PJ398SM
from faebryk.library.RJ45_Receptacle import RJ45_Receptacle
from faebryk.library.Relay import Relay
Expand Down Expand Up @@ -114,6 +113,7 @@
from faebryk.library.Capacitor import Capacitor
from faebryk.library.Crystal import Crystal
from faebryk.library.Fuse import Fuse
from faebryk.library.Header import Header
from faebryk.library.Inductor import Inductor
from faebryk.library.Resistor import Resistor
from faebryk.library.Switch import Switch
Expand Down
8 changes: 8 additions & 0 deletions src/faebryk/libs/picker/jlcpcb/jlcpcb.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,14 @@ def filter_by_manufacturer_pn(self, partnumber: str) -> Self:
self.Q &= Q(mfr__icontains=partnumber)
return self

def filter_by_package(self, package: str | list[str]) -> Self:
assert self.Q
if isinstance(package, str):
self.Q &= Q(package__icontains=package)
elif isinstance(package, list):
self.Q &= Q(package__in=package)
return self

def filter_by_manufacturer(self, manufacturer: str) -> Self:
assert self.Q
if not manufacturer:
Expand Down
76 changes: 76 additions & 0 deletions src/faebryk/libs/picker/jlcpcb/picker_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,81 @@ def find_ldo(cmp: Module):
)


def find_header(cmp: Module):
"""
Find a header part in the JLCPCB database that matches the parameters of the
provided header
"""

assert isinstance(cmp, F.Header)

def pin_structure_to_pin_count(vertical: bool) -> Callable[[str], F.Constant[int]]:
"""
Database data looks like: 1x3P
"""

def f(x: str) -> F.Constant[int]:
if "x" not in x:
raise ValueError(f"Invalid pin structure: {x}")
if vertical:
return F.Constant(int(x.strip("P").split("x")[0]))
else:
return F.Constant(int(x.strip("P").split("x")[1]))

return f

mapping = [
MappingParameterDB(
"pin_pitch",
[
"Row Spacing",
"Pitch",
],
),
MappingParameterDB(
"mating_pin_lenght",
["Length of Mating Pin"],
),
MappingParameterDB(
"conection_pin_lenght",
["Length of End Connection Pin"],
),
MappingParameterDB(
"spacer_height",
["Insulation Height"],
),
# MappingParameterDB(
ruben-iteng marked this conversation as resolved.
Show resolved Hide resolved
# "angle",
# ["Mounting Type"],
# transform_fn=str_to_enum_func(F.Header.Angle),
# ), #TODO
MappingParameterDB(
"pin_count_horizonal",
["Pin Structure"],
transform_fn=pin_structure_to_pin_count(vertical=False),
),
MappingParameterDB(
"pin_count_vertical",
["Pin Structure"],
transform_fn=pin_structure_to_pin_count(vertical=True),
),
]

(
ComponentQuery()
.filter_by_category("Connectors", "Header")
ruben-iteng marked this conversation as resolved.
Show resolved Hide resolved
.filter_by_package(
"SMD"
if cmp.pad_type == F.Header.PadType.SMD
else ["TH", "Plugin", "Push-Pull"]
)
.filter_by_stock(qty)
.filter_by_traits(cmp)
.sort_by_price(qty)
.filter_by_module_params_and_attach(cmp, mapping, qty)
)


# --------------------------------------------------------------------------------------

TYPE_SPECIFIC_LOOKUP = {
Expand All @@ -508,4 +583,5 @@ def find_ldo(cmp: Module):
F.Diode: find_diode,
F.MOSFET: find_mosfet,
F.LDO: find_ldo,
F.Header: find_header,
}
4 changes: 2 additions & 2 deletions src/faebryk/libs/picker/lcsc.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ def attach(component: Module, partno: str, get_model: bool = True):
raise LCSC_PinmapException(partno, f"Failed to get pinmap: {e}") from e
component.add(F.can_attach_to_footprint_via_pinmap(pinmap))

sym = F.Symbol.with_component(component, pinmap)
sym.add(F.Symbol.has_kicad_symbol(f"lcsc:{easyeda_footprint.info.name}"))
sym = F.Symbol.with_component(component, pinmap)
sym.add(F.Symbol.has_kicad_symbol(f"lcsc:{easyeda_footprint.info.name}"))
ruben-iteng marked this conversation as resolved.
Show resolved Hide resolved

# footprint
fp = F.KicadFootprint(
Expand Down
12 changes: 12 additions & 0 deletions test/libs/picker/test_jlcpcb.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,18 @@ def test_find_ldo(self):
],
)

def test_find_header(self):
self.TestRequirements(
self,
requirement=F.Header(horizonal_pin_count=3, vertical_pin_count=1).builder(
lambda h: (
h.pad_type.merge(F.Constant(F.Header.PadType.THROUGH_HOLE)),
h.pin_pitch.merge(F.Constant(2.54 * P.mm)),
)
),
footprint=[("Plugin,P=2.54mm", 3)],
)

def tearDown(self):
# in test atexit not triggered, thus need to close DB manually
JLCPCB_DB.get().close()
Expand Down