PCB progress
This commit is contained in:
parent
a6ed52b4bd
commit
05a33d00ec
7 changed files with 367 additions and 12 deletions
10
README.md
10
README.md
|
@ -572,7 +572,12 @@ Everything should be ready for a handwire, but if you'd like the design to be mo
|
|||
To help you get started, the necessary footprints and an edge cut can be automatically positioned so that all you need to do manually is the routing.
|
||||
|
||||
Footprints can be specified at the key-level (under the `points` section, like we discussed above), or here with manually given anchors.
|
||||
The only difference between the two footprint types is that an omitted `ref` in the anchor means the current key for key-level declarations, while here it defaults to `[0, 0]`.
|
||||
The differences between the two footprint types are:
|
||||
|
||||
- an omitted `ref` in the anchor means the current key for key-level declarations, while here it defaults to `[0, 0]`
|
||||
- a parameter starting with an exclamation point is an indirect reference to an eponymous key-level attribute -- so, for example, `from = !col_wire` would mean that the key's `col_wire` attribute is read there.
|
||||
|
||||
Another alternative to `anchor` here (here being under the `pcb` declaration) is to use the `between` key and place the footprint at the average of multiple anchors -- mostly useful for anchoring to the center, by averaging a key and its mirror.
|
||||
Additionally, the edge cut of the PCB can be specified using a previously defined outline name under the `edge` key.
|
||||
|
||||
```yaml
|
||||
|
@ -581,6 +586,9 @@ pcb:
|
|||
footprints:
|
||||
- type: <footprint type>
|
||||
anchor: <anchor declaration>
|
||||
between:
|
||||
- <anchor declaration>
|
||||
- ...
|
||||
params: <type-specific footprint params>
|
||||
- ...
|
||||
```
|
||||
|
|
10
src/cli.js
10
src/cli.js
|
@ -36,8 +36,14 @@ const args = yargs
|
|||
describe: 'Debug mode',
|
||||
type: 'boolean'
|
||||
})
|
||||
.option('clean', {
|
||||
default: false,
|
||||
describe: 'Clean output dir before parsing',
|
||||
type: 'boolean'
|
||||
})
|
||||
.argv
|
||||
|
||||
if (args.clean) fs.removeSync(args.o)
|
||||
fs.mkdirpSync(args.o)
|
||||
|
||||
const config_parser = args.c.endsWith('.yaml') ? yaml.load : JSON.parse
|
||||
|
@ -72,7 +78,9 @@ for (const [name, outline] of Object.entries(outlines)) {
|
|||
|
||||
console.log('Scaffolding PCB...')
|
||||
const pcb = pcb_lib.parse(config.pcb, points, outlines)
|
||||
fs.writeFileSync(path.join(args.o, `pcb/pcb.kicad_pcb`, pcb))
|
||||
const pcb_file = path.join(args.o, `pcb/pcb.kicad_pcb`)
|
||||
fs.mkdirpSync(path.dirname(pcb_file))
|
||||
fs.writeFileSync(pcb_file, pcb)
|
||||
|
||||
// goodbye
|
||||
|
||||
|
|
4
src/footprints/index.js
Normal file
4
src/footprints/index.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
module.exports = {
|
||||
mx: require('./mx'),
|
||||
promicro: require('./promicro')
|
||||
}
|
33
src/footprints/mx.js
Normal file
33
src/footprints/mx.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
module.exports = {
|
||||
params: ['from', 'to'],
|
||||
body: `
|
||||
|
||||
(module MX (layer F.Cu) (tedit 5DD4F656)
|
||||
|
||||
${''/* parametric position */}
|
||||
__AT
|
||||
|
||||
${''/* 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.54 -5.08) (size 2.286 2.286) (drill 1.4986) (layers *.Cu *.Mask) __PARAM_FROM)
|
||||
(pad 2 thru_hole circle (at -3.81 -2.54) (size 2.286 2.286) (drill 1.4986) (layers *.Cu *.Mask) __PARAM_TO)
|
||||
|
||||
${''/* middle shaft */}
|
||||
(pad "" np_thru_hole circle (at 0 0) (size 3.9878 3.9878) (drill 3.9878) (layers *.Cu *.Mask))
|
||||
|
||||
${''/* stabilizers */}
|
||||
(pad "" np_thru_hole circle (at 5.08 0) (size 1.7018 1.7018) (drill 1.7018) (layers *.Cu *.Mask))
|
||||
(pad "" np_thru_hole circle (at -5.08 0) (size 1.7018 1.7018) (drill 1.7018) (layers *.Cu *.Mask))
|
||||
)
|
||||
|
||||
`
|
||||
}
|
88
src/footprints/promicro.js
Normal file
88
src/footprints/promicro.js
Normal file
|
@ -0,0 +1,88 @@
|
|||
module.exports = {
|
||||
nets: [
|
||||
'RAW', 'GND', 'RST', 'VCC',
|
||||
'P21', 'P20', 'P19', 'P18',
|
||||
'P15', 'P14', 'P16', 'P10',
|
||||
'P1', 'P0', 'P2', 'P3', 'P4',
|
||||
'P5', 'P6', 'P7', 'P8', 'P9'
|
||||
],
|
||||
body: `
|
||||
|
||||
(module ProMicro (layer F.Cu) (tedit 5B307E4C)
|
||||
|
||||
${''/* parametric position */}
|
||||
__AT
|
||||
|
||||
${''/* 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))
|
||||
|
||||
${''/* 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))
|
||||
|
||||
${''/* 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))
|
||||
|
||||
${''/* pin names */}
|
||||
(fp_text user RAW (at -13.97 5.0) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user GND (at -11.43 5.0) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user RST (at -8.89 5.0) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user VCC (at -6.35 5.0) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user 21 (at -3.81 5.461) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user 20 (at -1.27 5.461) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user 19 (at 1.27 5.461) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user 18 (at 3.81 5.461) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user 15 (at 6.35 5.461) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user 14 (at 8.89 5.461) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user 16 (at 11.43 5.461) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user 10 (at 13.97 5.461) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
|
||||
(fp_text user 1 (at -13.97 -5.461) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user 0 (at -11.43 -5.461) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user GND (at -8.89 -5.0) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user GND (at -6.35 -5.0) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user 2 (at -3.81 -5.461) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user 3 (at -1.27 -5.461) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user 4 (at 1.27 -5.461) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user 5 (at 3.81 -5.461) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user 6 (at 6.35 -5.461) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user 7 (at 8.89 -5.461) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user 8 (at 11.43 -5.461) (layer F.SilkS) (effects (font (size 0.8 0.8) (thickness 0.15))))
|
||||
(fp_text user 9 (at 13.97 -5.461) (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 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 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)
|
||||
)
|
||||
`
|
||||
}
|
223
src/pcb.js
223
src/pcb.js
|
@ -2,7 +2,119 @@ const m = require('makerjs')
|
|||
const u = require('./utils')
|
||||
const a = require('./assert')
|
||||
|
||||
const makerjs2kicad = exports._makerjs2kicad = model => {
|
||||
const Point = require('./point')
|
||||
|
||||
const kicad_prefix = `
|
||||
(kicad_pcb (version 20171130) (host pcbnew 5.1.6)
|
||||
|
||||
(page A3)
|
||||
(title_block
|
||||
(title KEYBOARD_NAME_HERE)
|
||||
(rev VERSION_HERE)
|
||||
(company YOUR_NAME_HERE)
|
||||
)
|
||||
|
||||
(general
|
||||
(thickness 1.6)
|
||||
)
|
||||
|
||||
(layers
|
||||
(0 F.Cu signal)
|
||||
(31 B.Cu signal)
|
||||
(32 B.Adhes user)
|
||||
(33 F.Adhes user)
|
||||
(34 B.Paste user)
|
||||
(35 F.Paste user)
|
||||
(36 B.SilkS user)
|
||||
(37 F.SilkS user)
|
||||
(38 B.Mask user)
|
||||
(39 F.Mask user)
|
||||
(40 Dwgs.User user)
|
||||
(41 Cmts.User user)
|
||||
(42 Eco1.User user)
|
||||
(43 Eco2.User user)
|
||||
(44 Edge.Cuts user)
|
||||
(45 Margin user)
|
||||
(46 B.CrtYd user)
|
||||
(47 F.CrtYd user)
|
||||
(48 B.Fab user)
|
||||
(49 F.Fab user)
|
||||
)
|
||||
|
||||
(setup
|
||||
(last_trace_width 0.25)
|
||||
(trace_clearance 0.2)
|
||||
(zone_clearance 0.508)
|
||||
(zone_45_only no)
|
||||
(trace_min 0.2)
|
||||
(via_size 0.8)
|
||||
(via_drill 0.4)
|
||||
(via_min_size 0.4)
|
||||
(via_min_drill 0.3)
|
||||
(uvia_size 0.3)
|
||||
(uvia_drill 0.1)
|
||||
(uvias_allowed no)
|
||||
(uvia_min_size 0.2)
|
||||
(uvia_min_drill 0.1)
|
||||
(edge_width 0.05)
|
||||
(segment_width 0.2)
|
||||
(pcb_text_width 0.3)
|
||||
(pcb_text_size 1.5 1.5)
|
||||
(mod_edge_width 0.12)
|
||||
(mod_text_size 1 1)
|
||||
(mod_text_width 0.15)
|
||||
(pad_size 1.524 1.524)
|
||||
(pad_drill 0.762)
|
||||
(pad_to_mask_clearance 0.05)
|
||||
(aux_axis_origin 0 0)
|
||||
(visible_elements FFFFFF7F)
|
||||
(pcbplotparams
|
||||
(layerselection 0x010fc_ffffffff)
|
||||
(usegerberextensions false)
|
||||
(usegerberattributes true)
|
||||
(usegerberadvancedattributes true)
|
||||
(creategerberjobfile true)
|
||||
(excludeedgelayer true)
|
||||
(linewidth 0.100000)
|
||||
(plotframeref false)
|
||||
(viasonmask false)
|
||||
(mode 1)
|
||||
(useauxorigin false)
|
||||
(hpglpennumber 1)
|
||||
(hpglpenspeed 20)
|
||||
(hpglpendiameter 15.000000)
|
||||
(psnegative false)
|
||||
(psa4output false)
|
||||
(plotreference true)
|
||||
(plotvalue true)
|
||||
(plotinvisibletext false)
|
||||
(padsonsilk false)
|
||||
(subtractmaskfromsilk false)
|
||||
(outputformat 1)
|
||||
(mirror false)
|
||||
(drillshape 1)
|
||||
(scaleselection 1)
|
||||
(outputdirectory ""))
|
||||
)
|
||||
`
|
||||
|
||||
const kicad_suffix = `
|
||||
)
|
||||
`
|
||||
|
||||
const kicad_netclass = `
|
||||
(net_class Default "This is the default net class."
|
||||
(clearance 0.2)
|
||||
(trace_width 0.25)
|
||||
(via_dia 0.8)
|
||||
(via_drill 0.4)
|
||||
(uvia_dia 0.3)
|
||||
(uvia_drill 0.1)
|
||||
__ADD_NET
|
||||
)
|
||||
`
|
||||
|
||||
const makerjs2kicad = exports._makerjs2kicad = (model, layer='Edge.Cuts') => {
|
||||
const grs = []
|
||||
const xy = val => `${val[0]} ${val[1]}`
|
||||
m.model.walk(model, {
|
||||
|
@ -10,16 +122,14 @@ const makerjs2kicad = exports._makerjs2kicad = model => {
|
|||
const p = wp.pathContext
|
||||
switch (p.type) {
|
||||
case 'line':
|
||||
grs.push(`(gr_line (start ${xy(p.origin)}) (end ${xy(p.end)}) (angle 90) (layer Edge.Cuts) (width 0.15))`)
|
||||
grs.push(`(gr_line (start ${xy(p.origin)}) (end ${xy(p.end)}) (angle 90) (layer ${layer}) (width 0.15))`)
|
||||
break
|
||||
case 'arc':
|
||||
// console.log(require('util').inspect(p, false, 200))
|
||||
// throw 2
|
||||
const center = p.origin
|
||||
const angle_start = Math.min(p.startAngle, p.endAngle)
|
||||
const angle_diff = Math.abs(p.endAngle - p.startAngle)
|
||||
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 Edge.Cuts) (width 0.15))`)
|
||||
grs.push(`(gr_arc (start ${xy(center)}) (end ${xy(end)}) (angle ${angle_diff}) (layer ${layer}) (width 0.15))`)
|
||||
break
|
||||
case 'circle':
|
||||
break
|
||||
|
@ -31,12 +141,107 @@ const makerjs2kicad = exports._makerjs2kicad = model => {
|
|||
return grs
|
||||
}
|
||||
|
||||
const footprint_types = require('./footprints')
|
||||
const footprint = exports._footprint = (config, name, points, net_indexer, default_anchor) => {
|
||||
|
||||
// config sanitization
|
||||
a.detect_unexpected(config, name, ['type', 'anchor', 'between', 'params'])
|
||||
const type = a.in(config.type, `${name}.type`, Object.keys(footprint_types))
|
||||
let anchor = a.anchor(config.anchor, `${name}.anchor`, points, true, default_anchor)
|
||||
const params = a.sane(config.params, `${name}.params`, 'object')
|
||||
|
||||
// averaging multiple anchors, if necessary
|
||||
if (config.between) {
|
||||
const between = a.sane(config.between, `${name}.between`, 'array')
|
||||
let x = 0, y = 0, r = 0, bi = 0
|
||||
const len = between.length
|
||||
for (const b of between) {
|
||||
ba = a.anchor(b, `${name}.between[${++bi}]`, points, true)
|
||||
x += ba.x
|
||||
y += ba.y
|
||||
r += ba.r
|
||||
}
|
||||
anchor = new Point(x / len, y / len, r / len)
|
||||
}
|
||||
|
||||
// basic setup
|
||||
const fp = footprint_types[type]
|
||||
let result = fp.body
|
||||
|
||||
// footprint positioning
|
||||
const at = `(at ${anchor.x} ${anchor.y} ${anchor.r})`
|
||||
result = result.replace('__AT', at)
|
||||
|
||||
// connecting static nets
|
||||
for (const net of (fp.nets || [])) {
|
||||
const index = net_indexer(net)
|
||||
result = result.replace('__NET_' + net.toUpperCase(), `(net ${index} "${net}")`)
|
||||
}
|
||||
|
||||
// connecting parametric nets
|
||||
for (const param of (fp.params || [])) {
|
||||
const net = params[param]
|
||||
a.sane(net, `${name}.params.${param}`, 'string')
|
||||
const index = net_indexer(net)
|
||||
result = result.replace('__PARAM_' + net.toUpperCase(), `(net ${index} "${net}")`)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
exports.parse = (config, points, outlines) => {
|
||||
|
||||
// config sanitization
|
||||
a.detect_unexpected(config, 'pcb', ['edge', 'footprints'])
|
||||
const edge = outlines[config.edge]
|
||||
if (!edge) throw new Error(`Field "pcb.edge" doesn't name a valid outline!`)
|
||||
|
||||
// Edge.Cuts conversion
|
||||
const kicad_edge = makerjs2kicad(edge)
|
||||
|
||||
console.log(kicad_edge.join('\n'))
|
||||
throw 28
|
||||
// making a global net index registry
|
||||
const nets = {}
|
||||
const net_indexer = net => {
|
||||
if (nets[net]) return nets[net]
|
||||
const index = Object.keys(nets).length
|
||||
return nets[net] = index
|
||||
}
|
||||
|
||||
const footprints = []
|
||||
|
||||
// key-level footprints
|
||||
for (const [pname, point] of Object.entries(points)) {
|
||||
let f_index = 0
|
||||
for (const f of (point.meta.footprints || [])) {
|
||||
footprints.push(footprint(f, `${pname}.footprints[${++f_index}]`, points, net_indexer, point))
|
||||
}
|
||||
}
|
||||
|
||||
// global one-off footprints
|
||||
const global_footprints = a.sane(config.footprints || [], 'pcb.footprints', 'array')
|
||||
let gf_index = 0
|
||||
for (const gf of global_footprints) {
|
||||
footprints.push(footprint(gf, `pcb.footprints[${++gf_index}]`, points, net_indexer))
|
||||
}
|
||||
|
||||
// finalizing nets
|
||||
const nets_arr = []
|
||||
const add_nets_arr = []
|
||||
for (const [net, index] of Object.entries(nets)) {
|
||||
nets_arr.push(`(net ${index} "${net}")`)
|
||||
add_nets_arr.push(`(add_net "${net}")`)
|
||||
}
|
||||
|
||||
const netclass = kicad_netclass.replace('__ADD_NET', add_nets_arr.join('\n'))
|
||||
const nets_text = nets_arr.join('\n')
|
||||
const footprint_text = footprints.join('\n')
|
||||
return `
|
||||
|
||||
${kicad_prefix}
|
||||
${nets_text}
|
||||
${netclass}
|
||||
${footprint_text}
|
||||
${kicad_suffix}
|
||||
|
||||
`
|
||||
}
|
11
test/fixtures/absolem.yaml
vendored
11
test/fixtures/absolem.yaml
vendored
|
@ -54,6 +54,10 @@ points:
|
|||
home:
|
||||
bind: [10]
|
||||
top:
|
||||
key:
|
||||
footprints:
|
||||
- type: mx
|
||||
|
||||
thumbfan:
|
||||
anchor:
|
||||
ref: inner_bottom
|
||||
|
@ -152,4 +156,9 @@ outline:
|
|||
name: middle
|
||||
operation: stack
|
||||
pcb:
|
||||
edge: outline
|
||||
edge: outline
|
||||
footprints:
|
||||
- type: promicro
|
||||
between:
|
||||
- ref: inner_top
|
||||
- ref: mirror_inner_top
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue