Compare commits
108 Commits
master
...
usb-c_cabl
@ -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 |
||||
|
@ -1,9 +1,18 @@ |
||||
config: |
||||
output: coraleda |
||||
nodate: true |
||||
output: kicad |
||||
pattern: |
||||
densityLevel: 'N' |
||||
lineWidth: |
||||
silkscreen: 0.2 |
||||
polarityMark: none |
||||
preferManufacturer: false |
||||
smoothPadCorners: false |
||||
library: |
||||
- connector/usb-c_xkb_u262-24xn-4bv60 |
||||
- connector/battery_my-1220-03 |
||||
- resistor/r0603 |
||||
- diode/led0805 |
||||
- transistor/pmos_nxp_bss84 |
||||
- connector/usb-c_xkb_u262-24xn-4bv64 |
||||
- diode/led0603 |
||||
|
@ -0,0 +1,23 @@ |
||||
v3 |
||||
-- |
||||
|
||||
- replace 0805 LEDs with 0603 (makes it more compact) |
||||
- shield LED only on if shell is interconnected AND grounded (was OR before) |
||||
|
||||
v2 |
||||
-- |
||||
|
||||
- schematic and board layout redrawn in KiCAD |
||||
- slightly change front text to be more symmetrical |
||||
- change USB-C connector to improve manufacturing yield |
||||
|
||||
v1 |
||||
-- |
||||
|
||||
- reroute SBU test to only use one LED |
||||
- make LED colors symmetric |
||||
|
||||
v0 |
||||
-- |
||||
|
||||
initial design, based on a protoboard prototype. |
@ -0,0 +1,91 @@ |
||||
this will describe how to generate the output files form the sources. |
||||
|
||||
requirements |
||||
============ |
||||
|
||||
to be able to generate the outputs, you need following software: |
||||
|
||||
- [QEDA](http://qeda.org/): to generate footprints for the parts |
||||
- [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 |
||||
------- |
||||
|
||||
almost all of the symbols and footprints used in the schematic and board layout are defined in the [QEDA](http://qeda.org/) format and generated for the CAD software. |
||||
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 |
||||
npm install |
||||
sudo npm install --global |
||||
~~~ |
||||
|
||||
to generate the parts: |
||||
~~~ |
||||
make library |
||||
~~~ |
||||
|
||||
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 `.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 `kicad/` folder. |
||||
most symbols are generated by QEDA as described above. |
||||
|
||||
to export as pdf: |
||||
~~~ |
||||
make print |
||||
~~~ |
||||
|
||||
BOM |
||||
--- |
||||
|
||||
to export the bill of material (as CSV): |
||||
~~~ |
||||
make bom |
||||
~~~ |
||||
|
||||
board |
||||
----- |
||||
|
||||
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 footprints from the `kicad/` folder. |
||||
most symbols are generated by QEDA as described above. |
||||
|
||||
to export gerber files for PCB manufacturer (and photo preview + overview document): |
||||
~~~ |
||||
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 |
|
@ -0,0 +1,71 @@ |
||||
# project file name (use for schematic and board layout)
|
||||
NAME ?= usb-c_cable_tester
|
||||
# path to qeda
|
||||
QEDA := qeda
|
||||
|
||||
# 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 and current git commit
|
||||
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)))) |
||||
|
||||
all: print fabrication |
||||
|
||||
print: ${NAME}.sch.pdf ${NAME}.brd-top.png ${NAME}.brd-bot.png ${NAME}.bom.csv |
||||
|
||||
# generate fabrication files (gerbers/drill/BoM/PnP)
|
||||
FABRICATION_DIR := fabrication
|
||||
fabrication: ${NAME}.versioned.kicad_sch ${NAME}.versioned.kicad_pcb |
||||
kikit fab jlcpcb --drc --assembly --schematic $^ ${FABRICATION_DIR}
|
||||
|
||||
# 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 -rf ${FABRICATION_DIR}
|
||||
rm -f panel.kicad_pcb panel.kicad_pro
|
||||
rm -rf ${PANEL_DIR}
|
@ -1,88 +1,99 @@ |
||||
these are the hardware design files for **insert project name here**. |
||||
The USB-C cable tester shows which features a USB-C to USB-C cable supports. |
||||
|
||||
<img src="picture/v3_front.webp" title="front" height="250"/> |
||||
<img src="picture/v3_back.webp" title="back" height="250"/> |
||||
|
||||
purpose |
||||
======= |
||||
|
||||
usage |
||||
===== |
||||
|
||||
requirements |
||||
============ |
||||
|
||||
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. |
||||
|
||||
compiling |
||||
========= |
||||
|
||||
library |
||||
------- |
||||
|
||||
almost all of the symbols and footprints used in the schematic and board layout are defined in the [QEDA](http://qeda.org/) format and generated for the CAD software. |
||||
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 |
||||
npm install |
||||
sudo npm install --global |
||||
~~~ |
||||
USB-C to USB-C cables come in a several flavours. |
||||
The [USB Type-C Cable and Connector Specification](https://www.usb.org/document-library/usb-type-cr-cable-and-connector-specification-revision-21) lists two types of cables: |
||||
|
||||
to generate the parts: |
||||
~~~ |
||||
rake library |
||||
~~~ |
||||
- Standard: this supports USB 2.0 data transfer, as well as Power Delivery (PD) |
||||
- Full-Featured: this adds differential pairs used for SuperSpeed (SS) data transfer (for USB3, USB4, ...), and sideband use (SBU) for alternate modes or USB4 data transfer |
||||
|
||||
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. |
||||
On top of that, cables can be electronically marked (eMarked). |
||||
Full-Featured cables should be electronically marked, while this is optional for standard cables. |
||||
eMarked cables include chips that communicate on the CC wire using the PD protocol. |
||||
They provide information about the cable, and are mandatory (but not sufficient) for 5A current transfer (e.g. for 100W charging) instead of the standard 3A (e.g. 60W). |
||||
Then there are not specification compliant cables, that only support charging, or no PD communication. |
||||
I suspect some full-featured cables are not electronically marked, and most magnetic cables are not shielded, at least not from plug to plug. |
||||
|
||||
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. |
||||
Because what is inside of the cable is not indicated on the outside, the cable tester checks for the individual capabilities. |
||||
|
||||
schematic |
||||
--------- |
||||
|
||||
the `.sch` file is the schematic source file. |
||||
it has been drawn using [Lepton EDA](https://github.com/lepton-eda/lepton-eda). |
||||
|
||||
it uses standard symbols, and the ones in the `geda/symbols/` folder. |
||||
most symbols are generated by QEDA as described above. |
||||
|
||||
to export as pdf: |
||||
~~~ |
||||
rake print |
||||
~~~ |
||||
|
||||
BOM |
||||
--- |
||||
|
||||
to export the bill of material (as CSV): |
||||
~~~ |
||||
rake 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/). |
||||
|
||||
it uses the symbols from the `coraleda/subc/` 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/. |
||||
usage |
||||
===== |
||||
|
||||
to export gerber files for PCB manufacturer (and photo preview + overview document): |
||||
~~~ |
||||
rake fabrication |
||||
~~~ |
||||
Ensure a non-empty CR1220 battery is in the tester. |
||||
Plug both ends of the USB-C cable in the tester and read the lights: |
||||
|
||||
<img src="picture/v3_ff.webp" title="Full-Featured cable" height="250"/> |
||||
|
||||
- SHIELD: ensures the cable is shielded, important for super speed data transfer. |
||||
- POWER: ensures the VBUS and GND wires are present, required to power a device. |
||||
- USB2: ensures the D+ and D- wires are present, required for USB data transfer (up to at least 2.0). |
||||
- CC/PD: ensures the Configuration Channel (CC) wire is present, required to determine the plug orientation and for Power Delivery (PD) communication (used for fast charging) |
||||
- SS: ensure the 4 differential pairs are present, required for Super Speed (SS) data transfer (USB3, USB4, ...) |
||||
- SBU: ensures the Side Band Use (SBU) wires are present, used for alternate modes. |
||||
- eMarker: indicates if the cable is electronically marked, required to support 5A/100W power transfer. |
||||
|
||||
Note: the eMarker indication does not mean the cable does support 5A/100W power transfer. |
||||
Most of the time, an electronically marked cable does support 5A, since the chip costs more than the wire. |
||||
But to confirm it, this information needs to be read out from the chip inside the cable using the PD protocol. |
||||
The cable tester does not support this functionality. |
||||
Some USB Power Monitor (UPM) provide this functionality. |
||||
|
||||
mode of operation |
||||
================= |
||||
|
||||
Here the methods used to test the different capabilities of the cable: |
||||
|
||||
- POWER: ensures the VBUS and GND wires are present in the cable, required to power a device. |
||||
Although there 4 ground and 4 power pins, there are only 1 ground and 1 power wires. |
||||
The pins are inter-connected in the plugs on each side of the cable. |
||||
|
||||
- SHIELD: ensures the shell of the plugs are connected on both sides of the cable. |
||||
It also ensures the shield is grounded, as required by the specification. |
||||
This does not verify if the cable has proper shield foil and braid though, or it's just a wire (I haven't seen a cable cheating this way yet). |
||||
Also, if the cable has a shield, but only connected on one plug or it is not connected to ground, this will not be detected. |
||||
|
||||
- USB2: ensures the UTP wire are present, used for USB 2.0 data transfer. |
||||
There is only one pair of UTP wire for the Dp and Dn signals using for USB 2.0 communication, connected to A6 and A7 on both sides. |
||||
Since the plug is reversible on both sides, we short the pins to be sure we can test the cable. |
||||
|
||||
- SS: ensures the SuperSpeed (SS) wires are present, for USB3 (and USB4) data transfer. |
||||
There are 4 pairs of wires (SDPxx) used for differentials signals. |
||||
The tester checks if all are present. |
||||
|
||||
- SBU: ensures the sideband use (SBU) are present, used for Alternate Modes. |
||||
There are 2 single SBU wires. |
||||
The tester checks if all are present. |
||||
|
||||
- CC: ensures the Configuration Channel is present, used for Power Delivery (PD) communication. |
||||
There is one wire going from CC1 on one side of the connector, to CC1 on the other side of the connector. |
||||
Since the plug on both sides is reversible, there are 4 possible permutations. |
||||
This pin is actually used to determine the orientation of the plug, and do the date signal switching on the right pins. |
||||
Which of both LEDs is on also depends on the plug orientation. |
||||
|
||||
- eMarker: indicates if the cable is electronically marked. |
||||
The detection is the complicated part of this design. |
||||
A5 on both sides are interconnected through the CC wire. |
||||
B5 on both sides are connected to Vconn. |
||||
Vconn only allows to power the embedded chip, but does not provide B5 interconnection. |
||||
The connected device can detect the presence of the chip, by checking if B5 (on each side) is pulled down using Ra (~ 1kOhm). |
||||
It can then provide power on Vconn. |
||||
The cable tester detects electronically marked cables the following way. |
||||
If Ra is present, the gate voltage of a p-channel MOSFET on the tester is pulled low, powering the corresponding LED. |
||||
By default the gate is pulled up by the resistor used for the CC LED. |
||||
When Ra is present, it is on both plugs of the cable. |
||||
Thus it is enough to detect is on one plug. |
||||
Because it can be on A5 or B5 pins, the detection circuit needs to be on both pins. |
||||
On the other plug, the CC pins can't be interconnected, else the voltages is pulled to low for the CC LED to work. |
||||
Thus, two separate LEDs are used to detect CC. |
||||
The pull-up resistor needs to be as high as possible to, for the Ra pull-down resistor (800-1200 Ohm) to work properly, activating the gate. |
||||
The BSS84 pMOS has a Vgs of ~1.7V. |
||||
A pull-up resistor of 2.2 kOhm is sufficient (with a 3V battery). |
||||
Green LEDs are used for CC. |
||||
Although they have a higher voltage drop, they seems to be more efficient. |
||||
With a 2.2 kOhm, it produces a bright enough light. |
||||
Warning: because green LED has a forward voltage drop of ~2V to ground, the battery voltage can't be higher than 3.3V, else the gate voltage will exceed the threshold and the eMarker LED will be on, which is a false positive. |
||||
|
@ -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 |
@ -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 |
@ -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 |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -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" |
||||
|
@ -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) |
||||
} |
||||
|
||||