Compare commits

...

58 Commits

Author SHA1 Message Date
King Kévin 0c4987cd21 doc: overall improvement 2022-11-14 23:40:17 +01:00
King Kévin 3001cc643a doc: fix picture links 2022-11-13 16:11:36 +01:00
King Kévin 6e1c31dc20 doc: add pictures 2022-11-13 16:10:28 +01:00
King Kévin d07b963fe1 doc: add v2 change log 2022-11-13 15:58:20 +01:00
King Kévin 65347afc6c brd: increase tab size for V-cut 2022-11-13 15:54:54 +01:00
King Kévin 100885158c lib: update repo 2022-11-13 15:54:17 +01:00
King Kévin 82e1625925 sch: correct corrector position 2022-10-21 13:26:03 +02:00
King Kévin 041d02550f brd: prepare for panel 2022-10-21 13:25:32 +02:00
King Kévin d62c6ab718 brd: fix LED placement 2022-09-12 15:28:31 +02:00
King Kévin ac2b3405ae sch: complete bom 2022-08-12 16:47:02 +02:00
King Kévin 6a8f701bc3 remove lepton/rindove v1 design 2022-08-11 11:44:27 +02:00
King Kévin cf80f5126a make: add kicad scripts 2022-08-11 11:41:11 +02:00
King Kévin 853e962b98 sch/brd: copy design to kicad 2022-08-11 11:40:35 +02:00
King Kévin 87b8f56bba lib: generate library for kicad 2022-08-11 11:38:33 +02:00
King Kévin b146df5098 switch to version 2 2022-08-11 11:31:16 +02:00
King Kévin 208e5e2156 README: document OVP LED 2022-05-18 17:35:59 +02:00
King Kévin b386c5b15f document v1 in changelog 2022-05-18 17:31:17 +02:00
King Kévin 1f594f997a update library repo 2022-05-18 17:15:01 +02:00
King Kévin ce526a753e rake: export gerber in a directory 2022-05-18 17:11:53 +02:00
King Kévin f6f612837c rake: ignore stdout when exporting svg 2022-05-18 17:11:22 +02:00
King Kévin d4d39c742e brd: cleanup 2022-05-18 17:08:01 +02:00
King Kévin e5d831d11d brd: minor, clear stub 2022-04-16 10:17:11 +02:00
King Kévin c38bfd7936 brd: improve shield 2022-04-16 10:13:16 +02:00
King Kévin 8a36fbd62c brd: fix hole trace clearance issue 2022-04-16 10:08:53 +02:00
King Kévin 906ccac431 brd: add QR code 2022-04-14 14:40:54 +02:00
King Kévin c14b543b1c brd: fix plug paste 2022-04-14 14:28:07 +02:00
King Kévin 5b0ca4ee73 lib: list used parts 2022-04-14 14:13:20 +02:00
King Kévin b1402124fb sch: fill description 2022-04-14 14:12:54 +02:00
King Kévin 8a40d9d324 brd: cleanup 2022-04-14 13:46:17 +02:00
King Kévin 05da2fe9e0 brd: v1 routed 2022-04-14 13:23:48 +02:00
King Kévin 3314ba3232 sch: simplify debug header 2022-04-14 13:22:11 +02:00
King Kévin 698b54f518 sch: use single resistor for both LEDs 2022-04-13 17:17:39 +02:00
King Kévin f6f8dac594 sch: add OVP status LEDs 2022-04-12 15:48:55 +02:00
King Kévin edb6c05d60 lib: add LED 2022-04-12 15:48:35 +02:00
King Kévin 3ca4984dbb sch: replace comparator 2022-04-12 15:23:59 +02:00
King Kévin af77464f16 lib: add LM339 quad-comparator 2022-04-12 15:23:13 +02:00
King Kévin b7fce82fd8 sch: use LDO as voltage reference 2022-04-12 15:16:06 +02:00
King Kévin 09a33c8030 lib: add LDO 2022-04-12 15:15:01 +02:00
King Kévin 76a8e51616 sch: fix and improve pMOS control 2022-04-08 16:42:05 +02:00
King Kévin 5ea1d7ff1e sch: use diode for power source 2022-04-08 16:32:30 +02:00
King Kévin 57f1912036 lib: add BAV74 diode 2022-04-08 16:31:46 +02:00
King Kévin c88e8428e8 README: fix usage 2022-04-08 16:28:36 +02:00
King Kévin 2cea26444f sch: use fixed USB-C plug 2022-04-08 11:04:47 +02:00
King Kévin 1ef7bab466 lib: export fixed USB-C plug 2022-04-08 11:04:09 +02:00
King Kévin 16b69049a6 start v1 development 2022-04-08 11:03:35 +02:00
King Kévin 6e0ce9c3a6 add changelog, listing design errors 2022-04-08 10:58:31 +02:00
King Kévin 286c1ee872 README: better describe over-voltage protection 2022-04-08 10:57:55 +02:00
King Kévin f7bde7ea28 brd: minor cleanup 2022-04-06 13:07:49 +02:00
King Kévin 40e0972622 brd: add pullback DRC rule 2022-03-23 18:09:56 +01:00
King Kévin 2f3f9abb59 brd: add QR code 2022-03-23 17:55:08 +01:00
King Kévin 6d803b2504 add project description 2022-03-23 11:37:40 +01:00
King Kévin b7f120f00e brd: first completed layout 2022-03-23 10:50:33 +01:00
King Kévin 9bfda73719 sch: first completed design 2022-03-23 10:50:33 +01:00
King Kévin 7efd21e30c lib: add generated parts 2022-03-23 10:50:33 +01:00
King Kévin 1625d23247 lib: define parts used by project 2022-03-23 10:50:33 +01:00
King Kévin d6c219b381 lib: prefer manufacturer footprint 2022-03-23 10:50:28 +01:00
King Kévin 5a71e68dce lib: add generic chassis symbol 2022-03-23 10:49:54 +01:00
King Kévin 7052fb69bb rename project 2022-03-23 10:49:54 +01:00
63 changed files with 16781 additions and 1575 deletions

46
.gitignore vendored
View File

@ -1,31 +1,35 @@
# schematic lepton-EDA
*.sch
# board layout pcb-rnd
*.lht
*.lht.*
*.versioned.lht
# KiCAD
*.kicad_prl
*.kicad_pro-bak
*.xml
fp-info-cache
# temporary files
*~
*.versioned.sch
\#*\#
# outputs
*.svg
*.png
*.pdf
*.ps
*.zip
*.brd.*
*.ast
*.g2l
*.g3l
*.gbl
*.gbo
*.gbp
*.gbs
*.gko
*.gtl
*.gto
*.gtp
*.gts
*.xln
*.tdx
\#*\#
*.notes.txt
*.bom.csv
*.cost.csv
*.cpl.csv
*.versioned.*
fabrication
# scripts and utilities
*.json
*.rb
geda/footprints/
# panel files
panel.*
panel

View File

@ -1,10 +1,23 @@
config:
output: coraleda
output: kicad
pattern:
densityLevel: 'N'
lineWidth:
silkscreen: 0.2
polarityMark: none
preferManufacturer: false
preferManufacturer: true
smoothPadCorners: false
library:
- capacitor/c0603
- connector/usb-c_xkb_u262-24xn-4bv60
- transistor/pmos_40p05
- ic/comparator_lm393@so
- diode/zener@sod523
- resistor/r0603
- connector/header-2.54@1x10
- diode/schottky@sod523
- connector/usb-c_xkb_u261-24xn-4bc2ls
- diode/bav74
- vreg/ldo_holtek_ht75xx
- ic/comparator_lm339@tssop
- diode/led0603

52
CHANGELOG.md 100644
View File

