Skip to content
This repository has been archived by the owner on Oct 7, 2020. It is now read-only.

Support generating two-terminal footprints with IPC density argument #439

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 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
38 changes: 31 additions & 7 deletions ...ckage_rlc-etc/SMD_chip_package_rlc-etc.py → ...ip_package_rlc-etc/SMD_package_rlc-etc.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def merge_dicts(*dict_args):
result.update(dictionary)
return result

class TwoTerminalSMDchip():
class TwoTerminalSMD():
def __init__(self, command_file, configuration):
self.configuration = configuration
with open(command_file, 'r') as command_stream:
Expand All @@ -49,7 +49,7 @@ def calcPadDetails(self, device_dimensions, ipc_data, ipc_round_base, footprint_
# Gmin = Smax − 2JH − √(CS^2 + F^2 + P^2)
# Xmax = Wmin + 2JS + √(CW^2 + F^2 + P^2)

# Some manufacturers do not list the terminal spacing (S) in their datasheet but list the terminal lenght (T)
# Some manufacturers do not list the terminal spacing (S) in their datasheet but list the terminal length (T)
# Then one can calculate
# Stol(RMS) = √(Ltol^2 + 2*^2)
# Smin = Lmin - 2*Tmax
Expand Down Expand Up @@ -95,7 +95,7 @@ def deviceDimensions(device_size_data):
elif 'terminal_length_max' in device_size_data and 'terminal_length_min' in device_size_data or 'terminal_length' in device_size_data:
dimensions['terminal_length'] = TolerancedSize.fromYaml(device_size_data, base_name='terminal_length')
else:
raise KeyError("Either terminator spacing or terminal lenght must be included in the size definition.")
raise KeyError("Either terminator spacing or terminal length must be included in the size definition.")

if 'terminal_width_min' in device_size_data and 'terminal_width_max' in device_size_data or 'terminal_width' in device_size_data:
dimensions['terminal_width'] = TolerancedSize.fromYaml(device_size_data, base_name='terminal_width')
Expand All @@ -117,6 +117,7 @@ def generateFootprints(self):
print(exc)

for size_name in package_size_defintions:
print(group_name + ': ' + size_name)
device_size_data = package_size_defintions[size_name]
try:
self.generateFootprint(device_size_data,
Expand All @@ -130,10 +131,11 @@ def generateFootprint(self, device_size_data, footprint_group_data):
fab_line_width = self.configuration.get('fab_line_width', 0.1)
silk_line_width = self.configuration.get('silk_line_width', 0.12)

device_dimensions = TwoTerminalSMDchip.deviceDimensions(device_size_data)
device_dimensions = TwoTerminalSMD.deviceDimensions(device_size_data)

ipc_reference = footprint_group_data['ipc_reference']
ipc_density = footprint_group_data['ipc_density']
ipc_density = self.configuration.get('ipc_density')[0]
density_suffix = self.configuration.get('ipc_density')[1]
ipc_data_set = self.ipc_defintions[ipc_reference][ipc_density]
ipc_round_base = self.ipc_defintions[ipc_reference]['round_base']

Expand All @@ -147,6 +149,13 @@ def generateFootprint(self, device_size_data, footprint_group_data):

model3d_path_prefix = self.configuration.get('3d_model_prefix','${KISYS3DMOD}')
suffix_3d = suffix if footprint_group_data.get('include_suffix_in_3dpath', 'True') == 'True' else ""

if density_suffix != '' and 'handsolder' not in footprint_group_data['keywords']:
density_description = ', IPC-7351 {density:s} land protrusion'.format(density=ipc_density)
suffix = suffix + density_suffix
suffix_3d = suffix_3d + density_suffix
else:
density_description = ''

code_metric = device_size_data.get('code_metric')
code_letter = device_size_data.get('code_letter')
Expand Down Expand Up @@ -176,6 +185,7 @@ def generateFootprint(self, device_size_data, footprint_group_data):
# init kicad footprint
kicad_mod.setDescription(footprint_group_data['description'].format(code_imperial=code_imperial,
code_metric=code_metric, code_letter=code_letter,
density=density_description,
size_info=device_size_data.get('size_info')))
kicad_mod.setTags(footprint_group_data['keywords'])
kicad_mod.setAttribute('smd')
Expand Down Expand Up @@ -334,10 +344,23 @@ def generateFootprint(self, device_size_data, footprint_group_data):
help='list of files holding information about what devices should be created.')
parser.add_argument('--global_config', type=str, nargs='?', help='the config file defining how the footprint will look like. (KLC)', default='../tools/global_config_files/config_KLCv3.0.yaml')
parser.add_argument('--series_config', type=str, nargs='?', help='the config file defining series parameters.', default='config_KLCv3.0.yaml')
parser.add_argument('--ipc_definition', type=str, nargs='?', help='the ipc definition file', default='ipc7351B_smd_two_terminal_chip.yaml')
parser.add_argument('--ipc_definition', type=str, nargs='?', help='the ipc definition file', default='ipc7351B_smd_two_terminal.yaml')
parser.add_argument('--ipc_density', type=str, nargs='?', help='IPC density level (L,N,M)')
parser.add_argument('--force_rectangle_pads', action='store_true', help='Force the generation of rectangle pads instead of rounded rectangle (KiCad 4.x compatibility.)')
args = parser.parse_args()

# if the user requests an IPC density, put that and footprint suffix in a list
# otherwise, use nominal density with no suffix
if args.ipc_density is None or args.ipc_density not in ['l', 'L', 'n', 'N', 'm', 'M']:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if args.ipc_density is None or args.ipc_density not in ['l', 'L', 'n', 'N', 'm', 'M']:
if args.ipc_density is None or args.ipc_density.lower() not in ['l', 'n', 'm']:

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's an even better way to do this. I believed this could be improved but my brain was feeling worn out as I mentioned above; hopefully now inspiration has struck.

ipc_density = ['nominal', '']
else:
if args.ipc_density.upper() == 'L':
ipc_density = ['least', '_L']
elif args.ipc_density.upper() == 'N':
ipc_density = ['nominal', '_N']
elif args.ipc_density.upper() == 'M':
ipc_density = ['most', '_M']

with open(args.global_config, 'r') as config_stream:
try:
configuration = yaml.safe_load(config_stream)
Expand All @@ -351,10 +374,11 @@ def generateFootprint(self, device_size_data, footprint_group_data):
print(exc)
args = parser.parse_args()
configuration['ipc_definition'] = args.ipc_definition
configuration['ipc_density'] = ipc_density
if args.force_rectangle_pads:
configuration['round_rect_max_radius'] = None
configuration['round_rect_radius_ratio'] = 0

for filepath in args.files:
two_terminal_smd =TwoTerminalSMDchip(filepath, configuration)
two_terminal_smd = TwoTerminalSMD(filepath, configuration)
two_terminal_smd.generateFootprints()
Loading