Inital commit

This commit is contained in:
2026-05-06 23:45:52 +02:00
commit 26cbbd8ae8
16 changed files with 21248 additions and 0 deletions
+591
View File
@@ -0,0 +1,591 @@
// Copyright (c) 2023 Marco Massarelli
//
// SPDX-License-Identifier: CC-BY-NC-SA-4.0
//
// To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/
//
// Author: @infused-kim + @ceoloide improvements
//
// Description:
// A single-side or reversible footprint for the nice!nano (or any pro-micro compatible
// controller) that uses jumpers instead of two socket rows to be reversible.
//
// Note that the extra pins are *ONLY* compatible with nice!nano boards and not with
// clones like the Supermini, which has pins in a slightly different position.
//
// This is a re-implementation of the promicro_pretty footprint made popular
// by @benvallack.
//
// Pinout and schematics:
// https://nicekeyboards.com/docs/nice-nano/pinout-schematic
//
// Params:
// side: default is F for Front
// the side on which to place the single-side footprint and designator, either F or B
// reversible: default is false
// if true, the footprint will be placed on both sides so that the PCB can be
// reversible
// reverse_mount: default is false (MCU facing away from the PCB)
// if true, the sockets will be oriented so that the MCU faces the PCB (RAW / B+ is the
// top left pin). This is the most common mounting option for the nice!nano.
// When set to false, the pads will match the datasheet and assume the MCU faces away
// from the PCB (RAW / B+ is the top right pin).
// include_traces: default is true
// if true it will include traces that connect the jumper pads to the vias
// and the through-holes for the MCU
// include_extra_pins: default is false
// if true and if not reversible it will include nice!nano extra pin sockets (P1.01,
// P1.02, P1.07)
// only_required_jumpers: default is false
// if true, it will only place jumpers on the first 4 rows of pins, which can't be
// reversed in firmware, i.e. RAW and P1, GND and P0, GND and RST, GND and VCC.
// use_rectangular_jumpers: default is false
// if true, it will replace chevron-style jumpers with rectangual pads
// via_size: default is 0.8
// allows to define the size of the via. Not recommended below 0.56 (JLCPCB minimum),
// or above 0.8 (KiCad default), to avoid overlap or DRC errors.
// via_drill: default is 0.4
// allows to define the size of the drill. Not recommended below 0.3 (JLCPCB minimum),
// or above 0.4 (KiCad default), to avoid overlap or DRC errors.
// Pxx_label, VCC_label, RAW_label, GND_label, RST_label: default is ''
// allows to override the label for each pin
// mcu_3dmodel_filename: default is ''
// Allows you to specify the path to a 3D model STEP or WRL file to be
// used when rendering the PCB. Use the ${VAR_NAME} syntax to point to
// a KiCad configured path.
// mcu_3dmodel_xyz_offset: default is [0, 0, 0]
// xyz offset (in mm), used to adjust the position of the 3d model
// relative the footprint.
// mcu_3dmodel_xyz_scale: default is [1, 1, 1]
// xyz scale, used to adjust the size of the 3d model relative to its
// original size.
// mcu_3dmodel_xyz_rotation: default is [0, 0, 0]
// xyz rotation (in degrees), used to adjust the orientation of the 3d
// model relative the footprint.
//
// @infused-kim's improvements:
// - Use real traces instead of pads, which gets rid of hundreds of DRC errors.
// - Leave more space between the vias to allow easier routing through the middle
// of the footprint
//
// @ceoloide's improvements:
// - Move vias closer to the pads to clear up more space for silkscreen
// - Add ability to use rectangular jumpers instead of chevron-style
// - Add ability to control via size, to free up space for routing if needed
// - Add ability to only have required jumpers and let the rest be handled in firmware
// - Add single side (non-reversible) support
// - Add ability to mount with MCU facing towards or away from PCB
// - Add ability to show silkscreen labels on both sides for single side footprint
// - Add extra pins (P1.01, P1.02, P1.07) when footprint is single-side or reversible
// (only required jumpers)
// - Upgrade to KiCad 8
//
// # Placement and soldering of jumpers
//
// The reversible footprint is meant to be used with jumpers on the
// OPPOSITE side of where the nice!nano (or pro-micro compatible board) is
// installed. The silkscreen labels will also match the board when read on
// the opposite side. This is to have all jumpers and components to solder on
// the same side, and be able to read the correct labels of the MCU to do
// tests with a multimeter.
//
// # Further credits
//
// The original footprint was created from scratch by @infused-kim, but was based on the ideas from
// these other footprints:
//
// https://github.com/Albert-IV/ergogen-contrib/blob/main/src/footprints/promicro_pretty.js
// https://github.com/50an6xy06r6n/keyboard_reversible.pretty
module.exports = {
params: {
designator: 'MCU',
side: 'F',
reversible: false,
reverse_mount: false,
include_traces: true,
include_extra_pins: false,
invert_jumpers_position: false,
only_required_jumpers: false,
use_rectangular_jumpers: false,
via_size: 0.8, // JLCPC min is 0.56 for 1-2 layer boards, KiCad defaults to 0.8
via_drill: 0.4, // JLCPC min is 0.3 for 1-2 layer boards, KiCad defaults to 0.4
show_instructions: true,
show_silk_labels: true,
show_silk_labels_on_both_sides: false,
show_via_labels: true,
mcu_3dmodel_filename: '',
mcu_3dmodel_xyz_offset: [0, 0, 0],
mcu_3dmodel_xyz_rotation: [0, 0, 0],
mcu_3dmodel_xyz_scale: [1, 1, 1],
RAW_label: '',
GND_label: '',
RST_label: '',
VCC_label: '',
P21_label: '',
P20_label: '',
P19_label: '',
P18_label: '',
P15_label: '',
P14_label: '',
P16_label: '',
P10_label: '',
P1_label: '',
P0_label: '',
P2_label: '',
P3_label: '',
P4_label: '',
P5_label: '',
P6_label: '',
P7_label: '',
P8_label: '',
P9_label: '',
P101_label: '',
P102_label: '',
P107_label: '',
RAW: { type: 'net', value: 'RAW' },
GND: { type: 'net', value: 'GND' },
RST: { type: 'net', value: 'RST' },
VCC: { type: 'net', value: 'VCC' },
P21: { type: 'net', value: 'P21' },
P20: { type: 'net', value: 'P20' },
P19: { type: 'net', value: 'P19' },
P18: { type: 'net', value: 'P18' },
P15: { type: 'net', value: 'P15' },
P14: { type: 'net', value: 'P14' },
P16: { type: 'net', value: 'P16' },
P10: { type: 'net', value: 'P10' },
P1: { type: 'net', value: 'P1' },
P0: { type: 'net', value: 'P0' },
P2: { type: 'net', value: 'P2' },
P3: { type: 'net', value: 'P3' },
P4: { type: 'net', value: 'P4' },
P5: { type: 'net', value: 'P5' },
P6: { type: 'net', value: 'P6' },
P7: { type: 'net', value: 'P7' },
P8: { type: 'net', value: 'P8' },
P9: { type: 'net', value: 'P9' },
P101: { type: 'net', value: 'P101' },
P102: { type: 'net', value: 'P102' },
P107: { type: 'net', value: 'P107' },
},
body: p => {
const get_pin_net_name = (p, pin_name) => {
return p[pin_name].name;
};
const get_pin_net_str = (p, pin_name) => {
return p[pin_name].str;
};
const get_pin_label_override = (p, pin_name) => {
let prop_name = `${pin_name}_label`;
return p[prop_name];
};
const get_pin_label = (p, pin_name) => {
let label = get_pin_label_override(p, pin_name);
if (label == '') {
label = get_pin_net_name(p, pin_name);
}
if (label === undefined) {
label = '""';
}
return label;
};
const gen_traces_row = (row_num) => {
const traces = `
(segment (start ${p.eaxy((p.use_rectangular_jumpers ? 4.58 : 4.775), -12.7 + (row_num * 2.54))}) (end ${p.eaxy(3.4, -12.7 + (row_num * 2.54))}) (width 0.25) (layer "F.Cu"))
(segment (start ${p.eaxy((p.use_rectangular_jumpers ? -4.58 : -4.775), -12.7 + (row_num * 2.54))}) (end ${p.eaxy(-3.4, -12.7 + (row_num * 2.54))}) (width 0.25) (layer "F.Cu"))
(segment (start ${p.eaxy(-7.62, -12.7 + (row_num * 2.54))}) (end ${p.eaxy(-5.5, -12.7 + (row_num * 2.54))}) (width 0.25) (layer "F.Cu"))
(segment (start ${p.eaxy(-7.62, -12.7 + (row_num * 2.54))}) (end ${p.eaxy(-5.5, -12.7 + (row_num * 2.54))}) (width 0.25) (layer "B.Cu"))
(segment (start ${p.eaxy(5.5, -12.7 + (row_num * 2.54))}) (end ${p.eaxy(7.62, -12.7 + (row_num * 2.54))}) (width 0.25) (layer "F.Cu"))
(segment (start ${p.eaxy(7.62, -12.7 + (row_num * 2.54))}) (end ${p.eaxy(5.5, -12.7 + (row_num * 2.54))}) (width 0.25) (layer "B.Cu"))
(segment (start ${p.eaxy(-2.604695, 0.23 + (row_num * 2.54) - 12.7)}) (end ${p.eaxy(3.17, 0.23 + (row_num * 2.54) - 12.7)}) (width 0.25) (layer "B.Cu"))
(segment (start ${p.eaxy(-4.775, 0 + (row_num * 2.54) - 12.7)}) (end ${p.eaxy(-4.425305, 0 + (row_num * 2.54) - 12.7)}) (width 0.25) (layer "B.Cu"))
(segment (start ${p.eaxy(-3.700305, 0.725 + (row_num * 2.54) - 12.7)}) (end ${p.eaxy(-3.099695, 0.725 + (row_num * 2.54) - 12.7)}) (width 0.25) (layer "B.Cu"))
(segment (start ${p.eaxy(-4.425305, 0 + (row_num * 2.54) - 12.7)}) (end ${p.eaxy(-3.700305, 0.725 + (row_num * 2.54) - 12.7)}) (width 0.25) (layer "B.Cu"))
(segment (start ${p.eaxy(-3.099695, 0.725 + (row_num * 2.54) - 12.7)}) (end ${p.eaxy(-2.604695, 0.23 + (row_num * 2.54) - 12.7)}) (width 0.25) (layer "B.Cu"))
(segment (start ${p.eaxy(4.775, 0 + (row_num * 2.54) - 12.7)}) (end ${p.eaxy(4.425305, 0 + (row_num * 2.54) - 12.7)}) (width 0.25) (layer "B.Cu"))
(segment (start ${p.eaxy(2.594695, -0.22 + (row_num * 2.54) - 12.7)}) (end ${p.eaxy(-3.18, -0.22 + (row_num * 2.54) - 12.7)}) (width 0.25) (layer "B.Cu"))
(segment (start ${p.eaxy(4.425305, 0 + (row_num * 2.54) - 12.7)}) (end ${p.eaxy(3.700305, -0.725 + (row_num * 2.54) - 12.7)}) (width 0.25) (layer "B.Cu"))
(segment (start ${p.eaxy(3.700305, -0.725 + (row_num * 2.54) - 12.7)}) (end ${p.eaxy(3.099695, -0.725 + (row_num * 2.54) - 12.7)}) (width 0.25) (layer "B.Cu"))
(segment (start ${p.eaxy(3.099695, -0.725 + (row_num * 2.54) - 12.7)}) (end ${p.eaxy(2.594695, -0.22 + (row_num * 2.54) - 12.7)}) (width 0.25) (layer "B.Cu"))
`
return traces
}
const gen_traces = () => {
let traces = '';
for (let i = 0; i < 12; i++) {
if (i < 4 || !p.only_required_jumpers) {
let row_traces = gen_traces_row(i)
traces += row_traces
}
}
return traces
}
const invert_pins = (p.side == 'B' && !p.reverse_mount && !p.reversible) || (p.side == 'F' && p.reverse_mount && !p.reversible) || (!p.reverse_mount && p.reversible)
const gen_socket_row = (row_num, pin_name_left, pin_name_right, show_via_labels, show_silk_labels) => {
const row_offset_y = 2.54 * row_num
const socket_hole_num_left = 24 - row_num
const socket_hole_num_right = 1 + row_num
const via_num_left = 124 - row_num
const via_num_right = 101 + row_num
const net_left = get_pin_net_str(p, pin_name_left)
const net_right = get_pin_net_str(p, pin_name_right)
const via_label_left = get_pin_label(p, pin_name_left)
const via_label_right = get_pin_label(p, pin_name_right)
// These are the silkscreen labels that will be printed on the PCB.
// If the footprint is reversible, they will be aligned with the pins
// on the opposite side of where the MCU board is mounted.
const net_silk_front_left = via_label_left
const net_silk_front_right = via_label_right
const net_silk_back_left = via_label_right
const net_silk_back_right = via_label_left
let socket_row_base = `
${''/* Socket Holes */}
(pad "${socket_hole_num_left}" thru_hole circle (at -7.62 ${-12.7 + row_offset_y} ${p.r}) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") ${p.reversible && (row_num < 4 || !p.only_required_jumpers) ? p.local_net(socket_hole_num_left).str : net_left})
(pad "${socket_hole_num_right}" thru_hole circle (at 7.62 ${-12.7 + row_offset_y} ${p.r}) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") ${p.reversible && (row_num < 4 || !p.only_required_jumpers) ? p.local_net(socket_hole_num_right).str : net_right})
`
let socket_row_vias = `
${''/* Inside VIAS */}
(pad "${via_num_left}" thru_hole circle (at -3.4 ${-12.7 + row_offset_y} ${p.r}) (size ${p.via_size} ${p.via_size}) (drill ${p.via_drill}) (layers "*.Cu" "*.Mask") ${net_left})
(pad "${via_num_right}" thru_hole circle (at 3.4 ${-12.7 + row_offset_y} ${p.r}) (size ${p.via_size} ${p.via_size}) (drill ${p.via_drill}) (layers "*.Cu" "*.Mask") ${net_right})
`
let socket_row_rectangular_jumpers = `
${''/* Jumper Pads - Front Left */}
(pad "${socket_hole_num_left}" smd rect (at -5.48 ${-12.7 + row_offset_y} ${p.r}) (size 0.6 1.2) (layers "F.Cu" "F.Paste" "F.Mask") ${p.local_net(socket_hole_num_left).str})
(pad "${via_num_left}" smd rect (at -4.58 ${-12.7 + row_offset_y} ${p.r}) (size 0.6 1.2) (layers "F.Cu" "F.Paste" "F.Mask") ${net_left})
${''/* Jumper Pads - Front Right */}
(pad "${via_num_right}" smd rect (at 4.58 ${-12.7 + row_offset_y} ${p.r}) (size 0.6 1.2) (layers "F.Cu" "F.Paste" "F.Mask") ${net_right})
(pad "${socket_hole_num_right}" smd rect (at 5.48 ${-12.7 + row_offset_y} ${p.r}) (size 0.6 1.2) (layers "F.Cu" "F.Paste" "F.Mask") ${p.local_net(socket_hole_num_right).str})
${''/* Jumper Pads - Back Left */}
(pad "${socket_hole_num_left}" smd rect (at -5.48 ${-12.7 + row_offset_y} ${p.r}) (size 0.6 1.2) (layers "B.Cu" "B.Paste" "B.Mask") ${p.local_net(socket_hole_num_left).str})
(pad "${via_num_right}" smd rect (at -4.58 ${-12.7 + row_offset_y} ${p.r}) (size 0.6 1.2) (layers "B.Cu" "B.Paste" "B.Mask") ${net_right})
${''/* Jumper Pads - Back Right */}
(pad "${via_num_left}" smd rect (at 4.58 ${-12.7 + row_offset_y} ${p.r}) (size 0.6 1.2) (layers "B.Cu" "B.Paste" "B.Mask") ${net_left})
(pad "${socket_hole_num_right}" smd rect (at 5.48 ${-12.7 + row_offset_y} ${p.r}) (size 0.6 1.2) (layers "B.Cu" "B.Paste" "B.Mask") ${p.local_net(socket_hole_num_right).str})
`
let socket_row_chevron_jumpers = `
${''/* Jumper Pads - Front Left */}
(pad "${socket_hole_num_left}" smd custom (at -5.5 ${-12.7 + row_offset_y} ${p.r}) (size 0.2 0.2) (layers "F.Cu" "F.Paste" "F.Mask") ${p.local_net(socket_hole_num_left).str}
(zone_connect 2)
(options (clearance outline) (anchor rect))
(primitives
(gr_poly (pts
(xy -0.5 -0.625) (xy -0.25 -0.625) (xy 0.25 0) (xy -0.25 0.625) (xy -0.5 0.625)
) (width 0) (fill yes))
))
(pad "${via_num_left}" smd custom (at -4.775 ${-12.7 + row_offset_y} ${p.r}) (size 0.2 0.2) (layers "F.Cu" "F.Paste" "F.Mask") ${net_left}
(zone_connect 2)
(options (clearance outline) (anchor rect))
(primitives
(gr_poly (pts
(xy -0.65 -0.625) (xy 0.5 -0.625) (xy 0.5 0.625) (xy -0.65 0.625) (xy -0.15 0)
) (width 0) (fill yes))
))
${''/* Jumper Pads - Front Right */}
(pad "${via_num_right}" smd custom (at 4.775 ${-12.7 + row_offset_y} ${180 + p.r}) (size 0.2 0.2) (layers "F.Cu" "F.Paste" "F.Mask") ${net_right}
(zone_connect 2)
(options (clearance outline) (anchor rect))
(primitives
(gr_poly (pts
(xy -0.65 -0.625) (xy 0.5 -0.625) (xy 0.5 0.625) (xy -0.65 0.625) (xy -0.15 0)
) (width 0) (fill yes))
))
(pad "${socket_hole_num_right}" smd custom (at 5.5 ${-12.7 + row_offset_y} ${180 + p.r}) (size 0.2 0.2) (layers "F.Cu" "F.Paste" "F.Mask") ${p.local_net(socket_hole_num_right).str}
(zone_connect 2)
(options (clearance outline) (anchor rect))
(primitives
(gr_poly (pts
(xy -0.5 -0.625) (xy -0.25 -0.625) (xy 0.25 0) (xy -0.25 0.625) (xy -0.5 0.625)
) (width 0) (fill yes))
))
${''/* Jumper Pads - Back Left */}
(pad "${socket_hole_num_left}" smd custom (at -5.5 ${-12.7 + row_offset_y} ${p.r}) (size 0.2 0.2) (layers "B.Cu" "B.Paste" "B.Mask") ${p.local_net(socket_hole_num_left).str}
(zone_connect 2)
(options (clearance outline) (anchor rect))
(primitives
(gr_poly (pts
(xy -0.5 0.625) (xy -0.25 0.625) (xy 0.25 0) (xy -0.25 -0.625) (xy -0.5 -0.625)
) (width 0) (fill yes))
))
(pad "${via_num_right}" smd custom (at -4.775 ${-12.7 + row_offset_y} ${p.r}) (size 0.2 0.2) (layers "B.Cu" "B.Paste" "B.Mask") ${net_right}
(zone_connect 2)
(options (clearance outline) (anchor rect))
(primitives
(gr_poly (pts
(xy -0.65 0.625) (xy 0.5 0.625) (xy 0.5 -0.625) (xy -0.65 -0.625) (xy -0.15 0)
) (width 0) (fill yes))
))
${''/* Jumper Pads - Back Right */}
(pad "${via_num_left}" smd custom (at 4.775 ${-12.7 + row_offset_y} ${180 + p.r}) (size 0.2 0.2) (layers "B.Cu" "B.Paste" "B.Mask") ${net_left}
(zone_connect 2)
(options (clearance outline) (anchor rect))
(primitives
(gr_poly (pts
(xy -0.65 0.625) (xy 0.5 0.625) (xy 0.5 -0.625) (xy -0.65 -0.625) (xy -0.15 0)
) (width 0) (fill yes))
))
(pad "${socket_hole_num_right}" smd custom (at 5.5 ${-12.7 + row_offset_y} ${180 + p.r}) (size 0.2 0.2) (layers "B.Cu" "B.Paste" "B.Mask") ${p.local_net(socket_hole_num_right).str}
(zone_connect 2)
(options (clearance outline) (anchor rect))
(primitives
(gr_poly (pts
(xy -0.5 0.625) (xy -0.25 0.625) (xy 0.25 0) (xy -0.25 -0.625) (xy -0.5 -0.625)
) (width 0) (fill yes))
))
`
let socket_row = socket_row_base;
if (p.reversible && (row_num < 4 || !p.only_required_jumpers)) {
socket_row += socket_row_vias;
if (p.use_rectangular_jumpers) {
socket_row += socket_row_rectangular_jumpers
} else {
socket_row += socket_row_chevron_jumpers
}
}
if (show_silk_labels == true) {
if (p.reversible || p.show_silk_labels_on_both_sides || p.side == 'F') {
// Silkscreen labels - front
if (row_num != 9
|| !p.include_extra_pins
|| (p.include_extra_pins && invert_pins && !p.reversible)
|| (p.include_extra_pins && !p.only_required_jumpers && p.reversible)
) {
socket_row += `
(fp_text user "${net_silk_front_left}" (at -${p.reversible && (row_num < 4 || !p.only_required_jumpers) ? (net_silk_front_left.length > 2 ? 1.45 : 2.04) : 4.47} ${-12.7 + row_offset_y} ${p.r}) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
)
`
}
if (row_num != 9
|| !p.include_extra_pins
|| (p.include_extra_pins && !invert_pins && !p.reversible)
|| (p.include_extra_pins && !p.only_required_jumpers && p.reversible)
) {
socket_row += `
(fp_text user "${net_silk_front_right}" (at ${p.reversible && (row_num < 4 || !p.only_required_jumpers) ? (net_silk_front_right.length > 2 ? 1.45 : 2.04) : 4.47} ${-12.7 + row_offset_y} ${p.r}) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
)
`
}
}
if (p.reversible|| p.show_silk_labels_on_both_sides || p.side == 'B') {
// Silkscreen labels - back
if (row_num != 9
|| !p.include_extra_pins
|| (p.include_extra_pins && !invert_pins && !p.reversible)
|| (p.include_extra_pins && !p.only_required_jumpers && p.reversible)
) {
socket_row += `
(fp_text user "${net_silk_back_left}" (at ${p.reversible ? '-' : ''}${p.reversible && (row_num < 4 || !p.only_required_jumpers) ? (net_silk_back_left.length > 2 ? 1.45 : 2.04) : 4.47} ${-12.7 + row_offset_y} ${p.r}) (layer "B.SilkS")
(effects (font (size 1 1) (thickness 0.15)) (justify mirror))
)
`
}
if (row_num != 9
|| !p.include_extra_pins
|| (p.include_extra_pins && invert_pins && !p.reversible)
|| (p.include_extra_pins && !p.only_required_jumpers && p.reversible)
) {
socket_row += `
(fp_text user "${net_silk_back_right}" (at ${p.reversible ? '' : '-'}${p.reversible && (row_num < 4 || !p.only_required_jumpers) ? (net_silk_back_right.length > 2 ? 1.45 : 2.04) : 4.47} ${-12.7 + row_offset_y} ${p.r}) (layer "B.SilkS")
(effects (font (size 1 1) (thickness 0.15)) (justify mirror))
)
`
}
}
}
if (show_via_labels && (p.reversible && (row_num < 4 || !p.only_required_jumpers))) {
socket_row += `
${''/* Via Labels - Front */}
(fp_text user "${via_label_left}" (at -3.262 ${-13.5 + row_offset_y} ${p.r}) (layer "F.Fab")
(effects (font (size 0.5 0.5) (thickness 0.08)))
)
(fp_text user "${via_label_right}" (at 3.262 ${-13.5 + row_offset_y} ${p.r}) (layer "F.Fab")
(effects (font (size 0.5 0.5) (thickness 0.08)))
)
${''/* Via Labels - Back */}
(fp_text user "${via_label_left}" (at -3.262 ${-13.5 + row_offset_y} ${180 + p.r}) (layer "B.Fab")
(effects (font (size 0.5 0.5) (thickness 0.08)) (justify mirror))
)
(fp_text user "${via_label_right}" (at 3.262 ${-13.5 + row_offset_y} ${180 + p.r}) (layer "B.Fab")
(effects (font (size 0.5 0.5) (thickness 0.08)) (justify mirror))
)
`
}
return socket_row
}
const gen_socket_rows = (show_via_labels, show_silk_labels) => {
const pin_names = [
// The pin matrix below assumes PCB is mounted with the MCU
// facing away from the PCB (reverse_mount = false) on the
// Front side. It should be inverted for reverse_mount = true
// or when mounted on teh Back
['P1', 'RAW'],
['P0', 'GND'],
['GND', 'RST'],
['GND', 'VCC'],
['P2', 'P21'],
['P3', 'P20'],
['P4', 'P19'],
['P5', 'P18'],
['P6', 'P15'],
['P7', 'P14'],
['P8', 'P16'],
['P9', 'P10'],
]
let socket_rows = '';
for (let i = 0; i < pin_names.length; i++) {
let pin_name_left = pin_names[i][invert_pins ? 1 : 0]
let pin_name_right = pin_names[i][invert_pins ? 0 : 1]
const socket_row = gen_socket_row(
i, pin_name_left, pin_name_right,
show_via_labels, show_silk_labels
)
socket_rows += socket_row
}
// Socket silkscreen
// P1 / D1 / P0.06 is marked according to orientation
if (show_silk_labels == true) {
if (p.reversible || p.show_silk_labels_on_both_sides || p.side == 'F') {
socket_rows += `
(fp_line (start 6.29 -14.03) (end 8.95 -14.03) (layer "F.SilkS") (stroke (width 0.12) (type solid)))
(fp_line (start 6.29 -14.03) (end 6.29 16.57) (layer "F.SilkS") (stroke (width 0.12) (type solid)))
(fp_line (start 6.29 16.57) (end 8.95 16.57) (layer "F.SilkS") (stroke (width 0.12) (type solid)))
(fp_line (start -6.29 -14.03) (end -6.29 16.57) (layer "F.SilkS") (stroke (width 0.12) (type solid)))
(fp_line (start 8.95 -14.03) (end 8.95 16.57) (layer "F.SilkS") (stroke (width 0.12) (type solid)))
(fp_line (start -8.95 -14.03) (end -6.29 -14.03) (layer "F.SilkS") (stroke (width 0.12) (type solid)))
(fp_line (start -8.95 -14.03) (end -8.95 16.57) (layer "F.SilkS") (stroke (width 0.12) (type solid)))
(fp_line (start -8.95 16.57) (end -6.29 16.57) (layer "F.SilkS") (stroke (width 0.12) (type solid)))
(fp_line (start ${invert_pins ? '' : '-'}6.29 -11.43) (end ${invert_pins ? '' : '-'}8.95 -11.43) (layer "F.SilkS") (stroke (width 0.12) (type solid)))
`
}
if (p.reversible || p.show_silk_labels_on_both_sides || p.side == 'B') {
socket_rows += `
(fp_line (start -6.29 -14.03) (end -8.95 -14.03) (layer "B.SilkS") (stroke (width 0.12) (type solid)))
(fp_line (start -6.29 -14.03) (end -6.29 16.57) (layer "B.SilkS") (stroke (width 0.12) (type solid)))
(fp_line (start -6.29 16.57) (end -8.95 16.57) (layer "B.SilkS") (stroke (width 0.12) (type solid)))
(fp_line (start -8.95 -14.03) (end -8.95 16.57) (layer "B.SilkS") (stroke (width 0.12) (type solid)))
(fp_line (start 8.95 -14.03) (end 6.29 -14.03) (layer "B.SilkS") (stroke (width 0.12) (type solid)))
(fp_line (start 8.95 -14.03) (end 8.95 16.57) (layer "B.SilkS") (stroke (width 0.12) (type solid)))
(fp_line (start 8.95 16.57) (end 6.29 16.57) (layer "B.SilkS") (stroke (width 0.12) (type solid)))
(fp_line (start 6.29 -14.03) (end 6.29 16.57) (layer "B.SilkS") (stroke (width 0.12) (type solid)))
(fp_line (start ${invert_pins ? (p.reversible ? '-' : '') : (p.reversible ? '' : '-')}8.95 -11.43) (end ${invert_pins ? (p.reversible ? '-' : '') : (p.reversible ? '' : '-')}6.29 -11.43) (layer "B.SilkS") (stroke (width 0.12) (type solid)))
`
}
}
return socket_rows
}
const common_top = `
(footprint "ceoloide:mcu_nice_nano"
(layer "${p.side}.Cu")
${p.at}
(property "Reference" "${p.ref}"
(at 0 -15 ${p.r})
(layer "${p.side}.SilkS")
${p.ref_hide}
(effects (font (size 1 1) (thickness 0.15)))
)
(attr exclude_from_pos_files exclude_from_bom)
${''/* USB socket outline */}
(fp_line (start 3.556 -18.034) (end 3.556 -16.51) (layer "Dwgs.User") (stroke (width 0.15) (type solid)))
(fp_line (start -3.81 -16.51) (end -3.81 -18.034) (layer "Dwgs.User") (stroke (width 0.15) (type solid)))
(fp_line (start -3.81 -18.034) (end 3.556 -18.034) (layer "Dwgs.User") (stroke (width 0.15) (type solid)))
${''/* Controller outline */}
(fp_line (start -8.89 -16.51) (end 8.89 -16.51) (layer "Dwgs.User") (stroke (width 0.15) (type solid)))
(fp_line (start -8.89 -16.51) (end -8.89 16.57) (layer "Dwgs.User") (stroke (width 0.15) (type solid)))
(fp_line (start 8.89 -16.51) (end 8.89 16.57) (layer "Dwgs.User") (stroke (width 0.15) (type solid)))
(fp_line (start -8.89 16.57) (end 8.89 16.57) (layer "Dwgs.User") (stroke (width 0.15) (type solid)))
`;
const instructions = `
(fp_text user "R hand back side (M${!p.reverse_mount ? '↑' : '↓'})" (at 0 -15.245 ${p.r}) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text user "L hand back side (M${!p.reverse_mount ? '↑' : '↓'})" (at 0 -15.245 ${p.r}) (layer "B.SilkS")
(effects (font (size 1 1) (thickness 0.15)) (justify mirror))
)
`
const socket_rows = gen_socket_rows(
p.show_via_labels, p.show_silk_labels
)
const traces = gen_traces()
const extra_pins = `
(pad "25" thru_hole circle (at ${invert_pins ? '' : '-'}5.08 10.16 ${p.r}) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") ${p.P101})
(pad "26" thru_hole circle (at ${invert_pins ? '' : '-'}2.54 10.16 ${p.r}) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") ${p.P102})
(pad "27" thru_hole circle (at 0 10.16 ${p.r}) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") ${p.P107})
`
const extra_pins_reversible = `
(pad "28" thru_hole circle (at ${invert_pins ? '-' : ''}5.08 10.16 ${p.r}) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") ${p.P101})
(pad "29" thru_hole circle (at ${invert_pins ? '-' : ''}2.54 10.16 ${p.r}) (size 1.7 1.7) (drill 1) (layers "*.Cu" "*.Mask") ${p.P102})
`
const mcu_3dmodel = `
(model ${p.mcu_3dmodel_filename}
(offset (xyz ${p.mcu_3dmodel_xyz_offset[0]} ${p.mcu_3dmodel_xyz_offset[1]} ${p.mcu_3dmodel_xyz_offset[2]}))
(scale (xyz ${p.mcu_3dmodel_xyz_scale[0]} ${p.mcu_3dmodel_xyz_scale[1]} ${p.mcu_3dmodel_xyz_scale[2]}))
(rotate (xyz ${p.mcu_3dmodel_xyz_rotation[0]} ${p.mcu_3dmodel_xyz_rotation[1]} ${p.mcu_3dmodel_xyz_rotation[2]}))
)
`
return `
${''/* Controller*/}
${common_top}
${socket_rows}
${p.include_extra_pins && (!p.reversible || (p.reversible && p.only_required_jumpers)) ? extra_pins : ''}
${p.include_extra_pins && p.reversible && p.only_required_jumpers ? extra_pins_reversible : ''}
${p.reversible && p.show_instructions ? instructions : ''}
${p.mcu_3dmodel_filename ? mcu_3dmodel : ''}
)
${''/* Traces */}
${p.reversible && p.include_traces ? traces : ''}
`;
}
}
+31
View File
@@ -0,0 +1,31 @@
// MountingHole_2.2mm_M2_Pad_Via
// TODO add more sizes as param?
module.exports = {
nets: {
net: undefined
},
params: {
class: 'HOLE',
},
body: p => `
(module "MountingHole_2.2mm_M2_Pad_Via" (version 20210722) (generator pcbnew) (layer "F.Cu")
(tedit 56DDB9C7)
${p.at /* parametric position */}
(fp_text reference "${p.ref}" (at 0 -3.2) (layer "F.SilkS") ${p.ref_hide}
(effects (font (size 1 1) (thickness 0.15)))
(tstamp b68bb25c-687d-44b1-b966-dad4cac66b35)
)
(fp_circle (center 0 0) (end 2.45 0) (layer "F.CrtYd") (width 0.05) (fill none) (tstamp b2688462-c375-45d3-9095-3425fb17c88f))
(pad "1" thru_hole circle locked (at 1.166726 1.166726) (size 0.7 0.7) (drill 0.4) (layers *.Cu *.Mask) (tstamp 2a7fc905-328f-4bbb-9222-ca8d15d03a86))
(pad "1" thru_hole circle locked (at 0 0) (size 4.4 4.4) (drill 2.2) (layers *.Cu *.Mask) (tstamp 47ee1d53-0551-4b6d-bc24-3f3f14c73c36))
(pad "1" thru_hole circle locked (at 0 1.65) (size 0.7 0.7) (drill 0.4) (layers *.Cu *.Mask) (tstamp 4eef65bc-4add-40d7-8319-14dcdbae0d44))
(pad "1" thru_hole circle locked (at 1.166726 -1.166726) (size 0.7 0.7) (drill 0.4) (layers *.Cu *.Mask) (tstamp 56155f4d-2ebc-4ad4-8d82-7aa7846deba8))
(pad "1" thru_hole circle locked (at -1.65 0) (size 0.7 0.7) (drill 0.4) (layers *.Cu *.Mask) (tstamp 787d6162-1d3c-4def-859e-6532ce27c1ef))
(pad "1" thru_hole circle locked (at -1.166726 -1.166726) (size 0.7 0.7) (drill 0.4) (layers *.Cu *.Mask) (tstamp 8d699d12-7099-4814-bbe6-11bc74c6e8b2))
(pad "1" thru_hole circle locked (at -1.166726 1.166726) (size 0.7 0.7) (drill 0.4) (layers *.Cu *.Mask) (tstamp 95ab0420-a56b-46ee-98ad-5072a1a93a6f))
(pad "1" thru_hole circle locked (at 1.65 0) (size 0.7 0.7) (drill 0.4) (layers *.Cu *.Mask) (tstamp cde0acf2-b3b4-46de-9f6e-3ab519744000))
(pad "1" thru_hole circle locked (at 0 -1.65) (size 0.7 0.7) (drill 0.4) (layers *.Cu *.Mask) (tstamp ff0de415-ae11-46fb-b780-c24aee621212))
)`
}
+158
View File
@@ -0,0 +1,158 @@
// Nice!NanoV2
// Params
// orientation: default is down
// if down, power led will face the pcb
// if up, power led will face away from pcb
module.exports = {
params: {
designator: 'MCU',
orientation: 'down',
RAW: {type: 'net', value: 'RAW'},
GND: {type: 'net', value: 'GND'},
RST: {type: 'net', value: 'RST'},
VCC: {type: 'net', value: 'VCC'},
P031: {type: 'net', value: 'P031'},
P029: {type: 'net', value: 'P029'},
P002: {type: 'net', value: 'P002'},
P115: {type: 'net', value: 'P115'},
P113: {type: 'net', value: 'P113'},
P111: {type: 'net', value: 'P111'},
P010: {type: 'net', value: 'P010'},
P009: {type: 'net', value: 'P009'},
P006: {type: 'net', value: 'P006'},
P008: {type: 'net', value: 'P008'},
P017: {type: 'net', value: 'P017'},
P020: {type: 'net', value: 'P020'},
P022: {type: 'net', value: 'P022'},
P024: {type: 'net', value: 'P024'},
P100: {type: 'net', value: 'P100'},
P011: {type: 'net', value: 'P011'},
P104: {type: 'net', value: 'P104'},
P106: {type: 'net', value: 'P106'},
P101: {type: 'net', value: 'P101'},
P102: {type: 'net', value: 'P102'},
P107: {type: 'net', value: 'P107'}
},
body: p => {
const standard = `
(module nice_nano (layer F.Cu) (tedit 6058B206)
${p.at /* parametric position */}
${'' /* footprint reference */}
(fp_text reference "${p.ref}" (at 0 0) (layer F.SilkS) ${p.ref_hide} (effects (font (size 1.2 1.2) (thickness 0.2032))))
(fp_text value nice_nano (at 0 0) (layer F.SilkS) hide (effects (font (size 1.2 1.2) (thickness 0.2032))))
${''/* illustration of the (possible) USB port overhang */}
(fp_line (start -14.224 -3.556) (end -14.224 3.81) (layer Dwgs.User) (width 0.2))
(fp_line (start -14.224 3.81) (end -19.304 3.81) (layer Dwgs.User) (width 0.2))
(fp_line (start -19.304 3.81) (end -19.304 -3.556) (layer Dwgs.User) (width 0.2))
(fp_line (start -19.304 -3.556) (end -14.224 -3.556) (layer Dwgs.User) (width 0.2))
${''/* component outline */}
(fp_line (start 15.24 -8.89) (end -17.78 -8.89) (layer F.SilkS) (width 0.381))
(fp_line (start 15.24 8.89) (end 15.24 -8.89) (layer F.SilkS) (width 0.381))
(fp_line (start -17.78 8.89) (end 15.24 8.89) (layer F.SilkS) (width 0.381))
(fp_line (start -17.78 -8.89) (end -17.78 8.89) (layer F.SilkS) (width 0.381))
(fp_line (start 15.24 -8.89) (end -17.78 -8.89) (layer B.SilkS) (width 0.381))
(fp_line (start 15.24 8.89) (end 15.24 -8.89) (layer B.SilkS) (width 0.381))
(fp_line (start -17.78 8.89) (end 15.24 8.89) (layer B.SilkS) (width 0.381))
(fp_line (start -17.78 -8.89) (end -17.78 8.89) (layer B.SilkS) (width 0.381))
`
function pins(def_neg, def_pos) {
return `
${''/* pin names */}
(fp_text user RAW (at -13.97 ${def_pos}5.473715 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user GND (at -11.43 ${def_pos}5.454667 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user RST (at -8.89 ${def_pos}5.588 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user VCC (at -6.35 ${def_pos}5.537191 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user 031 (at -3.81 ${def_pos}5.537191 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user 029 (at -1.27 ${def_pos}5.537191 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user 002 (at 1.27 ${def_pos}5.537191 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user 115 (at 3.81 ${def_pos}5.537191 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user 113 (at 6.35 ${def_pos}5.537191 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user 111 (at 8.89 ${def_pos}5.537191 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user 010 (at 11.43 ${def_pos}5.537191 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user 006 (at -13.97 ${def_neg}5.53719 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user 008 (at -11.5 ${def_neg}5.53719 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user GND (at -8.89 ${def_neg}5.461 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user GND (at -6.35 ${def_neg}5.461 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user 017 (at -3.8 ${def_neg}5.53719 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user 020 (at -1.2 ${def_neg}5.53719 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user 022 (at 1.3 ${def_neg}5.53719 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user 024 (at 3.81 ${def_neg}5.53719 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user 100 (at 6.35 ${def_neg}5.53719 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user 104 (at 11.43 ${def_neg}5.53719 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
(fp_text user RAW (at -13.97 ${def_pos}5.473715 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user GND (at -11.43 ${def_pos}5.454667 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user RST (at -8.89 ${def_pos}5.588 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user VCC (at -6.35 ${def_pos}5.537191 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user 031 (at -3.81 ${def_pos}5.537191 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user 029 (at -1.27 ${def_pos}5.537191 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user 002 (at 1.27 ${def_pos}5.537191 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user 115 (at 3.81 ${def_pos}5.537191 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user 113 (at 6.35 ${def_pos}5.537191 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user 111 (at 8.89 ${def_pos}5.537191 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user 010 (at 11.43 ${def_pos}5.537191 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user 006 (at -13.97 ${def_neg}5.53719 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user 008 (at -11.5 ${def_neg}5.53719 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user GND (at -8.89 ${def_neg}5.461 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user GND (at -6.35 ${def_neg}5.461 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user 017 (at -3.8 ${def_neg}5.53719 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user 020 (at -1.2 ${def_neg}5.53719 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user 022 (at 1.3 ${def_neg}5.53719 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user 024 (at 3.81 ${def_neg}5.53719 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user 100 (at 6.35 ${def_neg}5.53719 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user 104 (at 11.43 ${def_neg}5.53719 ${p.rot + 90}) (layer B.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)))
(fp_text user nice!nano (at 13.462 ${def_pos}0.254 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 1.5 1.5) (thickness 0.3))))
${''/* and now the actual pins */}
(pad 1 thru_hole circle (at -13.97 ${def_neg}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P006.str})
(pad 2 thru_hole circle (at -11.43 ${def_neg}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P008.str})
(pad 3 thru_hole circle (at -8.89 ${def_neg}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.GND.str})
(pad 4 thru_hole circle (at -6.35 ${def_neg}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.GND.str})
(pad 5 thru_hole circle (at -3.81 ${def_neg}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P017.str})
(pad 6 thru_hole circle (at -1.27 ${def_neg}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P020.str})
(pad 7 thru_hole circle (at 1.27 ${def_neg}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P022.str})
(pad 8 thru_hole circle (at 3.81 ${def_neg}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P024.str})
(pad 9 thru_hole circle (at 6.35 ${def_neg}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P100.str})
(pad 10 thru_hole circle (at 8.89 ${def_neg}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P011.str})
(pad 11 thru_hole circle (at 11.43 ${def_neg}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P104.str})
(pad 12 thru_hole circle (at 13.97 ${def_neg}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P106.str})
(pad 13 thru_hole circle (at 13.97 ${def_pos}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P009.str})
(pad 14 thru_hole circle (at 11.43 ${def_pos}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P010.str})
(pad 15 thru_hole circle (at 8.89 ${def_pos}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P111.str})
(pad 16 thru_hole circle (at 6.35 ${def_pos}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P113.str})
(pad 17 thru_hole circle (at 3.81 ${def_pos}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P115.str})
(pad 18 thru_hole circle (at 1.27 ${def_pos}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P002.str})
(pad 19 thru_hole circle (at -1.27 ${def_pos}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P029.str})
(pad 20 thru_hole circle (at -3.81 ${def_pos}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P031.str})
(pad 21 thru_hole circle (at -6.35 ${def_pos}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.VCC.str})
(pad 22 thru_hole circle (at -8.89 ${def_pos}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.RST.str})
(pad 23 thru_hole circle (at -11.43 ${def_pos}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.GND.str})
(pad 24 thru_hole circle (at -13.97 ${def_pos}7.62) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.RAW.str})
(pad 31 thru_hole circle (at 8.89 5.08) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P101.str})
(pad 32 thru_hole circle (at 8.89 2.54) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P102.str})
(pad 33 thru_hole circle (at 8.89 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.P107.str})
`
}
if(p.orientation == 'down') {
return `
${standard}
${pins('-', '')})
`
} else {
return `
${standard}
${pins('', '-')})
`
}
}
}