@ -0,0 +1,52 @@
v2
--
first production batch.
redrawn in KiCAD.
removed debug pins.
v1
--
second prototype built.
needs a couple of small fixes, but works much better.
fixes (from v0):
- an LDO replaces the zener diode as voltage reference
- the voltage reference (2.1V) is below common-mode input-voltage range
- USB-C plug tab mounting holes made larger
additions:
- quad op-amp instead of dual op-amp is used
- other 2 op-amp circuits are used to indicate over-voltage using an LED
- more compact dual common-cathode diodes are used
errors:
- no decoupling caps around LDO
- no clearance around USB-C receptacle mount holes, causing the non-plated hole to be fabbed plated, and shorting ground to internal layers
v0
--
first prototype, with pin header to debug
the over-voltage protection is based on an design described by Texas Instruments, in Analog Engineer's Circuit: Amplifiers, SNOAA20, Overvoltage protection with comparator circuit.
this design is not ideal for our case though.
a Zener diode is used as reference voltage.
it requires at least 1 mA to operate.
this is already a lot for my application.
but 1 mA is when VBUS is at it's minimum of 4.75V.
at 35V this would result in 21 mA.
this power is mainly dissipated by the resistor limiting the current going through the diode.
the dissipated ~0.6W exceeds the 0.1W rating of the resistor, also heating up a zone of the board to 100 °C.
the reference voltage is current dependent, thus the cutoff voltage goes above 5.5V.
this is not too much of a problem because VBUS also exceeds this voltage, but it's not ideal.
design errors:
- the footprint for the USB-C plug has too small mounting holes
- the LM393 is actually an open-collector comparator, but the circuit uses it as push-pull
- the zener diode needs at least 1 mA to be used as voltage reference, not 10 µA (Ileakage and Ibias/Ikz are mixed)
- the design does not respect the common-mode input-voltage range (up to Vcc-2)

View File

