Source code for jitxlib.landpatterns.twopin.axial
from collections.abc import Iterable
from dataclasses import dataclass
from enum import Enum
from typing import override
from jitx.shapes.primitive import Circle
from jitx.toleranced import Toleranced
from jitx.transform import Transform
from .. import LandpatternGenerator
from ..courtyard import ExcessCourtyard, OriginMarkerMixin
from ..grid_layout import GridPosition, LinearNumbering
from ..leads import THLead
from ..package import PackageBody, PackageBodyMixin
from ..pads import GridPadShapeGeneratorMixin, IPCTHPadConfig
from ..silkscreen.marker import Pad1Marker
from .smt import CathodeAnodeNumbering
# Default lead bend start is 1.0mm from the edge of the package body.
DEFAULT_BEND_START = 1.0
[docs]
@dataclass(frozen=True)
class THWeldBeadLead(THLead):
"""Through-hole lead with optional weld bead
This class is used to specify a through-hole lead with an optional weld
bead. The weld bead is specified as an offset from the lead's center.
"""
weld_offset: Toleranced = Toleranced.exact(0.0)
"""Weld bead offset
Additional margin to provide around a lead to account for the weld bead.
"""
[docs]
class AxialMounting(Enum):
"""Axial component mounting style
This enum is used to specify the mounting style of an axial component.
"""
Horizontal = "Horizontal"
"""Horizontal Mounting Style
This is the typical mounting style where the lead axis is parallel to the
board surface.
"""
Vertical = "Vertical"
"""Vertical Mounting Style
This is the mounting style where the lead axis is perpendicular to the board
surface, and the lead pointing away from the board surface is bent 180
degrees to return to the board surface.
"""
[docs]
def compute_default_bend_radius(lead_diameter: Toleranced) -> float:
"""Compute default target bend radius.
.. seealso::
IPC-A-610 Section 7.1.2, Table 7-1 Lead Bend Radius
"""
diam = lead_diameter.typ
if diam < 0.8:
return diam
elif diam < 1.2:
return 1.5 * diam
else:
return 2.0 * diam
[docs]
@dataclass(frozen=True)
class LeadBend:
radius: float
"""Radius of the bend in the lead"""
start: float = 1.0
"""Lead bend start from the edge of the package body. Default is 1.0mm."""
DEFAULT_BEND_START = 1.0
[docs]
class AxialTwoPinBase(
PackageBodyMixin, GridPadShapeGeneratorMixin, LandpatternGenerator
):
_num_rows = 2
_num_cols = 1
def __init__(
self,
*,
lead: THLead,
package_body: PackageBody,
mounting: AxialMounting = AxialMounting.Horizontal,
bend: LeadBend | None = None,
):
super().__init__()
self.__lead = lead
self.__mounting = mounting
self.pad_config(IPCTHPadConfig())
self.package_body(package_body)
if isinstance(lead, THWeldBeadLead):
self.__weld_offset = lead.weld_offset.typ
else:
self.__weld_offset = 0.0
if bend is not None:
self.__bend = bend
else:
self.__bend = LeadBend(compute_default_bend_radius(lead.width))
def __lead_spacing(self) -> float:
lead = self.__lead
package_body = self._package_body()
mounting = self.__mounting
weld_offset = self.__weld_offset
bend_radius = self.__bend.radius
bend_start = self.__bend.start
width, length = package_body.dims
match mounting:
case AxialMounting.Horizontal:
base_len = length.typ
bend_len = bend_radius + bend_start + weld_offset
return base_len + 2.0 * bend_len
case AxialMounting.Vertical:
body_radius = width.typ / 2.0
lead_radius = lead.width.typ / 2.0
# TODO - explain margin magic number
bend_diam = body_radius + lead_radius + 0.1
bend_len = bend_radius + bend_start
# Take the max of the computed radius and the minimum bend
# radius
return max(bend_diam / 2.0, bend_radius)
@override
def _generate_layout(self) -> Iterable[GridPosition]:
half_spacing = self.__lead_spacing() / 2.0
return (
GridPosition(0, 0, Transform.translate(0.0, half_spacing)),
GridPosition(1, 0, Transform.translate(0.0, -half_spacing)),
)
@override
def _pad_shape(self, pos: GridPosition):
return Circle(diameter=self.__lead.width.typ)
[docs]
class AxialTwoPinDecorated(OriginMarkerMixin, ExcessCourtyard, AxialTwoPinBase):
pass
[docs]
class PolarizedAxialTwoPin(CathodeAnodeNumbering, Pad1Marker, AxialTwoPinDecorated):
pass
[docs]
class AxialTwoPin(LinearNumbering, AxialTwoPinDecorated):
pass