From f71368b8352a3518a6acd82a3428e12f0ec7d8b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1n=20D=C3=A9nes?= Date: Sat, 18 Jul 2020 22:58:44 +0200 Subject: [PATCH] A shitload of PCB progress --- src/assert.js | 1 + src/footprints/alps.js | 25 +++ src/footprints/choc.js | 32 ++++ src/footprints/diode.js | 23 +-- src/footprints/index.js | 5 +- src/footprints/mx.js | 9 +- src/footprints/pad.js | 35 ++++ src/footprints/promicro.js | 125 ++++++------ src/outlines.js | 24 ++- src/pcbs.js | 34 ++-- src/utils.js | 2 +- test/fixtures/absolem.yaml | 379 ++++++++++++++++++++++++++++++++----- 12 files changed, 541 insertions(+), 153 deletions(-) create mode 100644 src/footprints/alps.js create mode 100644 src/footprints/choc.js create mode 100644 src/footprints/pad.js diff --git a/src/assert.js b/src/assert.js index fb0f80b..456155a 100644 --- a/src/assert.js +++ b/src/assert.js @@ -95,6 +95,7 @@ const extend_pair = exports.extend_pair = (to, from) => { const res = u.deepcopy(to) for (const key of Object.keys(from)) { res[key] = extend_pair(to[key], from[key]) + if (res[key] === undefined) delete res[key] } return res } else if (from_type == 'array') { diff --git a/src/footprints/alps.js b/src/footprints/alps.js new file mode 100644 index 0000000..708e85e --- /dev/null +++ b/src/footprints/alps.js @@ -0,0 +1,25 @@ +module.exports = { + nets: ['from', 'to'], + body: p => ` + + (module ALPS (layer F.Cu) (tedit 5CF31DEF) + + ${p.at /* parametric position */} + + ${''/* corner marks */} + (fp_line (start -7 -6) (end -7 -7) (layer F.SilkS) (width 0.15)) + (fp_line (start -7 7) (end -6 7) (layer F.SilkS) (width 0.15)) + (fp_line (start -6 -7) (end -7 -7) (layer F.SilkS) (width 0.15)) + (fp_line (start -7 7) (end -7 6) (layer F.SilkS) (width 0.15)) + (fp_line (start 7 6) (end 7 7) (layer F.SilkS) (width 0.15)) + (fp_line (start 7 -7) (end 6 -7) (layer F.SilkS) (width 0.15)) + (fp_line (start 6 7) (end 7 7) (layer F.SilkS) (width 0.15)) + (fp_line (start 7 -7) (end 7 -6) (layer F.SilkS) (width 0.15)) + + ${''/* pins */} + (pad 1 thru_hole circle (at 2.5 -4.5) (size 2.25 2.25) (drill 1.47) (layers *.Cu *.Mask) ${p.net_from}) + (pad 2 thru_hole circle (at -2.5 -4) (size 2.25 2.25) (drill 1.47) (layers *.Cu *.Mask) ${p.net_to}) + ) + + ` +} \ No newline at end of file diff --git a/src/footprints/choc.js b/src/footprints/choc.js new file mode 100644 index 0000000..b2c4fb7 --- /dev/null +++ b/src/footprints/choc.js @@ -0,0 +1,32 @@ +module.exports = { + nets: ['from', 'to'], + body: p => ` + + (module PG1350 (layer F.Cu) (tedit 5DD50112) + + ${p.at /* parametric position */} + + ${''/* corner marks */} + (fp_line (start -7 -6) (end -7 -7) (layer F.SilkS) (width 0.15)) + (fp_line (start -7 7) (end -6 7) (layer F.SilkS) (width 0.15)) + (fp_line (start -6 -7) (end -7 -7) (layer F.SilkS) (width 0.15)) + (fp_line (start -7 7) (end -7 6) (layer F.SilkS) (width 0.15)) + (fp_line (start 7 6) (end 7 7) (layer F.SilkS) (width 0.15)) + (fp_line (start 7 -7) (end 6 -7) (layer F.SilkS) (width 0.15)) + (fp_line (start 6 7) (end 7 7) (layer F.SilkS) (width 0.15)) + (fp_line (start 7 -7) (end 7 -6) (layer F.SilkS) (width 0.15)) + + ${''/* pins */} + (pad 1 thru_hole circle (at 0 -5.9) (size 2.032 2.032) (drill 1.27) (layers *.Cu *.Mask) ${p.net_from}) + (pad 2 thru_hole circle (at -5 -3.8) (size 2.032 2.032) (drill 1.27) (layers *.Cu *.Mask) ${p.net_to}) + + ${''/* middle shaft */} + (pad "" np_thru_hole circle (at 0 0) (size 3.429 3.429) (drill 3.429) (layers *.Cu *.Mask)) + + ${''/* stabilizers */} + (pad "" np_thru_hole circle (at 5.5 0) (size 1.7018 1.7018) (drill 1.7018) (layers *.Cu *.Mask)) + (pad "" np_thru_hole circle (at -5.5 0) (size 1.7018 1.7018) (drill 1.7018) (layers *.Cu *.Mask)) + ) + + ` +} \ No newline at end of file diff --git a/src/footprints/diode.js b/src/footprints/diode.js index 7711e4c..1c91063 100644 --- a/src/footprints/diode.js +++ b/src/footprints/diode.js @@ -1,12 +1,11 @@ module.exports = { nets: ['from', 'to'], - body: ` + body: p => ` (module ComboDiode (layer F.Cu) (tedit 5B24D78E) - ${''/* parametric position */} - __AT + ${p.at /* parametric position */} ${''/* diode symbols */} (fp_line (start 0.25 0) (end 0.75 0) (layer F.SilkS) (width 0.1)) @@ -24,20 +23,16 @@ module.exports = { (fp_line (start -0.35 0) (end -0.35 -0.55) (layer B.SilkS) (width 0.1)) (fp_line (start -0.75 0) (end -0.35 0) (layer B.SilkS) (width 0.1)) - ${''/* extra direction bars */} - (fp_line (start -2.5 -0.9) (end -2.5 0.9) (layer F.SilkS) (width 0.12)) - (fp_line (start -2.5 -0.9) (end -2.5 0.9) (layer B.SilkS) (width 0.12)) - ${''/* SMD pads on both sides */} - (pad 1 smd rect (at -1.65 0 __ROT(0)) (size 0.9 1.2) (layers F.Cu F.Paste F.Mask) __NET_TO) - (pad 2 smd rect (at 1.65 0 __ROT(0)) (size 0.9 1.2) (layers B.Cu B.Paste B.Mask) __NET_FROM) - (pad 1 smd rect (at -1.65 0 __ROT(0)) (size 0.9 1.2) (layers B.Cu B.Paste B.Mask) __NET_TO) - (pad 2 smd rect (at 1.65 0 __ROT(0)) (size 0.9 1.2) (layers F.Cu F.Paste F.Mask) __NET_FROM) + (pad 1 smd rect (at -1.65 0 ${p.rot}) (size 0.9 1.2) (layers F.Cu F.Paste F.Mask) ${p.net_to}) + (pad 2 smd rect (at 1.65 0 ${p.rot}) (size 0.9 1.2) (layers B.Cu B.Paste B.Mask) ${p.net_from}) + (pad 1 smd rect (at -1.65 0 ${p.rot}) (size 0.9 1.2) (layers B.Cu B.Paste B.Mask) ${p.net_to}) + (pad 2 smd rect (at 1.65 0 ${p.rot}) (size 0.9 1.2) (layers F.Cu F.Paste F.Mask) ${p.net_from}) ${''/* THT terminals */} - (pad 1 thru_hole rect (at -3.81 0 __ROT(0)) (size 1.778 1.778) (drill 0.9906) (layers *.Cu *.Mask) __NET_TO) - (pad 2 thru_hole circle (at 3.81 0 __ROT(0)) (size 1.905 1.905) (drill 0.9906) (layers *.Cu *.Mask) __NET_FROM) + (pad 1 thru_hole circle (at 3.81 0 ${p.rot}) (size 1.905 1.905) (drill 0.9906) (layers *.Cu *.Mask) ${p.net_from}) + (pad 2 thru_hole rect (at -3.81 0 ${p.rot}) (size 1.778 1.778) (drill 0.9906) (layers *.Cu *.Mask) ${p.net_to}) ) ` - } \ No newline at end of file +} \ No newline at end of file diff --git a/src/footprints/index.js b/src/footprints/index.js index 8e74e60..04b1162 100644 --- a/src/footprints/index.js +++ b/src/footprints/index.js @@ -1,5 +1,8 @@ module.exports = { mx: require('./mx'), + alps: require('./alps'), + choc: require('./choc'), diode: require('./diode'), - promicro: require('./promicro') + promicro: require('./promicro'), + pad: require('./pad') } \ No newline at end of file diff --git a/src/footprints/mx.js b/src/footprints/mx.js index 7b5814b..a90e417 100644 --- a/src/footprints/mx.js +++ b/src/footprints/mx.js @@ -1,11 +1,10 @@ module.exports = { nets: ['from', 'to'], - body: ` + body: p => ` (module MX (layer F.Cu) (tedit 5DD4F656) - ${''/* parametric position */} - __AT + ${p.at /* parametric position */} ${''/* corner marks */} (fp_line (start -7 -6) (end -7 -7) (layer F.SilkS) (width 0.15)) @@ -18,8 +17,8 @@ module.exports = { (fp_line (start 7 -7) (end 7 -6) (layer F.SilkS) (width 0.15)) ${''/* pins */} - (pad 1 thru_hole circle (at 2.54 -5.08) (size 2.286 2.286) (drill 1.4986) (layers *.Cu *.Mask) __NET_FROM) - (pad 2 thru_hole circle (at -3.81 -2.54) (size 2.286 2.286) (drill 1.4986) (layers *.Cu *.Mask) __NET_TO) + (pad 1 thru_hole circle (at 2.54 -5.08) (size 2.286 2.286) (drill 1.4986) (layers *.Cu *.Mask) ${p.net_from}) + (pad 2 thru_hole circle (at -3.81 -2.54) (size 2.286 2.286) (drill 1.4986) (layers *.Cu *.Mask) ${p.net_to}) ${''/* middle shaft */} (pad "" np_thru_hole circle (at 0 0) (size 3.9878 3.9878) (drill 3.9878) (layers *.Cu *.Mask)) diff --git a/src/footprints/pad.js b/src/footprints/pad.js new file mode 100644 index 0000000..0082f9c --- /dev/null +++ b/src/footprints/pad.js @@ -0,0 +1,35 @@ +module.exports = { + nets: ['net'], + params: { + width: 1, + height: 1, + front: true, + back: true + }, + body: p => { + + let front = '' + if (p.param_front) { + front = `(pad 1 smd rect (at 0 0 ${p.rot}) (size ${p.param_width} ${p.param_height}) (layers F.Cu F.Paste F.Mask) ${p.net_net})` + } + + let back = '' + if (p.param_back) { + back = `(pad 1 smd rect (at 0 0 ${p.rot}) (size ${p.param_width} ${p.param_height}) (layers B.Cu B.Paste B.Mask) ${p.net_net})` + } + + return ` + + (module SMDPad (layer F.Cu) (tedit 5B24D78E) + + ${p.at /* parametric position */} + + ${''/* SMD pads */} + ${front} + ${back} + + ) + + ` + } +} \ No newline at end of file diff --git a/src/footprints/promicro.js b/src/footprints/promicro.js index 6731656..b69e2a0 100644 --- a/src/footprints/promicro.js +++ b/src/footprints/promicro.js @@ -6,83 +6,82 @@ module.exports = { 'P1', 'P0', 'P2', 'P3', 'P4', 'P5', 'P6', 'P7', 'P8', 'P9' ], - body: ` + body: p => ` (module ProMicro (layer F.Cu) (tedit 5B307E4C) - ${''/* parametric position */} - __AT + ${p.at /* parametric position */} - ${''/* illustration of the USB port overhang */} - (fp_line (start -19.304 -3.556) (end -14.224 -3.556) (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 -14.224 3.81) (end -19.304 3.81) (layer Dwgs.User) (width 0.2)) - (fp_line (start -14.224 -3.556) (end -14.224 3.81) (layer Dwgs.User) (width 0.2)) + ${''/* illustration of the (possible) USB port overhang */} + (fp_line (start -19.304 -3.556) (end -14.224 -3.556) (layer Dwgs.User) (width 0.25)) + (fp_line (start -19.304 3.81) (end -19.304 -3.556) (layer Dwgs.User) (width 0.25)) + (fp_line (start -14.224 3.81) (end -19.304 3.81) (layer Dwgs.User) (width 0.25)) + (fp_line (start -14.224 -3.556) (end -14.224 3.81) (layer Dwgs.User) (width 0.25)) ${''/* component outline */} - (fp_line (start -17.78 8.89) (end 15.24 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 15.24 -8.89) (end -17.78 -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 -17.78 8.89) (end 15.24 8.89) (layer F.SilkS) (width 0.25)) + (fp_line (start 15.24 8.89) (end 15.24 -8.89) (layer F.SilkS) (width 0.25)) + (fp_line (start 15.24 -8.89) (end -17.78 -8.89) (layer F.SilkS) (width 0.25)) + (fp_line (start -17.78 -8.89) (end -17.78 8.89) (layer F.SilkS) (width 0.25)) ${''/* extra border around "RAW", in case the rectangular shape is not distinctive enough */} - (fp_line (start -15.24 6.35) (end -12.7 6.35) (layer F.SilkS) (width 0.381)) - (fp_line (start -15.24 6.35) (end -15.24 8.89) (layer F.SilkS) (width 0.381)) - (fp_line (start -12.7 6.35) (end -12.7 8.89) (layer F.SilkS) (width 0.381)) + (fp_line (start -15.24 6.35) (end -12.7 6.35) (layer F.SilkS) (width 0.25)) + (fp_line (start -15.24 6.35) (end -15.24 8.89) (layer F.SilkS) (width 0.25)) + (fp_line (start -12.7 6.35) (end -12.7 8.89) (layer F.SilkS) (width 0.25)) ${''/* pin names */} - (fp_text user RAW (at -13.97 5.0 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user GND (at -11.43 5.0 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user RST (at -8.89 5.0 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user VCC (at -6.35 5.0 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 21 (at -3.81 5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 20 (at -1.27 5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 19 (at 1.27 5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 18 (at 3.81 5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 15 (at 6.35 5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 14 (at 8.89 5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 16 (at 11.43 5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 10 (at 13.97 5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user RAW (at -13.97 4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user GND (at -11.43 4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user RST (at -8.89 4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user VCC (at -6.35 4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P21 (at -3.81 4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P20 (at -1.27 4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P19 (at 1.27 4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P18 (at 3.81 4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P15 (at 6.35 4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P14 (at 8.89 4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P16 (at 11.43 4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P10 (at 13.97 4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 1 (at -13.97 -5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 0 (at -11.43 -5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user GND (at -8.89 -5.0 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user GND (at -6.35 -5.0 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 2 (at -3.81 -5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 3 (at -1.27 -5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 4 (at 1.27 -5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 5 (at 3.81 -5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 6 (at 6.35 -5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 7 (at 8.89 -5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 8 (at 11.43 -5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) - (fp_text user 9 (at 13.97 -5.461 __ROT(90)) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P01 (at -13.97 -4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P00 (at -11.43 -4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user GND (at -8.89 -4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user GND (at -6.35 -4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P02 (at -3.81 -4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P03 (at -1.27 -4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P04 (at 1.27 -4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P05 (at 3.81 -4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P06 (at 6.35 -4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P07 (at 8.89 -4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P08 (at 11.43 -4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) + (fp_text user P09 (at 13.97 -4.8 ${p.rot + 90}) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15)))) ${''/* and now the actual pins */} - (pad 1 thru_hole rect (at -13.97 7.62 __ROT(0)) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_RAW) - (pad 2 thru_hole circle (at -11.43 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_GND) - (pad 3 thru_hole circle (at -8.89 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_RST) - (pad 4 thru_hole circle (at -6.35 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_VCC) - (pad 5 thru_hole circle (at -3.81 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P21) - (pad 6 thru_hole circle (at -1.27 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P20) - (pad 7 thru_hole circle (at 1.27 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P19) - (pad 8 thru_hole circle (at 3.81 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P18) - (pad 9 thru_hole circle (at 6.35 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P15) - (pad 10 thru_hole circle (at 8.89 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P14) - (pad 11 thru_hole circle (at 11.43 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P16) - (pad 12 thru_hole circle (at 13.97 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P10) + (pad 1 thru_hole rect (at -13.97 7.62 ${p.rot}) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_RAW}) + (pad 2 thru_hole circle (at -11.43 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_GND}) + (pad 3 thru_hole circle (at -8.89 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_RST}) + (pad 4 thru_hole circle (at -6.35 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_VCC}) + (pad 5 thru_hole circle (at -3.81 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P21}) + (pad 6 thru_hole circle (at -1.27 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P20}) + (pad 7 thru_hole circle (at 1.27 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P19}) + (pad 8 thru_hole circle (at 3.81 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P18}) + (pad 9 thru_hole circle (at 6.35 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P15}) + (pad 10 thru_hole circle (at 8.89 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P14}) + (pad 11 thru_hole circle (at 11.43 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P16}) + (pad 12 thru_hole circle (at 13.97 7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P10}) - (pad 13 thru_hole circle (at -13.97 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P1) - (pad 14 thru_hole circle (at -11.43 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P0) - (pad 15 thru_hole circle (at -8.89 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_GND) - (pad 16 thru_hole circle (at -6.35 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_GND) - (pad 17 thru_hole circle (at -3.81 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P2) - (pad 18 thru_hole circle (at -1.27 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P3) - (pad 19 thru_hole circle (at 1.27 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P4) - (pad 20 thru_hole circle (at 3.81 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P5) - (pad 21 thru_hole circle (at 6.35 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P6) - (pad 22 thru_hole circle (at 8.89 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P7) - (pad 23 thru_hole circle (at 11.43 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P8) - (pad 24 thru_hole circle (at 13.97 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) __NET_P9) + (pad 13 thru_hole circle (at -13.97 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P1}) + (pad 14 thru_hole circle (at -11.43 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P0}) + (pad 15 thru_hole circle (at -8.89 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_GND}) + (pad 16 thru_hole circle (at -6.35 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_GND}) + (pad 17 thru_hole circle (at -3.81 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P2}) + (pad 18 thru_hole circle (at -1.27 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P3}) + (pad 19 thru_hole circle (at 1.27 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P4}) + (pad 20 thru_hole circle (at 3.81 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P5}) + (pad 21 thru_hole circle (at 6.35 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P6}) + (pad 22 thru_hole circle (at 8.89 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P7}) + (pad 23 thru_hole circle (at 11.43 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P8}) + (pad 24 thru_hole circle (at 13.97 -7.62 0) (size 1.7526 1.7526) (drill 1.0922) (layers *.Cu *.SilkS *.Mask) ${p.net_P9}) ) ` } diff --git a/src/outlines.js b/src/outlines.js index 906b010..4f2f292 100644 --- a/src/outlines.js +++ b/src/outlines.js @@ -230,19 +230,35 @@ exports.parse = (config = {}, points = {}) => { arg = layout_fn(part, name, expected) break case 'rectangle': - a.detect_unexpected(part, name, expected.concat(['ref', 'shift', 'rotate', 'size', 'corner', 'bevel'])) + a.detect_unexpected(part, name, expected.concat(['ref', 'shift', 'rotate', 'size', 'corner', 'bevel', 'mirror'])) anchor = a.anchor(part, name, points, false) const size = a.wh(part.size, `${name}.size`) const corner = a.sane(part.corner || 0, `${name}.corner`, 'number') const bevel = a.sane(part.bevel || 0, `${name}.bevel`, 'number') - arg = rectangle(size[0], size[1], corner, bevel, name) - arg = anchor.position(arg) + const rect_mirror = a.sane(part.mirror || false, `${name}.mirror`, 'boolean') + const rect = rectangle(size[0], size[1], corner, bevel, name) + arg = anchor.position(rect) + if (rect_mirror) { + const mirror_part = u.deepcopy(part) + a.assert(mirror_part.ref, `Field "${name}.ref" must be speficied if mirroring is required!`) + mirror_part.ref = `mirror_${mirror_part.ref}` + anchor = a.anchor(mirror_part, name, points, false) + arg = u.stack(arg, anchor.position(rect)) + } break case 'circle': - a.detect_unexpected(part, name, expected.concat(['ref', 'shift', 'rotate', 'radius'])) + a.detect_unexpected(part, name, expected.concat(['ref', 'shift', 'rotate', 'radius', 'mirror'])) anchor = a.anchor(part, name, points, false) const radius = a.sane(part.radius, `${name}.radius`, 'number') + const circle_mirror = a.sane(part.mirror || false, `${name}.mirror`, 'boolean') arg = u.circle(anchor.p, radius) + if (circle_mirror) { + const mirror_part = u.deepcopy(part) + a.assert(mirror_part.ref, `Field "${name}.ref" must be speficied if mirroring is required!`) + mirror_part.ref = `mirror_${mirror_part.ref}` + anchor = a.anchor(mirror_part, name, points, false) + arg = u.stack(arg, u.circle(anchor.p, radius)) + } break case 'polygon': a.detect_unexpected(part, name, expected.concat(['points'])) diff --git a/src/pcbs.js b/src/pcbs.js index 712aea2..b1825c7 100644 --- a/src/pcbs.js +++ b/src/pcbs.js @@ -125,13 +125,16 @@ const makerjs2kicad = exports._makerjs2kicad = (model, layer='Edge.Cuts') => { grs.push(`(gr_line (start ${xy(p.origin)}) (end ${xy(p.end)}) (angle 90) (layer ${layer}) (width 0.15))`) break case 'arc': - const center = p.origin + const arc_center = p.origin const angle_start = p.startAngle > p.endAngle ? p.startAngle - 360 : p.startAngle const angle_diff = Math.abs(p.endAngle - angle_start) - const end = m.point.rotate(m.point.add(center, [p.radius, 0]), angle_start, center) - grs.push(`(gr_arc (start ${xy(center)}) (end ${xy(end)}) (angle ${-angle_diff}) (layer ${layer}) (width 0.15))`) + const arc_end = m.point.rotate(m.point.add(arc_center, [p.radius, 0]), angle_start, arc_center) + grs.push(`(gr_arc (start ${xy(arc_center)}) (end ${xy(arc_end)}) (angle ${-angle_diff}) (layer ${layer}) (width 0.15))`) break case 'circle': + const circle_center = p.origin + const circle_end = m.point.add(circle_center, [p.radius, 0]) + grs.push(`(gr_circle (center ${xy(circle_center)}) (end ${xy(circle_end)}) (layer ${layer}) (width 0.15))`) break default: throw new Error(`Can't convert path type "${p.type}" to kicad!`) @@ -155,23 +158,16 @@ const footprint = exports._footprint = (config, name, points, net_indexer, point // basic setup const fp = footprint_types[type] - let result = fp.body + const parsed_params = {} // footprint positioning - const at = `(at ${anchor.x} ${-anchor.y} ${anchor.r})` - result = result.replace(new RegExp('__AT', 'g'), at) - // fix rotations within footprints - const rot_regex = /__ROT\((\d+)\)/g - const matches = [...result.matchAll(rot_regex)] - for (const match of matches) { - const angle = parseFloat(match[1]) - result = result.replace(match[0], (anchor.r + angle) + '') - } + parsed_params.at = `(at ${anchor.x} ${-anchor.y} ${anchor.r})` + parsed_params.rot = anchor.r // connecting static nets for (const net of (fp.static_nets || [])) { const index = net_indexer(net) - result = result.replace(new RegExp('__NET_' + net.toUpperCase(), 'g'), `(net ${index} "${net}")`) + parsed_params['net_' + net] = `(net ${index} "${net}")` } // connecting parametric nets @@ -184,22 +180,22 @@ const footprint = exports._footprint = (config, name, points, net_indexer, point a.sane(net, `${name}.nets.${net_ref} --> ${point.meta.name}.${indirect}`, 'string') } const index = net_indexer(net) - result = result.replace(new RegExp('__NET_' + net_ref.toUpperCase(), 'g'), `(net ${index} "${net}")`) + parsed_params['net_' + net_ref] = `(net ${index} "${net}")` } // connecting other, non-net parameters - for (const param of (fp.params || [])) { - let value = params[param] + for (const param of (Object.keys(fp.params || {}))) { + let value = params[param] === undefined ? fp.params[param] : params[param] if (value === undefined) throw new Error(`Field "${name}.params.${param}" is missing!`) if (a.type(value) == 'string' && value.startsWith('!') && point) { const indirect = value.substring(1) value = point.meta[indirect] if (value === undefined) throw new Error(`Field "${name}.params.${param} --> ${point.meta.name}.${indirect}" is missing!`) } - result = result.replace(new RegExp('__PARAM_' + param.toUpperCase(), 'g'), value) + parsed_params['param_' + param] = value } - return result + return fp.body(parsed_params) } exports.parse = (config, points, outlines) => { diff --git a/src/utils.js b/src/utils.js index 6ffa26d..8be4db0 100644 --- a/src/utils.js +++ b/src/utils.js @@ -11,7 +11,7 @@ const line = exports.line = (a, b) => { } exports.circle = (p, r) => { - return new m.paths.Circle(p, r) + return {paths: {circle: new m.paths.Circle(p, r)}} } exports.rect = (w, h, o=[0, 0]) => { diff --git a/test/fixtures/absolem.yaml b/test/fixtures/absolem.yaml index 4785e28..1968959 100644 --- a/test/fixtures/absolem.yaml +++ b/test/fixtures/absolem.yaml @@ -69,30 +69,193 @@ points: row_net: P14 mirror: row_net: P6 + top: + row_net: P15 + mirror: + row_net: P5 + s19: + extends: matrix + columns: + pinky: + rows: + bottom: + footprints: + diode: + anchor: + shift: [,12] + home: + footprints: + diode: + anchor: + shift: [,6] + top: + footprints: + row_ext: + anchor: + shift: [, -10] + extra_column: + type: pad + anchor: + shift: [-4, 4] + nets: + net: 'P19' + params: + width: 2 + height: 2 + front: false + key: + footprints: + row_ext: + type: pad + anchor: + shift: [-4, -4] + nets: + net: '!row_net' + params: + width: 2 + height: 2 + front: false + + ring: + rows: + bottom: + footprints: + diode: + anchor: + shift: [,5] + home: + footprints: + diode: + anchor: + shift: [,2.5] + middle: + rows: + top: + footprints: + diode: + anchor: + shift: [,-6] + home: + footprints: + diode: + anchor: + shift: [,-3] + index: + rows: + bottom: + footprints: + diode: + anchor: + shift: [-8.25,6] + home: + footprints: + diode: + anchor: + shift: [-8.25,3] + top: + footprints: + diode: + anchor: + shift: [-8.25,] + rows: top: footprints: mx: anchor: rotate: 180 - row_net: P15 - mirror: - row_net: P5 + alps: + anchor: + rotate: 180 + choc: + anchor: + rotate: 180 + col_ext: + type: pad + anchor: + shift: [4, 4] + nets: + net: '!column_net' + params: + width: 2 + height: 2 + front: false + bottom: + footprints: + diode: + anchor: + rotate: 270 + col_ext: + type: pad + anchor: + shift: [4, -4] + nets: + net: '!column_net' + params: + width: 2 + height: 2 + front: false key: tags: s19: true - choc: + footprints: &quad + mx: + type: mx + nets: + from: '!colrow' + to: '!column_net' + alps: + type: alps + nets: + from: '!colrow' + to: '!column_net' + <<: &choc + choc: + type: choc + nets: + from: '!colrow' + to: '!column_net' + diode: + type: diode + anchor: + rotate: 90 + shift: [8.25, 0] + nets: + from: '!colrow' + to: '!row_net' + mirror: + footprints: &quad_mirror + mx: + nets: + from: '!column_net' + to: '!colrow' + alps: + nets: + from: '!column_net' + to: '!colrow' + <<: &choc_mirror + choc: + nets: + from: '!column_net' + to: '!colrow' + s18: extends: matrix columns: pinky: stagger: 1 origin: [7, -8] + rows: + top: + footprints: + choc: + anchor: + rotate: 180 key: padding: 18 tags: - s19: false s18: true - footprints: - diode: '!!unset' + footprints: *choc + mirror: + footprints: *choc_mirror thumbfan: anchor: ref: matrix_inner_bottom @@ -105,10 +268,27 @@ points: rows: thumb: bind: [10,5,,] - key: - column_net: P2 - tags: - classic: true + column_net: P2 + tags: + classic: true + footprints: + choc: + anchor: + rotate: 180 + diode: + anchor: + shift: [8,] + row_ext: + type: pad + anchor: + shift: [-3, 9] + nets: + net: '!row_net' + params: + width: 2 + height: 2 + front: false + home: spread: 21.25 rotate: -28 @@ -125,15 +305,33 @@ points: rows: thumb: bind: [-1,,,5] - key: - column_net: P4 - tags: - classic: true + column_net: P4 + tags: + classic: true + footprints: + choc: + anchor: + rotate: 180 + diode: + anchor: + shift: [-4,] rows: thumb: row_net: P10 + footprints: + diode: + anchor: + shift: [0, 9] + rotate: 180 mirror: row_net: P8 + footprints: + diode: + anchor: + rotate: 0 + key: + footprints: *quad + mirror: *quad_mirror unifar: anchor: ref: thumbfan_home_thumb @@ -143,14 +341,20 @@ points: origin: [9.5, -9] key: skip: true - far1u: + far: rows: thumb: bind: [-1,,,5] key: column_net: P4 footprints: - diode: false + choc: + anchor: + rotate: 180 + diode: '!!unset' + mirror: + footprints: + diode: '!!unset' tags: uniform: true rows: @@ -158,6 +362,9 @@ points: row_net: P10 mirror: row_net: P8 + key: + footprints: *quad + mirror: *quad_mirror uninear: anchor: ref: thumbfan_home_thumb @@ -168,14 +375,20 @@ points: origin: [-9.5, -9] key: skip: true - near1u: + near: rows: thumb: bind: [10,5,,] key: column_net: P2 footprints: - diode: false + choc: + anchor: + rotate: 180 + diode: '!!unset' + mirror: + footprints: + diode: '!!unset' tags: uniform: true rows: @@ -183,28 +396,11 @@ points: row_net: P10 mirror: row_net: P8 + key: + footprints: *quad + mirror: *quad_mirror key: bind: [0,0,0,0] - footprints: - mx: - type: mx - nets: - from: '!column_net' - to: '!colrow' - diode: - type: diode - anchor: - rotate: 90 - shift: [8, 0] - nets: - from: '!name' - to: '!row_net' - mirror: - footprints: - mx: - nets: - from: '!colrow' - to: '!column_net' rotate: -20 mirror: ref: matrix_pinky_home @@ -237,16 +433,16 @@ outlines: extends: classic_s19 bottom: left: - ref: unifar_far1u_thumb + ref: unifar_far_thumb right: - ref: mirror_unifar_far1u_thumb + ref: mirror_unifar_far_thumb classic_s18: extends: classic_s19 top: left: - ref: choc_inner_top + ref: s18_inner_top right: - ref: mirror_choc_inner_top + ref: mirror_s18_inner_top uniform_s18: extends: - uniform_s19 @@ -276,6 +472,55 @@ outlines: - s18 - uniform glue: uniform_s18 + mounting_holes: + ring_top: + type: circle + ref: matrix_ring_home + shift: [-10, 5] + radius: 2.25 + mirror: true + ring_bottom: + type: circle + ref: matrix_ring_home + shift: [-9, -9] + radius: 2.25 + mirror: true + operation: stack + index_top: + type: circle + ref: matrix_index_home + shift: [9.5, 9.5] + radius: 2.25 + mirror: true + operation: stack + index_bottom: + type: circle + ref: matrix_index_home + shift: [9.5, -9.5] + radius: 2.25 + mirror: true + operation: stack + thumb_near: + type: circle + ref: thumbfan_home_thumb + shift: [-12, 2] + radius: 2.25 + mirror: true + operation: stack + thumb_far: + type: circle + ref: thumbfan_home_thumb + shift: [12, 2] + radius: 2.25 + mirror: true + operation: stack + middle: + type: circle + ref: thumbfan_home_thumb + shift: [-8, 19] + radius: 2.25 + mirror: true + operation: stack intersected_outline: one: type: outline @@ -284,6 +529,18 @@ outlines: type: outline name: uniform_s18_outline operation: intersect + controller_cutout: + type: rectangle + ref: + - s18_inner_top + - mirror_s18_inner_top + shift: [-10, -5] + size: [20, 10] + operation: subtract + mounting_holes: + type: outline + name: mounting_holes + operation: subtract classic_s19_switches: main: type: keys @@ -335,6 +592,10 @@ outlines: type: outline name: classic_s19_outline operation: intersect + mounting_holes: + type: outline + name: mounting_holes + operation: stack pcbs: main: edge: intersected_outline @@ -343,7 +604,33 @@ pcbs: type: promicro anchor: ref: - - choc_inner_top - - mirror_choc_inner_top - shift: [0, -20] + - s18_inner_top + - mirror_s18_inner_top + shift: [0, -23] rotate: 270 + extra_row_left: + type: pad + anchor: + ref: + - s18_inner_top + - mirror_s18_inner_top + shift: [-15, -10] + nets: + net: 'P20' + params: + width: 3 + height: 3 + front: false + extra_row_right: + type: pad + anchor: + ref: + - s18_inner_top + - mirror_s18_inner_top + shift: [15, -10] + nets: + net: 'P21' + params: + width: 3 + height: 3 + front: false