@ -1,19 +1,22 @@
this will describe how to generate the output file form the sources.
this will describe how to generate the output files form the sources.
requirements
============
to be able to generate the outputs you need following software:
to be able to generate the outputs, you need following software:
- rake: the central script taking care of generating the output files (Makefile is too cumbersome to parse files)
- [QEDA](http://qeda.org/): to generate footprints for the parts
- [Lepton EDA](https://github.com/lepton-eda/lepton-eda): for the schematic capture
- [pcb-rnd](http://repo.hu/projects/pcb-rnd/): for the board layout
the output generation is automatized.
- [KiCad](https://www.kicad.org/): EDA software used for schematic capture and board layout
- [PcbDraw](https://github.com/yaqwsx/PcbDraw): to generate board layout rendering
- [KiKit](https://github.com/yaqwsx/KiKit): to generate fabrications files (Gerber, Excellon)
- [KiAuto](https://github.com/INTI-CMNB/KiAuto): to generate schematic printout (PDF)
- [KiBoM](https://github.com/SchrodingersGat/KiBoM): to generate Bill of Material (CSV)
compiling
=========
to generate schematic, BoM, board render, and fabrication output, run `make`.
library
-------
@ -21,11 +24,13 @@ almost all of the symbols and footprints used in the schematic and board layout
the `library` folder contains the QEDA parts definitions.
to install QEDA using NPM from the official repository:
~~~
sudo npm install -g qeda
~~~
to install QEDA from the sources:
~~~
git clone https://github.com/qeda/qeda
cd qeda
@ -34,49 +39,59 @@ sudo npm install --global
~~~
to generate the parts:
~~~
rake library
make lib
~~~
this will use the parts definition (.yaml files) in the `library` to generate [gEDA gschem](http://wiki.geda-project.org/geda:gaf)/[Lepton EDA](https://github.com/lepton-eda/lepton-eda) symbols (.sym files) in the `geda/symbols` folder, and [coralEDA pcb-rnd](http://repo.hu/projects/pcb-rnd/) footprints (.lht files) in the `coraleda/subc` folder.
only the QEDA parts in subfolders within `library` come from the [QEDA library](https://doc.qeda.org/library/), but the files are included in this project for simplicity and archiving purposes.
all other parts are custom and written for this project.
this will use the parts definition (.yaml files) in the `library` to generate the symbols (.sym files) and footprints used by KiCAD in the `kicad` folder.
schematic
---------
the `.sch` file is the schematic source file.
it has been drawn using [Lepton EDA](https://github.com/lepton-eda/lepton-eda).
the `.kicad_sch` file is the schematic source file.
it has been drawn using the [KiCAD eeschema](https://www.kicad.org/) schematic editor.
it uses standard symbols, and the ones in the `geda/symbols/` folder.
it uses standard symbols, and the ones in the `kicad/` folder.
most symbols are generated by QEDA as described above.
to export as pdf:
~~~
rake print
make print
~~~
BOM
---
to export the bill of material (as CSV):
~~~
rake bom
make bom
~~~
board
-----
the `.lht` file is the board layout source file.
it has been drawn using [coralEDA pcb-rnd](http://repo.hu/projects/pcb-rnd/).
the `.kicad_brd` file is the board layout source file.
it has been drawn using the [KiCAD pcbnew](https://docs.kicad.org/6.0/en/pcbnew/pcbnew.html) PCB editor.
it uses the symbols from the `coraleda/subc/` folder.
it uses the footprints from the `kicad/` folder.
most symbols are generated by QEDA as described above.
`oshw_logo.lht` is just the Open Source Hardware Logo.
it been generated from https://oshwlogo.cuvoodoo.info/.
to export gerber files for PCB manufacturer (and photo preview + overview document):
~~~
rake fabrication
make fabrication
~~~
versioning
----------
the source schematic and board layout do not include version information.
when generating schematic or board fabrication output, a copy of the source files with date and version information is done as `.versioned.` files.
the date corresponds to the last changes (i.e. commit).
the version is formatted as `v.r`:
- `v` corresponds to the major version information defined in `version`
- `r` corresponds to the total number of changes done to the source files

View File

@ -0,0 +1,12 @@
package;x;y;rot
LEDC2012X80N;0;0;-90
LEDC1608X90N;0;0;-90
UC1608X55N;0;0;-90
CAPC1608X92N;0;0;-90
SOT95P237X112-3N;0;0;180
CONNECTOR_MY-1220-03;0;-1.1;0
CONNECTOR_XKB_U262-24XN-4BV64;0;-1.3;0
CONNECTOR_U231-09XN-4BLRA00;0;-3.0;0
SOP254P976X355-14N;0;0;-90
SOP65P640X120-20N;0;0;-90
CONNECTOR_HDMI-001S;0;1.1;0
1 package x y rot
2 LEDC2012X80N 0 0 -90
3 LEDC1608X90N 0 0 -90
4 UC1608X55N 0 0 -90
5 CAPC1608X92N 0 0 -90
6 SOT95P237X112-3N 0 0 180
7 CONNECTOR_MY-1220-03 0 -1.1 0
8 CONNECTOR_XKB_U262-24XN-4BV64 0 -1.3 0
9 CONNECTOR_U231-09XN-4BLRA00 0 -3.0 0
10 SOP254P976X355-14N 0 0 -90
11 SOP65P640X120-20N 0 0 -90
12 CONNECTOR_HDMI-001S 0 1.1 0

80
Makefile 100644
View File

@ -0,0 +1,80 @@
# project file name (use for schematic and board layout)
NAME ?= pd_blocker
# path to qeda
QEDA := qeda
# path to InteractiveHtmlBom
IBOMGEN := /usr/share/kicad/scripting/plugins/InteractiveHtmlBom/generate_interactive_bom.py
# read project version
VERSION := $(shell cat version)
# current date for stamping output
DATE = $(shell date +%Y-%m-%d)
# revision based on number of changes on schematic or board layout
REVISION := $(shell git log --pretty=oneline "${NAME}.kicad_sch" "${NAME}.kicad_pcb" | wc -l)
# generate file with version information
VERSIONED_EXT = kicad_sch kicad_pcb kicad_pro json
define version_rule
%.versioned.$1: %.$1
cp $$< $$@
sed --in-place 's/\$$$$version\$$$$/${VERSION}/g' $$@
sed --in-place 's/\$$$$date\$$$$/${DATE}/g' $$@
sed --in-place 's/\$$$$revision\$$$$/${REVISION}/g' $$@
endef
$(foreach EXT,$(VERSIONED_EXT),$(eval $(call version_rule,$(EXT))))
FABRICATION_DIR := fabrication
IBOM := ${FABRICATION_DIR}/ibom.html
all: ${NAME}.sch.pdf ${NAME}.brd-top.png ${NAME}.brd-bot.png ${NAME}.bom.csv fab
fab: ${FABRICATION_DIR} ${IBOM}
# generate fabrication files (gerbers/drill/BoM/PnP)
${FABRICATION_DIR}: ${NAME}.versioned.kicad_sch ${NAME}.versioned.kicad_pcb
kikit fab jlcpcb --drc --assembly --schematic $^ $@
# generate interactive BoM
${IBOM}: ${NAME}.versioned.kicad_pcb
$(IBOMGEN) --no-browser --dest-dir `dirname $@` --name-format `basename $@ ".html"` --show-fields "Value" $< &>/dev/null
# generate symbols and footprints from parts
lib:
$(QEDA) generate qeda
# generate printable version (PDF) of schematic
%.sch.pdf: %.versioned.kicad_sch %.versioned.kicad_pro
eeschema_do export $< .
mv $*.versioned.pdf $@
# generate render from layout (top side)
%.brd-top.png: %.versioned.kicad_pcb
pcbdraw --silent $< --dpi 600 $@
# generate render from layout (bottom side)
%.brd-bot.png: %.versioned.kicad_pcb
pcbdraw --silent $< --dpi 600 --back $@
# export Bill of Material (as CSV)
%.bom.csv: %.versioned.kicad_sch %.versioned.kicad_pro
eeschema_do bom_xml $< .
kibom $*.versioned.xml $@
# generate panel
PANEL_DIR := panel
panel: panel.kicad_pcb
panel.kicad_pcb: ${NAME}.versioned.kicad_pcb ${NAME}.versioned.kicad_pro ${NAME}.versioned.kicad_sch ${NAME}.versioned.json
kikit panelize -p ${NAME}.versioned.json ${NAME}.versioned.kicad_pcb $@
sed --in-place 's/\"missing_courtyard\": \"warning\"/\"missing_courtyard\": \"ignore\"/g' $(patsubst %.kicad_pcb,%.kicad_pro,$@) # the mouse bites don't have a courtyard
kikit fab jlcpcb --drc --assembly --missingError --schematic ${NAME}.versioned.kicad_sch $@ ${PANEL_DIR}
pcbdraw --silent $@ --dpi 600 panel.brd-top.png
pcbdraw --silent $@ --dpi 600 --back panel.brd-bot.png
clean:
rm -f $(foreach EXT,$(VERSIONED_EXT),${NAME}.versioned.$(EXT))
rm -f ${NAME}.sch.pdf ${NAME}.brd-top.png ${NAME}.brd-bot.png ${NAME}.versioned.xml ${NAME}.bom.csv
rm -f ${NAME}.versioned.kicad_prl ${NAME}.versioned.kicad_pro-bak ${NAME}.versioned.xml ${NAME}.versioned.csv
rm -f ${IBOM}
rm -rf ${FABRICATION_DIR}
rm -f panel.kicad_pcb panel.kicad_pro
rm -rf ${PANEL_DIR}

View File

@ -1,7 +1,49 @@
these are the hardware design files for **insert project name here**.
The PD blocker removes Power Delivery (PD) capabilities from USB-C connections and provides over-voltage protection.
<img src="picture/v2_front.webp" title="front" height="250"/>
<img src="picture/v2_back.webp" title="back" height="250"/>
purpose
=======
Some USB-C devices do not require the Power Delivery features available on USB-C, mainly higher voltage and current.
The device could not even be rated for higher voltages.
But chargers might be stuck at higher voltage, or mischievous eMarked cables (with PD-capable chips built in) could raise the voltage, permanently damaging it.
The PD blocker protects your [expensive] USB-C device from such damages.
usage
=====
Insert the PD blocker in line, between the power source (e.g. charger or host computer), cable, and your device.
It can be inserted between any two of these components, and will work the same.
Plug and receptacle can be either side, and it is reversible along the axis of the connectors (like normal USB-C connectors).
The PD blocker will prevent any Power Delivery communication, such as raising the voltage.
And when over-voltage is detected (Vbus > 5.5V), power is cut and an OVP LED indicating the culprit side lights up.
Connect the PD blocker before the target device for the protection to take effect before it can reach it.
All other features of USB-C are preserved (e.g. USB2, USB3, USB4, SBU, orientation detection)
Some alternate modes requiring PD communication will not work anymore though.
mode of operation
=================
To prevent PD communication, capacitors are placed on the CC lines.
They smooth out the 300 Kbps BMC signal used for PD communication.
It still allows the identification of Rp, Rd, and Ra used for orientation and role detection.
Additionally there is an over-voltage protection circuit.
VBUS (on either side) is compared to a reference voltage.
When VBUS is below 5.5V, p-channel MOSFETs are switched on, and allow VBUS going from one side to the other.
When VBUS is above 5.5V, the p-channel MOSFETs are switched off, and prevent VBUS interconnection, cutting the power.
warning
=======
The PD blocker can block up to 36V.
PD rev 2.0 specifies voltages up to 20V.
PD rev 3.0 specifies voltages up to 48V, but I haven't seen any power source using this new capability yet.
The PD blocker can take a seconds (at 5.6V) until the over-voltage protection take effect.
Connect the PD blocker before the target device for the protection to take effect before it can reach it.

180
Rakefile
View File

@ -1,180 +0,0 @@
# encoding: utf-8
# ruby: 2.1.0
=begin
Rakefile to manage hardware projects
uses Lepton EDA for schematic and pcb-rnd for board layouts.
Rakefile instead of Makefile for better text file parsing capabilities.
=end
require 'rake/clean'
require 'csv' # to export BOM and costs
# =================
# project variables
# =================
# common name used for file names
name = "template"
# project version, read from "version" file
raise "define project version in 'version' file" unless File.exist? "version"
version = IO.read("version").split("\n")[0]
# current date for stamping output
date = Time.now.strftime("%Y-%m-%d")
# revision based on number of changes on schematic or board layout and current git commit
changes = `git log --pretty=oneline "#{name}.sch" "#{name}.lht" | wc -l`.chomp.to_i
commit = `git rev-parse --short HEAD`.chomp
revision = "#{changes} (#{commit})"
# path to qeda"
qeda = "qeda"
# ==========
# main tasks
# ==========
desc "main building task"
task :default => [:print, :fabrication, :bom, :pnp]
desc "print schematic and layout (as pdf)"
prints = [ "#{name}.sch.pdf", "#{name}.brd.pdf", "#{name}.brd-top.svg", "#{name}.brd-bottom.svg" ]
task :print => prints
CLEAN.include([ "#{name}.versioned.sch", "#{name}.versioned.lht" ])
CLOBBER.include(prints)
desc "generate fabrication gerbers (as archive)"
gerbers = [ "#{name}.brd.asb", "#{name}.brd.ast", "#{name}.brd.gbl", "#{name}.brd.gbo", "#{name}.brd.gbp", "#{name}.brd.gbs", "#{name}.brd.gko", "#{name}.brd.gtl", "#{name}.brd.gto", "#{name}.brd.gtp", "#{name}.brd.gts", "#{name}.brd.xln", "#{name}.brd.g2l", "#{name}.brd.g3l" ]
fab = [ "#{name}.brd.zip" ]
task :fabrication => fab
CLEAN.include(gerbers)
CLOBBER.include(fab)
desc "generate symbols and footprints from parts"
task :library do
sh "#{qeda} config output geda"
sh "#{qeda} generate ."
sh "#{qeda} config output coraleda"
sh "#{qeda} generate ."
end
desc "export BOMs from schematic"
boms = [ "#{name}.bom.csv" ]
task :bom => boms
CLOBBER.include(boms)
desc "export PnP placement"
pnps = [ "#{name}.cpl.csv" ]
task :pnp => pnps
CLOBBER.include(pnps)
# ===============
# file generation
# ===============
desc "generate schematic with version information all symbols embedded"
rule ".versioned.sch" => ".sch" do |t|
sh "cp #{t.source} #{t.name}"
sh "lepton-embed --embed #{t.name} 2> /dev/null"
sh "sed --in-place 's/\\$version\\$/#{version}/' #{t.name}"
sh "sed --in-place 's/\\$date\\$/#{date}/' #{t.name}"
sh "sed --in-place 's/\\$revision\\$/#{revision}/' #{t.name}"
end
desc "generate board layout with version information"
rule ".versioned.lht" => ".lht" do |t|
sh "cp #{t.source} #{t.name}"
sh "sed --in-place 's/\\$version\\$/#{version}/' #{t.name}"
sh "sed --in-place 's/\\$date\\$/#{date}/' #{t.name}"
sh "sed --in-place 's/\\$revision\\$/#{revision}/' #{t.name}"
end
desc "generate printable version (PDF) of schematic"
rule ".sch.pdf" => ".versioned.sch" do |t|
sh "lepton-cli export --color --paper=iso_a4 --layout=landscape --output=#{t.name} #{t.source} 2> /dev/null"
end
desc "generate printable version (PostScript) of board layout"
rule ".brd.ps" => ".versioned.lht" do |t|
sh "pcb-rnd -x ps --ps-color --media A4 --psfile #{t.name} #{t.source} 2> /dev/null"
end
desc "generate printable version (PDF) of board layout"
rule ".brd.pdf" => ".brd.ps" do |t|
sh "ps2pdf -sPAPERSIZE=a4 -dEPSCrop #{t.source} #{t.name}"
end
desc "generate photo realistic picture from layout (top side)"
rule ".brd-top.svg" => ".versioned.lht" do |t|
sh "pcb-rnd -x svg --photo-mode --outfile #{t.name} #{t.source} 2> /dev/null"
end
desc "generate photo realistic picture from layout (bottom side)"
rule ".brd-bottom.svg" => ".versioned.lht" do |t|
sh "pcb-rnd -x svg --photo-mode --flip --outfile #{t.name} #{t.source} 2> /dev/null"
end
desc "archive gerbers"
rule ".brd.zip" => ".versioned.lht" do |t|
base = File.basename(t.source, ".versioned.lht")
puts base
sh "pcb-rnd -x cam gerber:JLC_PCB --outfile #{base}.brd #{t.source} 2> /dev/null"
sh "zip --quiet #{t.name} #{base}.brd.xln #{base}.brd.a* #{base}.brd.g*"
end
desc "generate BOM file from schematic"
rule ".bom.csv" => ".sch" do |t|
attributes = ["device", "value", "description", "footprint", "manufacturer", "mpn", "datasheet", "lcsc", "digikey"]
bom_data = bom2(t.prerequisites[0], attributes)
CSV.open(t.name, "wb") do |csv|
all_attributes = ["refdes","qty"] + attributes
csv << all_attributes
bom_data.each do |line|
csv << all_attributes.collect{|attribute| line[attribute]}
end
end
end
desc "generate pick-and-place file from board"
rule ".cpl.csv" => [".versioned.lht", "mass_prop.sh", "pnp_fab.tab"] do |t|
sh "./mass_prop.sh #{t.prerequisites[0]} pnp_fab.tab" # add fab placement offsets
sh "pcb-rnd -x XY --xyfile #{t.name} --xy-unit mm --format 'JLCPCB' --vendor jlcpcb #{t.prerequisites[0]}" # export XY file in JLCPCB format
end
# ================
# helper functions
# ================
# generate gnetlist bom2 and parse them
# arguments: schematic=schematic to use, attributes=attributes to use for generating bom2
# returns an array of hash. key is the attribute name, value is the attribute value
def bom2(schematic, attributes)
to_return = []
# force attributes to be an array
attributes = case attributes
when String
[attributes]
when Array
attributes
else
[attributes.to_s]
end
# generate bom2
list = `lepton-netlist --backend bom2 --backend-option attribs=#{attributes*','} --quiet --output - #{schematic} 2> /dev/null`
list = list.each_line {|l| '"' + l + '"' + '\n' }
list.gsub!(/^(.+)/, '"\1')
list.gsub!(/(.+)$/, '\1"')
list.gsub!(/(?!http):(?!\/\/)/, '\1":"\2') # protect the values between ':' (such as URLs)
# parse bom2
csv = CSV.parse(list, col_sep: ":", quote_char: '"')
if csv.empty? then
$stderr.puts "no parts found for BOM"
return []
end
csv[1..-1].each do |row|
line = {}
row.each_index do |col|
line[csv[0][col]] = row[col] unless row[col] == "unknown"
end
to_return << line
end
return to_return
end

42
bom.ini 100644
View File

@ -0,0 +1,42 @@
[BOM_OPTIONS]
ignore_dnf = 0
number_rows = 0
group_connectors = 1
test_regex = 0
merge_blank_fields = 1
output_file_name = %O%V
[IGNORE_COLUMNS]
; Any column heading that appears here will be excluded from the Generated BoM
; Titles are case-insensitive
Part
Part Lib
Footprint
Footprint Lib
Build Quantity
sheetpath
[COLUMN_ORDER]
; Columns will apear in the order they are listed here
; Titles are case-insensitive
References
Value
Quantity Per PCB
Description
Part
Part Lib
Footprint
Footprint Lib
Build Quantity
LCSC
Datasheet
[GROUP_FIELDS]
; List of fields used for sorting individual components into groups
; Components which match (comparing *all* fields) will be grouped together
; Field names are case-insensitive
Part
Part Lib
Value
Footprint
Footprint Lib

View File

@ -1,421 +0,0 @@
# footprint generated from CuVoodoo Land Pattern
# author: King Kévin
# version: 1
# date: 2019-05-13
li:pcb-rnd-subcircuit-v6 {
ha:subc.1 {
uid = any_24_ASCII_characters_
ha:attributes {
footprint = open source hardware logo
}
ha:data {
li:padstack_prototypes {
}
li:objects {
}
li:layers {
ha:top-silkscreen {
lid = 1
ha:type {
top = 1
silk = 1
}
li:objects {
ha:line.2{
clearance = 0
x1 = 0.15mm
y1 = 1.8mm
x2 = 0.75mm
y2 = 1.8mm
thickness = 0.3mm
}
ha:line.3{
clearance = 0
x1 = 1.8mm
y1 = 5.8500000000000005mm
x2 = 1.8mm
y2 = 6.45mm
thickness = 0.3mm
}
ha:line.4{
clearance = 0
x1 = 5.8500000000000005mm
y1 = 1.8mm
x2 = 6.45mm
y2 = 1.8mm
thickness = 0.3mm
}
ha:line.5{
clearance = 0
x1 = 1.8mm
y1 = 0.15mm
x2 = 1.8mm
y2 = 0.75mm
thickness = 0.3mm
}
ha:line.6{
clearance = 0
x1 = 0.15mm
y1 = 2.4mm
x2 = 0.75mm
y2 = 2.4mm
thickness = 0.3mm
}
ha:line.7{
clearance = 0
x1 = 2.4mm
y1 = 5.8500000000000005mm
x2 = 2.4mm
y2 = 6.45mm
thickness = 0.3mm
}
ha:line.8{
clearance = 0
x1 = 5.8500000000000005mm
y1 = 2.4mm
x2 = 6.45mm
y2 = 2.4mm
thickness = 0.3mm
}
ha:line.9{
clearance = 0
x1 = 2.4mm
y1 = 0.15mm
x2 = 2.4mm
y2 = 0.75mm
thickness = 0.3mm
}
ha:line.10{
clearance = 0
x1 = 0.15mm
y1 = 3mm
x2 = 0.75mm
y2 = 3mm
thickness = 0.3mm
}
ha:line.11{
clearance = 0
x1 = 3mm
y1 = 5.8500000000000005mm
x2 = 3mm
y2 = 6.45mm
thickness = 0.3mm
}
ha:line.12{
clearance = 0
x1 = 5.8500000000000005mm
y1 = 3mm
x2 = 6.45mm
y2 = 3mm
thickness = 0.3mm
}
ha:line.13{
clearance = 0
x1 = 3mm
y1 = 0.15mm
x2 = 3mm
y2 = 0.75mm
thickness = 0.3mm
}
ha:line.14{
clearance = 0
x1 = 0.15mm
y1 = 3.5999999999999996mm
x2 = 0.75mm
y2 = 3.5999999999999996mm
thickness = 0.3mm
}
ha:line.15{
clearance = 0
x1 = 3.5999999999999996mm
y1 = 5.8500000000000005mm
x2 = 3.5999999999999996mm
y2 = 6.45mm
thickness = 0.3mm
}
ha:line.16{
clearance = 0
x1 = 5.8500000000000005mm
y1 = 3.5999999999999996mm
x2 = 6.45mm
y2 = 3.5999999999999996mm
thickness = 0.3mm
}
ha:line.17{
clearance = 0
x1 = 3.5999999999999996mm
y1 = 0.15mm
x2 = 3.5999999999999996mm
y2 = 0.75mm
thickness = 0.3mm
}
ha:line.18{
clearance = 0
x1 = 0.15mm
y1 = 4.2mm
x2 = 0.75mm
y2 = 4.2mm
thickness = 0.3mm
}
ha:line.19{
clearance = 0
x1 = 4.2mm
y1 = 5.8500000000000005mm
x2 = 4.2mm
y2 = 6.45mm
thickness = 0.3mm
}
ha:line.20{
clearance = 0
x1 = 5.8500000000000005mm
y1 = 4.2mm
x2 = 6.45mm
y2 = 4.2mm
thickness = 0.3mm
}
ha:line.21{
clearance = 0
x1 = 4.2mm
y1 = 0.15mm
x2 = 4.2mm
y2 = 0.75mm
thickness = 0.3mm
}
ha:line.22{
clearance = 0
x1 = 0.15mm
y1 = 4.8mm
x2 = 0.75mm
y2 = 4.8mm
thickness = 0.3mm
}
ha:line.23{
clearance = 0
x1 = 4.8mm
y1 = 5.8500000000000005mm
x2 = 4.8mm
y2 = 6.45mm
thickness = 0.3mm
}
ha:line.24{
clearance = 0
x1 = 5.8500000000000005mm
y1 = 4.8mm
x2 = 6.45mm
y2 = 4.8mm
thickness = 0.3mm
}
ha:line.25{
clearance = 0
x1 = 4.8mm
y1 = 0.15mm
x2 = 4.8mm
y2 = 0.75mm
thickness = 0.3mm
}
ha:line.26{
clearance = 0
x1 = 1.8mm
y1 = 1.35mm
x2 = 4.8mm
y2 = 1.35mm
thickness = 0.3mm
}
ha:line.27{
clearance = 0
x1 = 5.25mm
y1 = 1.8mm
x2 = 5.25mm
y2 = 4.8mm
thickness = 0.3mm
}
ha:line.28{
clearance = 0
x1 = 4.8mm
y1 = 5.25mm
x2 = 1.8mm
y2 = 5.25mm
thickness = 0.3mm
}
ha:line.29{
clearance = 0
x1 = 1.35mm
y1 = 4.8mm
x2 = 1.35mm
y2 = 1.8mm
thickness = 0.3mm
}
ha:arc.30{
clearance = 0
x = 1.8mm
y = 1.8mm
width = 0.45mm
height = 0.45mm
thickness = 0.3mm
astart = 0
adelta = -90
}
ha:arc.31{
clearance = 0
x = 4.8mm
y = 1.8mm
width = 0.45mm
height = 0.45mm
thickness = 0.3mm
astart = -90
adelta = -90
}
ha:arc.32{
clearance = 0
x = 4.8mm
y = 4.8mm
width = 0.45mm
height = 0.45mm
thickness = 0.3mm
astart = 180
adelta = -90
}
ha:arc.33{
clearance = 0
x = 1.8mm
y = 4.8mm
width = 0.45mm
height = 0.45mm
thickness = 0.3mm
astart = 90
adelta = -90
}
ha:line.34{
clearance = 0
x1 = 1.8mm
y1 = 1.8mm
x2 = 3mm
y2 = 1.8mm
thickness = 0.3mm
}
ha:line.35{
clearance = 0
x1 = 3mm
y1 = 1.8mm
x2 = 3mm
y2 = 3mm
thickness = 0.3mm
}
ha:line.36{
clearance = 0
x1 = 3mm
y1 = 3mm
x2 = 1.8mm
y2 = 3mm
thickness = 0.3mm
}
ha:line.37{
clearance = 0
x1 = 1.8mm
y1 = 3mm
x2 = 1.8mm
y2 = 1.8mm
thickness = 0.3mm
}
ha:line.38{
clearance = 0
x1 = 4.8mm
y1 = 1.8mm
x2 = 3.5999999999999996mm
y2 = 1.8mm
thickness = 0.3mm
}
ha:line.39{
clearance = 0
x1 = 3.5999999999999996mm
y1 = 1.8mm
x2 = 3.5999999999999996mm
y2 = 2.4mm
thickness = 0.3mm
}
ha:line.40{
clearance = 0
x1 = 3.5999999999999996mm
y1 = 2.4mm
x2 = 4.8mm
y2 = 2.4mm
thickness = 0.3mm
}
ha:line.41{
clearance = 0
x1 = 4.8mm
y1 = 2.4mm
x2 = 4.8mm
y2 = 3mm
thickness = 0.3mm
}
ha:line.42{
clearance = 0
x1 = 4.8mm
y1 = 3mm
x2 = 3.5999999999999996mm
y2 = 3mm
thickness = 0.3mm
}
ha:line.43{
clearance = 0
x1 = 1.8mm
y1 = 3.5999999999999996mm
x2 = 1.8mm
y2 = 4.8mm
thickness = 0.3mm
}
ha:line.44{
clearance = 0
x1 = 1.8mm
y1 = 4.199999999999999mm
x2 = 3mm
y2 = 4.199999999999999mm
thickness = 0.3mm
}
ha:line.45{
clearance = 0
x1 = 3mm
y1 = 3.5999999999999996mm
x2 = 3mm
y2 = 4.8mm
thickness = 0.3mm
}
ha:line.46{
clearance = 0
x1 = 3.5999999999999996mm
y1 = 3.5999999999999996mm
x2 = 3.5999999999999996mm
y2 = 4.8mm
thickness = 0.3mm
}
ha:line.47{
clearance = 0
x1 = 3.5999999999999996mm
y1 = 4.8mm
x2 = 4.199999999999999mm
y2 = 4.2mm
thickness = 0.3mm
}
ha:line.48{
clearance = 0
x1 = 4.199999999999999mm
y1 = 4.2mm
x2 = 4.799999999999999mm
y2 = 4.8mm
thickness = 0.3mm
}
ha:line.49{
clearance = 0
x1 = 4.799999999999999mm
y1 = 4.8mm
x2 = 4.799999999999999mm
y2 = 3.5999999999999996mm
thickness = 0.3mm
}
}
}
}
}
}
}

View File

@ -1,39 +0,0 @@
#!/bin/sh
#@@example qr(hello world, 1mm)
#@@purpose Generate QR code on silk
#@@desc Generate the specified QR code as silk lines
#@@params text,pixel_size,level
#@@thumbsize 2
#@@param:text ASCII text to encode
#@@param:pixel_size width and height of each pixel
#@@dim:pixel_size
#@@param:level error correction level
#@@optional:level
#@@enum:level:L low
#@@enum:level:H high
#@@default:L
libdir=""
for n in $PCB_RND_PCBLIB/parametric `dirname $0` /usr/local/share/pcb-rnd/pcblib/parametric /usr/share/pcb-rnd/pcblib/parametric
do
if test -f "$n/common.awk"
then
libdir="$n"
break
fi
done
if test -z "$libdir"
then
echo "pcblib/parametric/common.awk not found." >&2
exit 1
fi
awk -f $libdir/common.awk -f `dirname $0`/qr.awk -v "args=$*" -v gen=`basename $0` -v "genfull=$0"

View File

@ -1,62 +0,0 @@
function flush_line(x1, x2, y, w ,n,yy)
{
x1/=2
x2/=2
for(n = 0; n < 3; n++) {
yy = y*w + w/6 + w/3 * n
element_line(x1*w + w/6, yy, x2*w - w/6, yy, w/3)
}
element_line(x1*w + w/6, y*w + w/6, x1*w + w/6, (y+1)*w - w/6, w/3)
element_line(x2*w - w/6, y*w + w/6, x2*w - w/6, (y+1)*w - w/6, w/3)
}
BEGIN {
help_auto()
set_arg(P, "?pixel_size", "1mm")
proc_args(P, "text,pixel_size,level", "text")
pixel_size = parse_dim(P["pixel_size"])
element_begin("", "QR1", "qr(" P["text"] "," P["pixel_size"] "," P["level"] ")" ,0,0, 0,-mil(50))
print "# text=" P["text"]
cmd = "echo '" P["text"] "' | qrencode -t ASCII"
if (P["level"] != "") {
if (tolower(P["level"]) == "h")
cmd = cmd " -l H"
else if (tolower(P["level"]) == "l")
cmd = cmd " -l L"
}
y = 0;
while((cmd | getline line) > 0) {
line = line "-"
# print line
len = length(line)
start = ""
for(x = 1; x < len; x++) {
if (substr(line, x, 1) == "#") {
if (start == "")
start = x;
}
else {
if (start != "") {
flush_line(start, x, y, pixel_size)
start = ""
}
}
}
if (start != "")
flush_line(start, x, y, pixel_size)
y++;
}
# dimension(+spacing/aspect, -dia, +spacing/aspect, dia, "@" spacing*1.2 ";0", "dia")
element_end()
}

5
fp-lib-table 100644
View File

@ -0,0 +1,5 @@
(fp_lib_table
(lib (name "qeda")(type "KiCad")(uri "${KIPRJMOD}/kicad/qeda.pretty")(options "")(descr ""))
(lib (name "kikit")(type "KiCad")(uri "${KIPRJMOD}/kicad/kikit.pretty")(options "")(descr ""))
(lib (name "custom")(type "KiCad")(uri "${KIPRJMOD}/kicad/custom.pretty")(options "")(descr ""))
)

2
gafrc
View File

@ -1,2 +0,0 @@
(source-library ".")
(component-library "./geda/symbols/")

View File

@ -1,18 +0,0 @@
v 20210407 2
P 200 0 200 200 1 0 0
{
T 250 50 5 6 0 1 0 0 1
pinnumber=1
T 250 50 5 6 0 0 0 0 1
pinseq=1
T 250 50 5 6 0 1 0 0 1
pinlabel=1
T 250 50 5 6 0 1 0 0 1
pintype=pwr
}
T 200 250 9 8 1 0 0 3 1
1V8
T 300 0 8 8 0 0 0 0 1
net=1V8:1
L 150 100 200 200 3 10 1 0 -1 -1
L 200 200 250 100 3 10 1 0 -1 -1

View File

@ -1,18 +0,0 @@
v 20210407 2
P 200 0 200 200 1 0 0
{
T 250 50 5 6 0 1 0 0 1
pinnumber=1
T 250 50 5 6 0 0 0 0 1
pinseq=1
T 250 50 5 6 0 1 0 0 1
pinlabel=1
T 250 50 5 6 0 1 0 0 1
pintype=pwr
}
T 200 250 9 8 1 0 0 3 1
3V3
T 300 0 8 8 0 0 0 0 1
net=3V3:1
L 150 100 200 200 3 10 1 0 -1 -1
L 200 200 250 100 3 10 1 0 -1 -1

View File

@ -1,18 +0,0 @@
v 20210407 2
P 200 0 200 200 1 0 0
{
T 250 50 5 6 0 1 0 0 1
pinnumber=1
T 250 50 5 6 0 0 0 0 1
pinseq=1
T 250 50 5 6 0 1 0 0 1
pinlabel=1
T 250 50 5 6 0 1 0 0 1
pintype=pwr
}
T 200 250 9 8 1 0 0 3 1
5V
T 300 0 8 8 0 0 0 0 1
net=5V:1
L 150 100 200 200 3 10 1 0 -1 -1
L 200 200 250 100 3 10 1 0 -1 -1

View File

@ -1,17 +0,0 @@
v 20210407 2
P 100 100 100 200 1 0 1
{
T 158 161 5 4 0 1 0 0 1
pinnumber=1
T 158 161 5 4 0 0 0 0 1
pinseq=1
T 158 161 5 4 0 1 0 0 1
pinlabel=1
T 158 161 5 4 0 1 0 0 1
pintype=pwr
}
L 0 100 200 100 3 0 0 0 -1 -1
T 300 50 8 10 0 0 0 0 1
net=GND:1
L 0 100 100 0 3 0 1 0 -1 -1
L 200 100 100 0 3 0 1 0 -1 -1

View File

@ -1,18 +0,0 @@
v 20210626 2
P 200 0 200 200 1 0 0
{
T 250 50 5 6 0 1 0 0 1
pinnumber=1
T 250 50 5 6 0 0 0 0 1
pinseq=1
T 250 50 5 6 0 1 0 0 1
pinlabel=1
T 250 50 5 6 0 1 0 0 1
pintype=pwr
}
T 200 250 9 8 1 0 0 3 1
VCC
T 300 0 8 8 0 0 0 0 1
net=VCC:1
L 150 100 200 200 3 10 1 0 -1 -1
L 200 200 250 100 3 10 1 0 -1 -1

View File

@ -1,18 +0,0 @@
v 20210407 2
P 200 0 200 200 1 0 0
{
T 250 50 5 6 0 1 0 0 1
pinnumber=1
T 250 50 5 6 0 0 0 0 1
pinseq=1
T 250 50 5 6 0 1 0 0 1
pinlabel=1
T 250 50 5 6 0 1 0 0 1
pintype=pwr
}
T 200 250 9 8 1 0 0 3 1
VTRG
T 300 0 8 8 0 0 0 0 1
net=VTRG:1
L 150 100 200 200 3 10 1 0 -1 -1
L 200 200 250 100 3 10 1 0 -1 -1

View File

@ -1,40 +0,0 @@
v 20210626 2
L 3000 900 3000 0 15 0 0 0 -1 -1
B 0 0 6000 1500 15 0 0 0 -1 -1 0 -1 -1 -1 -1 -1
L 0 900 6000 900 15 0 0 0 -1 -1
T 1000 700 9 10 1 1 0 0 1
date=$date$
T 4300 700 9 10 1 1 0 0 1
org=$organisation$
T 4300 400 9 10 1 1 0 0 1
authors=$authors$
T 3000 1200 9 14 1 1 0 4 1
title=TITLE
T 3100 400 15 8 1 0 0 0 1
AUTHORS:
T 3100 100 15 8 1 0 0 0 1
LICENCE:
T 100 100 15 8 1 0 0 0 1
REVISION:
T 100 1100 15 8 1 0 0 0 1
TITLE:
T 100 400 15 8 1 0 0 0 1
VERSION:
T 0 1600 8 10 0 0 0 0 1
graphical=1
T 3100 700 15 8 1 0 0 0 1
ORGANISATION:
T 100 700 15 8 1 0 0 0 1
DATE:
T 1000 400 9 10 1 1 0 0 1
version=$version$
T 1000 100 9 10 1 1 0 0 1
revision=$revision$
T 4300 100 9 10 1 1 0 0 1
licence=$licence$
T 0 1800 8 10 0 0 0 0 1
device=none
T 0 2000 8 10 0 0 0 0 1
footprint=none
T 0 2200 8 10 0 0 0 0 1
refdes=none

View File

@ -0,0 +1,589 @@
(footprint "qr" (version 20211014) (generator pcbnew)
(layer "F.Cu")
(tedit 0)
(fp_text reference "QR*****" (at 0 8) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp bcf9717e-ae89-404f-aaeb-815660132d6f)
)
(fp_text value "qr" (at 0 -8) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp b6162aec-924d-439b-a32d-537f73656aa9)
)
(fp_rect (start 0.2 -0.2) (end 0.6 0.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 009123f2-f648-40c1-ace8-be29c5b83cef))
(fp_rect (start -0.2 -5.4) (end 0.2 -5) (layer "F.SilkS") (width 0) (fill solid) (tstamp 009e0089-89da-448d-b6e7-3f1a71b49feb))
(fp_rect (start 1.8 -3.8) (end 2.2 -3.4) (layer "F.SilkS") (width 0) (fill solid) (tstamp 00f24ef3-7715-494e-b83a-0ed35ba0e15f))
(fp_rect (start -5 -2.2) (end -4.6 -1.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 01459f80-88b3-4a0c-82b7-001a6b77aeac))
(fp_rect (start -5.4 1.8) (end -5 2.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 01b2c5a3-6011-4274-80ec-8984eac15b27))
(fp_rect (start 5.8 -2.6) (end 6.2 -2.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 01e30f77-5399-4045-add5-1687f463ebb7))
(fp_rect (start 4.6 5.8) (end 5 6.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 058b81d1-2511-4979-ac38-bcf730b88f5b))
(fp_rect (start 5 -1) (end 5.4 -0.6) (layer "F.SilkS") (width 0) (fill solid) (tstamp 0611adff-6e26-42cc-92dd-e8cdf810d5d0))
(fp_rect (start -5.8 -4.2) (end -5.4 -3.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 0640d715-8042-4e36-b2bf-7f86647057fe))
(fp_rect (start 4.6 -4.2) (end 5 -3.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 066531e1-4344-4d37-82b6-564183ebb3bb))
(fp_rect (start -4.2 -4.6) (end -3.8 -4.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 069a8d05-1339-4d55-a15e-e2533eaed5da))
(fp_rect (start 4.6 3.4) (end 5 3.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 06b2725e-d169-46ed-bf75-2c1702c46475))
(fp_rect (start -3.4 3.4) (end -3 3.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 06cc8c88-0c35-4848-8c09-6bd290bc4e2f))
(fp_rect (start -0.2 1.4) (end 0.2 1.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 06f5711d-705c-4d03-90d8-372c8e680289))
(fp_rect (start 5.4 -3) (end 5.8 -2.6) (layer "F.SilkS") (width 0) (fill solid) (tstamp 072325e5-6352-4b17-a587-34a82bd0412e))
(fp_rect (start 5.4 -4.2) (end 5.8 -3.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 0838aa30-eeae-492f-8198-c26fbe967ebe))
(fp_rect (start -6.2 6.2) (end -5.8 6.6) (layer "F.SilkS") (width 0) (fill solid) (tstamp 08a90f35-6088-4905-b870-689b6f086ee6))
(fp_rect (start 0.6 -5) (end 1 -4.6) (layer "F.SilkS") (width 0) (fill solid) (tstamp 0927cce7-21bc-4308-8f8c-201d63e5bbb8))
(fp_rect (start -6.6 0.2) (end -6.2 0.6) (layer "F.SilkS") (width 0) (fill solid) (tstamp 09400db6-a892-43d9-be80-98943f337c86))
(fp_rect (start -6.6 -4.2) (end -6.2 -3.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 096f0c76-b607-4fc4-9d18-665793803aef))
(fp_rect (start 3.8 6.2) (end 4.2 6.6) (layer "F.SilkS") (width 0) (fill solid) (tstamp 098e8c93-d87f-4754-8893-87582a822e4e))
(fp_rect (start -2.6 3.8) (end -2.2 4.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 09a99b1d-e5f1-4413-807a-9dd9aa9b1c46))
(fp_rect (start 6.2 -6.6) (end 6.6 -6.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 09bd5480-0f6b-4b45-b2e6-54d3ca55debc))
(fp_rect (start -1.8 -0.2) (end -1.4 0.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 09d55ca2-5242-4032-840a-f1be4f9d6c3e))
(fp_rect (start 5.4 3.4) (end 5.8 3.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 09e8c902-4e7e-4de6-b6a9-cd34206d6cfd))
(fp_rect (start -2.6 -5) (end -2.2 -4.6) (layer "F.SilkS") (width 0) (fill solid) (tstamp 09e9666b-34da-42a2-9356-cd86c0fad08a))
(fp_rect (start -0.6 -5) (end -0.2 -4.6) (layer "F.SilkS") (width 0) (fill solid) (tstamp 0a320520-2a91-4929-b02e-8a72dcd6e71d))
(fp_rect (start -2.6 -4.2) (end -2.2 -3.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 0ad75a3a-6dd8-472d-9861-c0f67a14395f))
(fp_rect (start -4.2 4.6) (end -3.8 5) (layer "F.SilkS") (width 0) (fill solid) (tstamp 0c5ba198-343c-4fe6-8ea7-e71aef2ad914))
(fp_rect (start 4.2 4.6) (end 4.6 5) (layer "F.SilkS") (width 0) (fill solid) (tstamp 0c73ea24-5815-4051-a716-00bef08005ed))
(fp_rect (start 6.2 5) (end 6.6 5.4) (layer "F.SilkS") (width 0) (fill solid) (tstamp 0d22bfc7-0889-4ea5-a0d5-bb124570337c))
(fp_rect (start 4.2 -3) (end 4.6 -2.6) (layer "F.SilkS") (width 0) (fill solid) (tstamp 0de73f01-b299-43fb-bcdf-0d7aca52e3f1))
(fp_rect (start 2.2 -6.6) (end 2.6 -6.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 0e186e55-0cc2-48eb-a845-c28bc454279c))
(fp_rect (start 3.8 -1.8) (end 4.2 -1.4) (layer "F.SilkS") (width 0) (fill solid) (tstamp 0e7afaeb-58b3-4bdd-8edb-1c754b96a649))
(fp_rect (start 2.6 -1.8) (end 3 -1.4) (layer "F.SilkS") (width 0) (fill solid) (tstamp 0e9101a9-0c2a-491b-8a9c-e7ccf937a89f))
(fp_rect (start 1 5.4) (end 1.4 5.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 0ea4b2c8-b33c-4370-b777-38d870433e38))
(fp_rect (start 1 -1) (end 1.4 -0.6) (layer "F.SilkS") (width 0) (fill solid) (tstamp 0f15a4d9-6917-4b69-bdf2-7452ad13eded))
(fp_rect (start 6.2 3.4) (end 6.6 3.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 0f388ab4-f840-4261-a965-99cb30c7f402))
(fp_rect (start -2.2 -4.6) (end -1.8 -4.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 0f64a7d7-08c4-44ea-9021-e4a443a9c78d))
(fp_rect (start -1.4 5.8) (end -1 6.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 107e4ecf-93fd-4c94-b600-74c3e0cf6c24))
(fp_rect (start 1 -5.4) (end 1.4 -5) (layer "F.SilkS") (width 0) (fill solid) (tstamp 11e02ef1-f6ee-4695-bea3-7c3bd3f30f23))
(fp_rect (start -5.4 1) (end -5 1.4) (layer "F.SilkS") (width 0) (fill solid) (tstamp 12888ca3-f799-43ed-aaf9-4426da9723d8))
(fp_rect (start -3.8 -0.2) (end -3.4 0.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 12b87007-502d-450f-80ab-8614603ba524))
(fp_rect (start -0.6 -3.4) (end -0.2 -3) (layer "F.SilkS") (width 0) (fill solid) (tstamp 12c6cf6c-5c43-4110-b2ba-8a3cfb2078d8))
(fp_rect (start 4.2 -6.6) (end 4.6 -6.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 13b484e3-635a-4a71-bca1-0a65c84197a2))
(fp_rect (start 4.2 5.4) (end 4.6 5.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 13de31fd-b119-488a-b6a8-a35fde15214b))
(fp_rect (start -5.8 -1.4) (end -5.4 -1) (layer "F.SilkS") (width 0) (fill solid) (tstamp 14561ab7-748d-4736-919f-7f424b293f84))
(fp_rect (start -4.2 0.6) (end -3.8 1) (layer "F.SilkS") (width 0) (fill solid) (tstamp 14b87a78-5691-4a7f-a2e2-f6eea79afcbe))
(fp_rect (start -0.2 -1.4) (end 0.2 -1) (layer "F.SilkS") (width 0) (fill solid) (tstamp 14e80e51-0e5f-400a-bae8-44971296f2c8))
(fp_rect (start 5 3) (end 5.4 3.4) (layer "F.SilkS") (width 0) (fill solid) (tstamp 15efc393-d412-47ce-9f07-f1784967eb90))
(fp_rect (start 2.6 -5.8) (end 3 -5.4) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1615c7c3-1794-46d8-b307-741b26ddcdb1))
(fp_rect (start 2.6 3.4) (end 3 3.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 16f163b0-a409-4e1d-842e-a189cafc189d))
(fp_rect (start -6.2 -6.6) (end -5.8 -6.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 17d5e101-dc96-48ac-bd6a-00a4f83ebf70))
(fp_rect (start -0.2 -6.6) (end 0.2 -6.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1962a49a-4bab-457c-ad41-a228e78bb52f))
(fp_rect (start -1.8 1.4) (end -1.4 1.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1973168b-928b-4891-ba1a-479a5035d42a))
(fp_rect (start -1 -5.4) (end -0.6 -5) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1988b72d-f2ec-4036-aba3-30b4c38d47e0))
(fp_rect (start -0.6 3) (end -0.2 3.4) (layer "F.SilkS") (width 0) (fill solid) (tstamp 199c794b-08ec-4bb3-9feb-7a18fea77cd5))
(fp_rect (start -1 -1.4) (end -0.6 -1) (layer "F.SilkS") (width 0) (fill solid) (tstamp 19ab79ed-cec7-4bc8-a6b9-eaf621ef5773))
(fp_rect (start -0.2 5.8) (end 0.2 6.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 19f827f6-9bec-4d46-8a72-b8153b664b95))
(fp_rect (start -1 -2.2) (end -0.6 -1.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1a163c6f-5a3c-4f09-8b65-f1f6d0be23ae))
(fp_rect (start 1.8 -1.8) (end 2.2 -1.4) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1aafc4f0-cb16-419b-9e14-6645b6b160c2))
(fp_rect (start -5.8 4.6) (end -5.4 5) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1ad38005-1fb6-40aa-bb7a-6440ac18fc9b))
(fp_rect (start 1.4 -2.2) (end 1.8 -1.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1ae43f65-c65a-4eaa-a88d-f93f5f81074e))
(fp_rect (start -5 5) (end -4.6 5.4) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1b0be9cd-8fe4-4c1f-8b08-63bf54d3299c))
(fp_rect (start -6.2 1.4) (end -5.8 1.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1b25bf4f-6f38-4f01-8c50-5881e5bb1bb1))
(fp_rect (start 4.6 -5.8) (end 5 -5.4) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1c1e240b-2f43-4058-b6b1-f62444f333b6))
(fp_rect (start 4.6 4.6) (end 5 5) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1c9b54dc-cd84-464c-b7f7-f7111a73f018))
(fp_rect (start 2.2 5) (end 2.6 5.4) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1cbcf0b0-0fb8-4c7e-9390-baa29aed8218))
(fp_rect (start 3 -5.8) (end 3.4 -5.4) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1e7820a6-7b18-40bc-a7c2-34d857dd5ac6))
(fp_rect (start -4.6 6.2) (end -4.2 6.6) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1ee8e9c3-bce6-4568-8362-c6acea3db8ef))
(fp_rect (start 0.6 1) (end 1 1.4) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1f5f47f3-1a56-43b1-b062-ef4c5193df8b))
(fp_rect (start -0.2 -2.2) (end 0.2 -1.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1f6b4aa6-f6a8-4740-8065-c29f74c0ca18))
(fp_rect (start -0.6 1.8) (end -0.2 2.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 1f6ed510-9b1b-4760-90a2-4eb618c62cff))
(fp_rect (start 5.4 0.6) (end 5.8 1) (layer "F.SilkS") (width 0) (fill solid) (tstamp 204c67c4-5969-4420-9441-0ac6955a98ce))
(fp_rect (start 1.4 0.6) (end 1.8 1) (layer "F.SilkS") (width 0) (fill solid) (tstamp 2077ca7f-04c6-4b7d-bee3-f1e6d5bb1120))
(fp_rect (start -1.8 -2.2) (end -1.4 -1.8) (layer "F.SilkS") (width 0) (fill solid) (tstamp 20c0e16d-f07a-4c1d-ac40-51232b12aeba))
(fp_rect (start -4.6 -3.4) (end -4.2 -3) (layer "F.SilkS") (width 0) (fill solid) (tstamp 2190a3ff-3548-45a6-a079-9db8cb811d85))
(fp_rect (start -3 -5.8) (end -2.6 -5.4) (layer "F.SilkS") (width 0) (fill solid) (tstamp 22bd6662-08dc-4a29-84fa-b4af072a6a5a))
(fp_rect (start 2.6 -0.2) (end 3 0.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 22bf3e0c-1351-4f73-b452-08072e785958))
(fp_rect (start -4.2 2.2) (end -3.8 2.6) (layer "F.SilkS") (width 0) (fill solid) (tstamp 23070448-2df2-45fd-bafe-89be6ea994b2))
(fp_rect (start -0.6 -1.4) (end -0.2 -1) (layer "F.SilkS") (width 0) (fill solid) (tstamp 23f65527-6e85-4940-8b1d-11e5413c48b0))
(fp_rect (start -1.4 -4.6) (end -1 -4.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 2427ce28-737b-4052-8257-4e2fc06b5dba))
(fp_rect (start 4.6 -6.6) (end 5 -6.2) (layer "F.SilkS") (width 0) (fill solid) (tstamp 2524ae0f-bfbd-4703-aa85-5308162f2d39))
(fp_rect (start -5.8 1.8) (end -5.4 2.2) (lay