Compare commits

..

112 Commits

Author SHA1 Message Date
King Kévin 4eb4a1993d add physical case for USB hub 2022-12-21 02:15:07 +01:00
King Kévin 13c5469ba2 lib: update repo 2022-12-21 02:14:07 +01:00
King Kévin 2b563d3e59 doc: add serial info 2022-12-21 02:13:51 +01:00
King Kévin c91917f370 doc: add EEPROM programming 2022-12-21 02:13:07 +01:00
King Kévin 7f3c5024ad doc: minor, fix README 2022-12-21 02:12:57 +01:00
King Kévin c5b8e17fe7 doc: add v2 changelog 2022-12-21 02:12:24 +01:00
King Kévin 49b61c90fd doc: fix typo and improve over-current details 2022-10-15 16:03:32 +02:00
King Kévin 1e3a18c7b2 sch/brd: fix 6-40V feedback 2022-10-15 15:37:47 +02:00
King Kévin 08382b5221 rake: fix pdfcat 2022-09-12 14:00:11 +02:00
King Kévin bfec7d2523 brd: minor, remove stub 2022-09-12 13:49:36 +02:00
King Kévin b12dc32618 brd: minor, add missing DFP silk screen 2022-09-12 13:39:12 +02:00
King Kévin b7281faf20 doc: listed tested current limiters 2022-09-12 12:13:23 +02:00
King Kévin f45d075096 brd: update current limit netname 2022-09-12 12:03:43 +02:00
King Kévin 23dd01b03b sch: replace TJ2242 current limit with DIO7553 2022-09-12 12:03:19 +02:00
King Kévin a9610657e4 lib: add DIO7553 current limit 2022-09-12 12:01:53 +02:00
King Kévin c241c9cfb4 brd: route TJ2242 for other DFP 2022-07-24 19:04:03 +02:00
King Kévin 61112471f2 sch: set TJ2242 BoM 2022-07-24 18:19:19 +02:00
King Kévin dc836b816f sch: propagate TJ2242 change to DFP 2022-07-24 18:17:11 +02:00
King Kévin b3956df5d2 brd: route TJ2242 2022-07-24 18:15:24 +02:00
King Kévin 6861b06fe4 sch: replace current limit with TJ2242 2022-07-24 17:32:30 +02:00
King Kévin 55c48fbaf9 lib: add TJ2242 current limit 2022-07-24 17:31:49 +02:00
King Kévin 7cd047cf24 doc: document OCS timing 2022-07-24 16:50:40 +02:00
King Kévin f41d5e6557 sch: reduce green LED brightness 2022-06-18 10:05:40 +02:00
King Kévin 0f2fca2479 sch: minor, add OCS info 2022-06-17 17:33:50 +02:00
King Kévin 6731d4e397 brd: route DFP VBUS for TVS 2022-06-17 17:08:36 +02:00
King Kévin efa7388363 sch: use DFP VBUS for TVS 2022-06-17 17:08:21 +02:00
King Kévin a822a1ae14 brd: implement sch changes (crystal, 6-40V output, current limit) 2022-06-17 16:37:56 +02:00
King Kévin 2b838e7a54 sch: minor, fix connection 2022-06-17 16:36:30 +02:00
King Kévin 6e35891b90 sch: minor, fix footprint 2022-06-17 16:35:46 +02:00
King Kévin 5755d3a790 sch: replicate changes to other DFP 2022-06-16 19:22:42 +02:00
King Kévin 0355594851 sch: use current limit with error flag 2022-06-16 19:21:23 +02:00
King Kévin f9abdbdb4d sch: prevent 6-40V feedback 2022-06-16 19:16:21 +02:00
King Kévin b165245ded sch: only allow 6-40V output when present 2022-06-16 19:06:13 +02:00
King Kévin 338657f927 lib: add SY6288 current limit 2022-06-16 19:00:49 +02:00
King Kévin 64cb5285b1 lib: minor description improvement 2022-06-16 19:00:19 +02:00
King Kévin beb1722f2f sch: fix 3.3V dip and hub reset 2022-06-16 18:50:52 +02:00
King Kévin 48cad88a56 sch: fix crystal 2022-06-16 18:38:12 +02:00
King Kévin 4f25a52ca6 brd: add port text information 2022-06-16 18:32:43 +02:00
King Kévin 23c5dc43a1 doc: add flashing instructions 2022-06-16 18:14:01 +02:00
King Kévin 9f8f01dd5d switch to version 2 to add fixes 2022-06-16 18:04:17 +02:00
King Kévin 23b70f5697 doc: improve doc, fix current limit 2022-06-16 18:03:29 +02:00
King Kévin 37636fa6cd doc: document usage 2022-06-16 17:51:05 +02:00
King Kévin d81381e0c0 doc: move developmnet information in separate file 2022-06-16 17:24:52 +02:00
King Kévin c5e6291beb doc: list v1 changes 2022-06-16 17:01:00 +02:00
King Kévin 51c6af4add rake: all multi-sheet export 2022-06-16 16:44:14 +02:00
King Kévin bde94d7b85 lib: update repo 2022-05-28 12:36:25 +02:00
King Kévin 2988c900c8 brd: minor cleanup 2022-05-21 13:39:24 +02:00
King Kévin 94d78ddd39 brd: improve silk 2022-05-21 11:40:00 +02:00
King Kévin 2223168ef2 brd: improve text 2022-05-20 19:59:00 +02:00
King Kévin 2b26e45092 brd: finish routing 2022-05-20 18:53:10 +02:00
King Kévin 11d7172ab9 sch: connect more shield of USB-A 2022-05-20 18:52:50 +02:00
King Kévin a668a7953b sch: fix hub part 2022-05-20 14:05:13 +02:00
King Kévin 9dc2d6bbe9 fix dfp generation 2022-05-20 14:04:33 +02:00
King Kévin d67ac812a0 brd: restart 1-sided layout 2022-05-20 13:34:29 +02:00
King Kévin 223f4ffdf8 sch: fix netname, improve routing 2022-05-20 13:33:37 +02:00
King Kévin 1a37524a59 sch: minor, fix downstream ports 2022-05-20 13:32:50 +02:00
King Kévin a8b1bac321 lib: add 1x6 header 2022-05-20 13:31:58 +02:00
King Kévin 5080e79de8 lib: make inductor footprint smaller 2022-05-20 13:31:28 +02:00
King Kévin 891291cc64 changelog: document v0 errors 2022-05-20 13:29:28 +02:00
King Kévin e01867bf73 add empty changelog 2022-05-20 10:26:36 +02:00
King Kévin f3cc67efa1 lib: fix USB-A connector 2022-05-16 16:03:43 +02:00
King Kévin 7a951854e2 brd: use all schematic sheets 2022-05-16 16:02:56 +02:00
King Kévin e5c06db27a sch: make schematic flat instead of hierarchical 2022-05-16 16:02:17 +02:00
King Kévin 9adee74626 sch: fix capacitor refdes collision 2022-05-16 16:01:43 +02:00
King Kévin 97f117f52a add script to clone dfp schematic 2022-05-12 18:35:21 +02:00
King Kévin 578567b95d sch: add all DFP 2022-05-12 18:34:45 +02:00
King Kévin 7b095612d8 lib: fix USB-A pinout 2022-05-11 19:34:01 +02:00
King Kévin 89bf8ee2da sch: use current limit and fix OCS 2022-05-11 19:33:05 +02:00
King Kévin 34454bc0ad lib: add MT9700 current-limit 2022-05-11 19:32:18 +02:00
King Kévin f7c22b3bac sch: use subsheet for DFP 2022-05-11 12:40:49 +02:00
King Kévin 4428bf9740 lib: minor, update library 2022-05-11 12:40:15 +02:00
King Kévin a4b46c4b3b update submodule source 2022-05-11 12:13:02 +02:00
King Kévin 71377ef17d sch: use multi-part USB symbol 2022-05-11 12:12:40 +02:00
King Kévin 6b8b118f57 lib: make USB symbol multipart 2022-05-11 12:11:33 +02:00
King Kévin 748d9caa8a sch: document nMOS on power output 2022-05-10 18:53:37 +02:00
King Kévin f90cc17564 sch: unswap DFP data lines 2022-05-10 18:44:43 +02:00
King Kévin 38c017df0e sch: fix 6-40V buck enable 2022-05-10 18:40:20 +02:00
King Kévin 6ca314ab20 switch to next version 2022-05-10 16:21:50 +02:00
King Kévin 43b39e512e brd: change some thermals 2022-04-18 14:33:32 +02:00
King Kévin d1c82f8293 sch: minor, re-arrange 2022-04-14 15:36:21 +02:00
King Kévin 51960b929f brd: add project name as silk screen 2022-04-05 18:47:25 +02:00
King Kévin f7c3d5492d brd: place refdes 2022-04-05 18:15:03 +02:00
King Kévin 27d79fde82 brd: first routing completed 2022-04-05 15:23:52 +02:00
King Kévin a793fce99f sch: simplify protection 2022-04-05 15:22:57 +02:00
King Kévin 1fa95afea2 sch: arrange ports 2022-04-03 18:37:20 +02:00
King Kévin 166e92724d sch: copy 6 downstream ports 2022-04-03 18:34:25 +02:00
King Kévin 8bc6a95643 sch: swap DM/DP 2022-04-03 18:27:00 +02:00
King Kévin bc0fad1f42 brd: fix overlapping components 2022-04-03 18:20:58 +02:00
King Kévin 4557640f5f brd: copy 6 downstream ports 2022-04-03 18:14:44 +02:00
King Kévin 0d7b6b19ba sch: use VBUS for input-TVS 2022-04-03 12:24:45 +02:00
King Kévin 6581d18e41 sch: make routing easier for header 2022-04-02 18:31:51 +02:00
King Kévin 8783935df5 sch: minor, comment 1V8 rail 2022-04-02 18:20:01 +02:00
King Kévin 5966ed10d8 sch: connect tab of XL2596S 2022-04-02 18:17:35 +02:00
King Kévin f026117a8b lib: add tab pin to XL2596S 2022-04-02 18:17:14 +02:00
King Kévin 26f31a612c sch: add Vgs protection resistor 2022-04-02 13:54:36 +02:00
King Kévin db951d8493 sch: add net names 2022-04-02 13:52:53 +02:00
King Kévin e3ebf72bcb Makefile: fix lepton CLI call 2022-02-02 15:38:51 +01:00
King Kévin 62f35353d4 lib: footprint don't have polarity dot anymore 2022-02-02 15:37:06 +01:00
King Kévin 09b899a9a6 qeda: remove polarity dot 2022-02-02 15:36:01 +01:00
King Kévin abee832aa0 lib: add description to symbol 2022-01-30 16:20:24 +01:00
King Kévin a0ba6ce381 lib: fix USB-B footprint 2022-01-30 16:19:26 +01:00
King Kévin b776544878 pcb: add project enclosure 2022-01-28 18:47:58 +01:00
King Kévin 5ee619c0b5 README: add project description 2022-01-28 18:46:39 +01:00
King Kévin 6c51f29372 Rakefile: minor, show error on empty BOM 2022-01-28 18:45:05 +01:00
King Kévin d21265f083 Rakefile: minor, improve readability 2022-01-28 18:44:48 +01:00
King Kévin 786947f2fb lib: add better crystal symbol, with 4 pins 2022-01-28 18:40:13 +01:00
King Kévin 327b1ca07e lib: add better power jack symbol 2022-01-28 18:19:44 +01:00
King Kévin a976e4fde0 lib: add custom chassi ssymbol with net name 2022-01-28 18:15:15 +01:00
King Kévin 60ce73cdf9 lib: add generated parts 2022-01-28 18:09:58 +01:00
King Kévin 5fcf15b9c6 lib: define project parts 2022-01-28 17:57:55 +01:00
King Kévin f2304bbd82 sch: first draft, with one port 2022-01-28 17:56:22 +01:00
King Kévin adc85e6281 set project name 2022-01-04 14:31:54 +01:00
134 changed files with 110845 additions and 8360 deletions

35
.gitignore vendored
View File

@ -1,37 +1,18 @@
# schematic lepton-EDA
*.sch
# board layout pcb-rnd
*.lht
*.lht.*
# KiCAD
*.kicad_prl
*.kicad_pro-bak
*.xml
fp-info-cache
# temporary files
*.versioned.lht
*~
\#*\#
~*.lck
# outputs
*.versioned.sch
*.svg
*.png
*.pdf
*.ps
*.zip
*.brd.*
*.tdx
\#*\#
*.notes.txt
*.bom.csv
*.cost.csv
*.cpl.csv
*.3d.step
*.versioned.*
fabrication
# scripts and utilities
*.json
*.rb
# panel files
panel.*
panel
geda/footprints/

View File

@ -1,8 +1,5 @@
config:
nodate: true
output: kicad7
symbol:
pinIcon: false
output: coraleda
pattern:
densityLevel: 'N'
lineWidth:
@ -11,6 +8,31 @@ config:
preferManufacturer: false
smoothPadCorners: false
library:
- connector/barrel_dc-005-2.0
- ic/eeprom_ft24c16a-e@p
- mechanical/switch_hroppart_ss12f44g5
- vreg/buck_xl2596@to263-5l
- connector/usb-a-2.0-receptacle_c42678
- connector/usb-b-2.0-receptacle_c46392
- vreg/fuse_1206sfh
- resistor/r0603
- capacitor/c0603
- transistor/pmos_40p05
- transistor/nmos_bss138
- diode/schottky_rb521s
- diode/schottky_ss34
- inductor/slh@1207
- vreg/ldo_torex_xc6206@mr
- ic/usbhub_microchip_usb2517
- diode/tvs_st_usblc6-2@sc6
- diode/led0805
- capacitor/cap_radial_10mm
- capacitor/cap_radial_6.3mm
- capacitor/cap_radial_5mm
- connector/header-2.54@2x3
- oscillator/x3225
- vreg/current-limit_mt9700
- connector/header-2.54@1x6
- vreg/current-limit_sy6288
- vreg/current-limit_tj2242
- vreg/current-limit_dio755x

View File

@ -0,0 +1,45 @@
v2
==
this has major fixes for version 1:
- missing crystal resistor
- 3.3V dip using larger capacitor
- 6-40V feedback
- DFP over-current
v1
==
this is a complete re- board layout.
it does not fit an off-the selves enclosure anymore.
all SMD parts are on one side to allow easier SMT assembly.
fixes:
- 6-40V power input activated when UFP is connected
- use current limit on DFP (prevents USB to reset when DFP is shorted)
- 6-40V power input capacitor now lays down
- remove copper plane under crystal to prevent impedance error
errors:
- crystal still does not start
- none of the two possible OCS inputs (Dx04 XOR Dx05) work
- power dip causes reset when enabling all 7 DFP power outputs at once
v0
==
this version has been designed to fit in a 100x60x25mm enclosure.
this makes it very compact, and not all surface mount parts fit on one side.
this is not too much of an issue since it's a hand soldered prototype.
the prototype mostly works, with a couple of small errors:
- 6-40V power input is not activated unless the hub is already powered (through USB or 5V input)
- crystal oscillator doesn't always start. I think the underlying copper plane skewed the impedance/capacitance too much
- USB-A footprint has inverted pinout: just solder it on the other side and don't swap the data pins in the EEPROM configuration
- fuse on downstream port is not fast enough to prevent shorts and causes the hub to reset
- 6-40V power input capacitor is too tall and does not fit in the case
- one of the LEDS on port 3 is misplaced

View File

@ -3,31 +3,17 @@ 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
- [KiCad v8](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)
- [KiBoM](https://github.com/SchrodingersGat/KiBoM): to generate Bill of Material (CSV)
- [Interactive HTML BOM](https://github.com/openscopeproject/InteractiveHtmlBom): to generate placement guide
install Interactive HTML BOM using KiCad's Plugin and Content Manager.
for the others:
~~~
npm install qeda
pip install pcbdraw kibom kikit
~~~
you can additionally install KiKit using KiCad's Plugin and Content Manager for an integrated GUI.
- [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
=========
to generate schematic, BoM, board render, and fabrication output, run `make`.
library
-------
@ -35,13 +21,11 @@ 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
@ -50,59 +34,63 @@ sudo npm install --global
~~~
to generate the parts:
~~~
make lib
rake 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.
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.
schematic
---------
the `.kicad_sch` file is the schematic source file.
it has been drawn using the [KiCAD eeschema](https://www.kicad.org/) schematic editor.
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 `kicad/` folder.
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:
~~~
make print
rake print
~~~
BOM
---
to export the bill of material (as CSV):
~~~
make bom
rake 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.
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 footprints from the `kicad/` folder.
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/.
to export gerber files for PCB manufacturer (and photo preview + overview document):
~~~
make fabrication
rake fabrication
~~~
versioning
----------
flashing
========
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`:
the USB hub gets its configuration from an external EEPROM.
running `eeprom.rb` will generate the EEPROM configuration in `eeprom.bin`.
this must then be flashed on the board EEPROM.
it is possible to flash it in circuit using the corresponding header, and by holding the RST signal low to prevent the USB hub from interfering with the communication.
- `v` corresponds to the major version information defined in `version`
- `r` corresponds to the total number of changes done to the source files
to flash it using [minipro](https://gitlab.com/DavidGriffith/minipro/):
~~~
minipro --device "AT24C16@SOIC8" --write eeprom.bin -s
~~~

View File

@ -1,28 +0,0 @@
#!/usr/bin/env python3
"""
@package
KiBOM - Bill of Materials generation for KiCad
Generate BOM in xml, csv, txt, tsv, html or xlsx formats.
- Components are automatically grouped into BoM rows (grouping is configurable)
- Component groups count number of components and list component designators
- Rows are automatically sorted by component reference(s)
- Supports board variants
Extended options are available in the "bom.ini" config file in the PCB directory
(this file is auto-generated with default options the first time the script is executed).
For usage help:
python KiBOM_CLI.py -h
"""
import sys
import os
here = os.path.abspath(os.path.dirname(__file__))
sys.path.insert(0, here)
from kibom.__main__ import main # noqa: E402
main()

112
Makefile
View File

@ -1,112 +0,0 @@
# project file name (use for schematic and board layout)
NAME ?= template
SUBSHEET ?=
# path to KiCad CLI
KICAD = kicad-cli
# path to qeda
QEDA := qeda
# path to KiBOM
KIBOM := kibom
# path to InteractiveHtmlBom
IBOMGEN := ~/.local/share/kicad/8.0/3rdparty/plugins/org_openscopeproject_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' $$@
sed --in-place 's/\.kicad_sch/.versioned.kicad_sch/g' $$@
endef
$(foreach EXT,$(VERSIONED_EXT),$(eval $(call version_rule,$(EXT))))
VERSIONED_SHEET = $(foreach SHEET,$(NAME) $(SUBSHEET),$(SHEET).versioned.kicad_sch)
FABRICATION_DIR := fabrication
IBOM := ${FABRICATION_DIR}/ibom.html
all: $(VERSIONED_SHEET) ${NAME}.sch.pdf ${NAME}.bom.csv render fab
fab: ${FABRICATION_DIR} ${IBOM}
render: ${NAME}.brd-top.png ${NAME}.brd-bot.png ${NAME}.brd-top.svg ${NAME}.brd-bot.svg ${NAME}.3d.step
# generate fabrication files (gerbers/drill/BoM/PnP)
${FABRICATION_DIR}: ${NAME}.versioned.kicad_sch ${NAME}.versioned.kicad_pcb
kikit fab jlcpcb --no-drc --assembly --field JLCPCB,LCSC --schematic $^ $@
# generate fabrication files (gerbers/drill/uncorrected PnP)
#${FABRICATION_DIR}: ${NAME}.versioned.kicad_pcb
# mkdir -p ${FABRICATION_DIR}
# $(KICAD) pcb export gerbers --output ${FABRICATION_DIR} $<
# $(KICAD) pcb export drill --output ${FABRICATION_DIR}/ $<
# $(KICAD) pcb export pos --output ${FABRICATION_DIR}/${NAME}.versioned.pos $<
# generate interactive BoM
${IBOM}: ${NAME}.versioned.kicad_pcb
python $(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
$(KICAD) sch export pdf --output $@ $<
# generate render from layout (top side)
%.brd-top.png: %.versioned.kicad_pcb
pcbdraw plot --silent --no-components --dpi 600 --side front $< $@
# generate render from layout (bottom side)
%.brd-bot.png: %.versioned.kicad_pcb
pcbdraw plot --silent --no-components --dpi 600 --side back $< $@
# generate render from layout (top side)
%.brd-top.svg: %.versioned.kicad_pcb
$(KICAD) pcb export svg --layers F.Cu,F.Paste,F.Silkscreen,Edge.Cuts --page-size-mode 2 --exclude-drawing-sheet --output $@ $<
# generate render from layout (bottom side)
%.brd-bot.svg: %.versioned.kicad_pcb
$(KICAD) pcb export svg --layers B.Cu,B.Paste,B.Silkscreen,Edge.Cuts --mirror --page-size-mode 2 --exclude-drawing-sheet --output $@ $<
# export Bill of Material (as CSV)
%.bom.xml: %.versioned.kicad_sch %.versioned.kicad_pro
$(KICAD) sch export python-bom --output $@ $<
# export 3D model
%.3d.step: %.versioned.kicad_pcb
$(KICAD) pcb export step --output $@ $<
# export Bill of Material (as CSV)
%.bom.csv: %.bom.xml
$(KIBOM) $< $@
# generate panel
PANEL_DIR := panel_fab
panel: panel.kicad_pcb panel.brd-top.svg panel.brd-bot.svg panel.brd-top.png panel.brd-bot.png ${PANEL_DIR}
panel.kicad_pcb: ${NAME}.versioned.kicad_pcb ${NAME}.versioned.kicad_pro ${NAME}.versioned.kicad_sch panel.versioned.json
kikit panelize -p panel.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
${PANEL_DIR}: ${NAME}.versioned.kicad_sch panel.kicad_pcb
kikit fab jlcpcb --assembly --missingError --field JLCPCB,LCSC --schematic $^ $@
clean:
rm -f $(foreach EXT,$(VERSIONED_EXT),${NAME}.versioned.$(EXT))
rm -f ${NAME}.sch.pdf ${NAME}.brd-top.png ${NAME}.brd-bot.png ${NAME}.brd-top.svg ${NAME}.brd-bot.svg ${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.versioned.json panel.kicad_pcb panel.kicad_pro panel.brd-top.svg panel.brd-bot.svg panel.brd-top.png panel.brd-bot.png
rm -rf ${PANEL_DIR}

164
README.md
View File

@ -1,7 +1,169 @@
these are the hardware design files for **insert project name here**.
the CuVoodoo USB hub is a 7-port USB 2.0 hub meant for device testing.
purpose
=======
most USB hubs are super cheap and crappy, leading to poor connection and data transfer.
there are industrial USB hubs, but they are bulky and very expensive.
to solve this issue I decided to design my own USB hub, tailored to my needs.
when developing and testing hardware, you often end with a lot of USB devices connected (serial debugger, programmer, logic analyzer, ...).
USB allows to have up to 128 devices, but only with a maximum depth of 7.
thus you are only allowed to have a maximum of 5 USB hubs between computer and devices, and I often have to plan my setup to not reach this limit.
most 7-port USB hubs use two 4-port USB hub, the seconds being connected to the first.
there are some exceptions to that, but they are rare, old, and often not advertised as such.
this heavily limits the actual number of end devices.
the CuVoodoo USB hub is a 7-port flat USB hub, preventing reaching this limit too fast.
the upstream and downstream USB ports are individually ESD protected.
this safety becomes important when developing, testing, and handling bare electronic devices.
this also comes in handy when connecting circuit with different ground potentials.
ESD protections already saved my day twice this way.
the issue is that they can blow without you noticing, but at least they protected the device once.
each output port is current limited to 500 mA.
no USB 2.0 device should draw more that this specified limit.
it if does, there is very probably an issue with the device.
this protection allows to isolate the faulty device and not have it affect all other connected devices, or the hub itself.
see `current limitation` below for more details.
each downstream port is power controlled.
this allows to remotely switch on and off individual devices.
this is an important requirement when developing and testing devices, which require a power cycle.
additionally, a switch next to the USB port can force the power off state.
the USB hub can be self-powered (through the USB input port), externally powered by 5V, or externally powered by anything between 6 and 40V.
this allows to use higher voltage power supplies to provide enough current to all ports.
the 5V are not feed back to the host.
each USB port comes with a high voltage output power port, connected to the high voltage input port.
this allows to power devices which require more than 5V, with a maximum or 5A, such as 12V externally powered devices.
these power outputs are controllable along the USB port.
as with the 5V USB power output, this allows to remotely switch on an off individual devices.
each port has status LEDs, indicating the speed and power status of the connected device.
the board uses proper impedance and differential signal routing to provide clean USB signals.
design choice
=============
USB 2.0
-------
this hub is only for USB 2.0 devices.
these are by far most of the devices I develop.
it makes it simpler and keeps the cost reasonable.
I often even disable USB 3.0 because of the 13-device limitation of the Intel xHCI.
when I need USB 3.0 for the very few devices, I connected them to the computer directly.
USB2517
-------
I wanted to use the FE2.1 7-port USB hub chip.
it does not need an external voltage regulator or crystal.
it is easier to solder thanks to its TQFP package, and provides all required functionalities.
sadly I could not find a source for the 64-pin packages, and the 48-pin variant does not provide all required functionalities.
thus I had to fall back to the Microchip USB2517, which uses a harder to solder QFN package.
power control
-------------
some USB hub chips allow to remotely control the power output on individual ports.
this capability is here also used to control the power on the higher voltage output.
thus you can completely power off even larger target devices.
current limitation
------------------
the USB hub has current limitation on the output.
this does limit the current to 500 mA, but only in constant current mode.
following current limiters have been tested:
- 0.5A PPTC fuse: it takes too long to trigger (> 1s), and switch off is not reliably detected
- MT9700: it has no over-current signal
- SY6288AAAC: the (fixed) current limit is not 0.6A, but around 1.5A
- TJ2242GSF6: over-current is only detected after 3s (instead of specified 100us, probably caused by thermal shutdown), and it is not signaled
- DIO7553ST6: works as expected and wished
the power distribution switch detects the over-current state and asserts the fault flag after 10 ms.
after 0.1 ms (as set in OC_TIMER, in Configuration Data Byte 2, in EEPROM) the hub will switch off power.
this also clears the over-current state.
after 100 ms the HUB will re-enable power.
this loop will repeat indefinitely.
no over-current is reported to the host in this case (when the over-current is cleared while power is off).
it is only reported when the OCS is asserted for longer (unknown time, with OCS kept low also when powered off).
this is a flaw of the USB2517, where the over-current is only reported if it can't control the power state.
I did not find a configuration option for this aspect in the datasheet.
LED color
---------
the USB specification, LEDs are used as port indicator (section 11.5.3)
- off: powered off/disconnected
- amber: current limitation reached
- green: enabled or transmitting
instead the following color scheme is used:
- green off: power off or over-current
- green on: power on
- red: low speed device connected
- blue: full speed device connected
- purple (red+blue): high speed device connected
- red and blue off: disconnected or in sleep
power output
------------
switching the power of the USB port also switches the 6-40V forward output.
when the 6-40V input is not connected, current/voltage feedback from the outputs is blocked.
usage
=====
it mainly works like a regular USB hub, at least when it comes to the data transfer.
just plug the device in a port.
power on the Downstream Facing Ports (DFPs) is only available when the Upstream Facing Port (UFP) is connected.
the hub can operate as bus powered (power coming from the UFP), but it would not be able to provide more than 500 mA across all DFPs.
it is preferable to connect an external 5V power supply to be able to provide 500 mA on all DFPs.
this will also turn the hub into self powered, not using any power from the UFP.
alternatively, you can connect a 6 to 40V power supply on the other power input.
the power for the hub and the 5V for the DFP will be derivate from this higher voltage supply.
the same higher voltage will be available on the power output next to the individual DFPs.
the hub will not switch on until the UFP USB port is connected.
a switch next to each DFP allows to turn off the power output on the USB and power ports.
the green LED is on when power output is available.
the power output on the USB and power ports can also be turned on/off remotely using standard USB commands.
this power output control is implemented in [uhubctl](https://github.com/mvp/uhubctl):
~~~
# list controllable USB hub ports
sudo uhubctl
# switch of port
uhubctl --action off --location 1-1.4 --ports 5
~~~
EEPROM
======
the USB2517 USB hub chip gets its configuration from an EEPROM.
to generate the configuration:
~~~
ruby eeprom.rb
~~~
this will create the `eeprom.bin` binary file.
feel free to adjust the configuration in the generating script, such as the serial number.
after having soldered all the parts on the board, connect a programmer (here a MiniPRO TL866xx) on the J4 pin header to write the AT24C02 EEPROM:
~~~
minipro --device "AT24C02@SOIC8" --write eeprom.bin -s
~~~

191
Rakefile Normal file
View File

@ -0,0 +1,191 @@
# 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 = "usb_hub"
# additional schematic sheets
sheets = ["usb_hub-dfp1", "usb_hub-dfp2", "usb_hub-dfp3", "usb_hub-dfp4", "usb_hub-dfp5", "usb_hub-dfp6", "usb_hub-dfp7"]
# 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" ]
unless sheets.empty? then
prints += sheets.collect{|sheet| "#{sheet}.sch.pdf"}
prints << "#{name}.sch-all.pdf"
end
task :print => prints
CLEAN.include([ "#{name}.versioned.sch", "#{name}.versioned.lht" ] + sheets.collect{|sheet| "#{sheet}.versioned.sch"})
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 grouped printable version (PDF) of schematic"
rule ".sch-all.pdf" => ["#{name}.sch.pdf"] + sheets.collect{|sheet| "#{sheet}.sch.pdf"} do |t|
sh "mutool merge -o #{t.name} " + t.prerequisites * " "
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

108
bom.ini
View File

@ -1,108 +0,0 @@
[BOM_OPTIONS]
; General BoM options here
; If 'ignore_dnf' option is set to 1, rows that are not to be fitted on the PCB will not be written to the BoM file
ignore_dnf = 0
; If 'html_generate_dnf' option is set to 1, also generate a list of components not fitted on the PCB (HTML only)
html_generate_dnf = 1
; If 'use_alt' option is set to 1, grouped references will be printed in the alternate compressed style eg: R1-R7,R18
use_alt = 0
; If 'alt_wrap' option is set to and integer N, the references field will wrap after N entries are printed
alt_wrap = 0
; If 'number_rows' option is set to 1, each row in the BoM will be prepended with an incrementing row number
number_rows = 1
; If 'group_connectors' option is set to 1, connectors with the same footprints will be grouped together, independent of the name of the connector
group_connectors = 1
; If 'test_regex' option is set to 1, each component group will be tested against a number of regular-expressions (specified, per column, below). If any matches are found, the row is ignored in the output file
test_regex = 1
; If 'merge_blank_fields' option is set to 1, component groups with blank fields will be merged into the most compatible group, where possible
merge_blank_fields = 1
; Specify output file name format, %O is the defined output name, %v is the version, %V is the variant name which will be ammended according to 'variant_file_name_format'.
output_file_name = %O%V
; Specify the variant file name format, this is a unique field as the variant is not always used/specified. When it is unused you will want to strip all of this.
variant_file_name_format = _(%V)
; Field name used to determine if a particular part is to be fitted
fit_field = Config
; Make a backup of the bom before generating the new one, using the following template
;make_backup = %O.tmp
; Default number of boards to produce if none given on CLI with -n
number_boards = 1
; Default PCB variant if none given on CLI with -r
board_variant = ['default']
; Whether to hide headers from output file
hide_headers = False
; Whether to hide PCB info from output file
hide_pcb_info = False
[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
qeda_part
qeda_variant
name
JLCPCB_CORRECTION
Rating
[COLUMN_ORDER]
; Columns will appear 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
Manufacturer
MPN
DigiKey
LCSC
JLCPCB
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
Value
Footprint
Footprint Lib
[COMPONENT_ALIASES]
; A series of values which are considered to be equivalent for the part name
; Each line represents a list of equivalent component name values separated by white space
; e.g. 'c c_small cap' will ensure the equivalent capacitor symbols can be grouped together
; Aliases are case-insensitive
c c_small cap capacitor
r r_small res resistor
sw switch
l l_small inductor
zener zenersmall
d diode d_small
[REGEX_INCLUDE]
; A series of regular expressions used to include parts in the BoM
; If there are any regex defined here, only components that match against ANY of them will be included in the BOM
; Column names are case-insensitive
; Format is: "[ColumName] [Regex]" (white-space separated)
[REGEX_EXCLUDE]
; A series of regular expressions used to exclude parts from the BoM
; If a component matches ANY of these, it will be excluded from the BoM
; Column names are case-insensitive
; Format is: "[ColumName] [Regex]" (white-space separated)
References ^TP[0-9]*
References ^FID
Part mount.*hole
Part solder.*bridge
Part test.*point
Footprint test.*point
Footprint mount.*hole
Footprint fiducial

View File

@ -0,0 +1,187 @@
$fn=30;
BOARD_WIDTH=96.5;
BOARD_HEIGHT=96.0;
BOARD_THICKNESS=1.6;
HOLE_NW_X=4.0;
HOLE_NW_Y=4.0;
HOLE_NE_X=92.5;
HOLE_NE_Y=4.0;
HOLE_SW_X=4.0;
HOLE_SW_Y=92.0;
HOLE_SE_X=92.5;
HOLE_SE_Y=92.0;
WALL_SPACE=1.0;
WALL_THICKNESS=2.0;
HOLE_HEIGHT=15.0; // USB A is 14.5
module pillar() {
translate([0,0,HOLE_HEIGHT/2]) {
difference() {
cylinder(h=HOLE_HEIGHT, d=6, center=true);
cylinder(h=HOLE_HEIGHT, d=3.5, center=true);
}
}
}
mirror([1,0,0]) { // we used bottom view
// bottom plate
cube([BOARD_WIDTH+2*WALL_SPACE+2*WALL_THICKNESS, BOARD_HEIGHT+2*WALL_SPACE+2*WALL_THICKNESS, WALL_THICKNESS]);
// screw mounts
translate([WALL_THICKNESS+WALL_SPACE+HOLE_NW_X,WALL_THICKNESS+WALL_SPACE+HOLE_NW_Y,WALL_THICKNESS]) {
pillar();
}
translate([WALL_THICKNESS+WALL_SPACE+HOLE_NE_X,WALL_THICKNESS+WALL_SPACE+HOLE_NE_Y,WALL_THICKNESS]) {
pillar();
}
translate([WALL_THICKNESS+WALL_SPACE+HOLE_SW_X,WALL_THICKNESS+WALL_SPACE+HOLE_SW_Y,WALL_THICKNESS]) {
pillar();
}
translate([WALL_THICKNESS+WALL_SPACE+HOLE_SE_X,WALL_THICKNESS+WALL_SPACE+HOLE_SE_Y,WALL_THICKNESS]) {
pillar();
}
// side
MARGIN=1.0;
USB_B_WIDTH=12.0+MARGIN;
USB_B_HEIGHT=11.0+MARGIN;
USB_A_WIDTH=7.0+MARGIN;
USB_A_HEIGHT=14.5+MARGIN;
BARREL_WIDTH=9.0+MARGIN;
BARREL_HEIGHT=11.3+MARGIN;
INDUCTOR_HEIGHT=7.5;
// side north
difference() {
cube([BOARD_WIDTH+2*WALL_SPACE+2*WALL_THICKNESS, WALL_THICKNESS, WALL_THICKNESS+HOLE_HEIGHT+BOARD_THICKNESS+INDUCTOR_HEIGHT]);
// DFP 7 USB A
translate([WALL_THICKNESS+WALL_SPACE+12.5-USB_A_WIDTH/2,0,WALL_THICKNESS+HOLE_HEIGHT-USB_A_HEIGHT]) {
cube([USB_A_WIDTH,WALL_THICKNESS,USB_A_HEIGHT]);
}
// DFP 7 BARREL
translate([WALL_THICKNESS+WALL_SPACE+28-BARREL_WIDTH/2,0,WALL_THICKNESS+HOLE_HEIGHT-BARREL_HEIGHT]) {
cube([BARREL_WIDTH,WALL_THICKNESS,BARREL_HEIGHT]);
}
// DFP 6 USB A
translate([WALL_THICKNESS+WALL_SPACE+40.5-USB_A_WIDTH/2,0,WALL_THICKNESS+HOLE_HEIGHT-USB_A_HEIGHT]) {
cube([USB_A_WIDTH,WALL_THICKNESS,USB_A_HEIGHT]);
}
// DFP 6 BARREL
translate([WALL_THICKNESS+WALL_SPACE+56-BARREL_WIDTH/2,0,WALL_THICKNESS+HOLE_HEIGHT-BARREL_HEIGHT]) {
cube([BARREL_WIDTH,WALL_THICKNESS,BARREL_HEIGHT]);
}
// DFP 5 USB A
translate([WALL_THICKNESS+WALL_SPACE+68.5-USB_A_WIDTH/2,0,WALL_THICKNESS+HOLE_HEIGHT-USB_A_HEIGHT]) {
cube([USB_A_WIDTH,WALL_THICKNESS,USB_A_HEIGHT]);
}
// DFP 5 BARREL
translate([WALL_THICKNESS+WALL_SPACE+84-BARREL_WIDTH/2,0,WALL_THICKNESS+HOLE_HEIGHT-BARREL_HEIGHT]) {
cube([BARREL_WIDTH,WALL_THICKNESS,BARREL_HEIGHT]);
}
}
// side west
difference() {
cube([WALL_THICKNESS, BOARD_HEIGHT+2*WALL_SPACE+2*WALL_THICKNESS, WALL_THICKNESS+HOLE_HEIGHT+BOARD_THICKNESS+INDUCTOR_HEIGHT]);
// USB B
translate([0,WALL_THICKNESS+WALL_SPACE+48-USB_B_WIDTH/2,WALL_THICKNESS+HOLE_HEIGHT-USB_B_HEIGHT]) {
cube([WALL_THICKNESS,USB_B_WIDTH,USB_B_HEIGHT]);
}
// 5V BARREL
translate([0,WALL_THICKNESS+WALL_SPACE+33-BARREL_WIDTH/2,WALL_THICKNESS+HOLE_HEIGHT-BARREL_HEIGHT]) {
cube([WALL_THICKNESS,BARREL_WIDTH,BARREL_HEIGHT]);
}
// 12V BARREL
translate([0,WALL_THICKNESS+WALL_SPACE+63-BARREL_WIDTH/2,WALL_THICKNESS+HOLE_HEIGHT-BARREL_HEIGHT]) {
cube([WALL_THICKNESS,BARREL_WIDTH,BARREL_HEIGHT]);
}
}
// side south
translate([0,BOARD_HEIGHT+WALL_THICKNESS+2*WALL_SPACE,0]) {
difference() {
cube([BOARD_WIDTH+2*WALL_SPACE+2*WALL_THICKNESS, WALL_THICKNESS, WALL_THICKNESS+HOLE_HEIGHT+BOARD_THICKNESS+INDUCTOR_HEIGHT]);
// DFP 1 USB A
translate([WALL_THICKNESS+WALL_SPACE+27.5-USB_A_WIDTH/2,0,WALL_THICKNESS+HOLE_HEIGHT-USB_A_HEIGHT]) {
cube([USB_A_WIDTH,WALL_THICKNESS,USB_A_HEIGHT]);
}
// DFP 1 BARREL
translate([WALL_THICKNESS+WALL_SPACE+12-BARREL_WIDTH/2,0,WALL_THICKNESS+HOLE_HEIGHT-BARREL_HEIGHT]) {
cube([BARREL_WIDTH,WALL_THICKNESS,BARREL_HEIGHT]);
}
// DFP 2 USB A
translate([WALL_THICKNESS+WALL_SPACE+55.5-USB_A_WIDTH/2,0,WALL_THICKNESS+HOLE_HEIGHT-USB_A_HEIGHT]) {
cube([USB_A_WIDTH,WALL_THICKNESS,USB_A_HEIGHT]);
}
// DFP 2 BARREL
translate([WALL_THICKNESS+WALL_SPACE+40-BARREL_WIDTH/2,0,WALL_THICKNESS+HOLE_HEIGHT-BARREL_HEIGHT]) {
cube([BARREL_WIDTH,WALL_THICKNESS,BARREL_HEIGHT]);
}
// DFP 3 USB A
translate([WALL_THICKNESS+WALL_SPACE+83.5-USB_A_WIDTH/2,0,WALL_THICKNESS+HOLE_HEIGHT-USB_A_HEIGHT]) {
cube([USB_A_WIDTH,WALL_THICKNESS,USB_A_HEIGHT]);
}
// DFP 3 BARREL
translate([WALL_THICKNESS+WALL_SPACE+68-BARREL_WIDTH/2,0,WALL_THICKNESS+HOLE_HEIGHT-BARREL_HEIGHT]) {
cube([BARREL_WIDTH,WALL_THICKNESS,BARREL_HEIGHT]);
}
}
}
// side east
translate([BOARD_WIDTH+WALL_THICKNESS+2*WALL_SPACE,0,0]) {
difference() {
cube([WALL_THICKNESS, BOARD_HEIGHT+2*WALL_SPACE+2*WALL_THICKNESS, WALL_THICKNESS+HOLE_HEIGHT+BOARD_THICKNESS+INDUCTOR_HEIGHT]);
// DFP 4 USB A
translate([0,WALL_THICKNESS+WALL_SPACE+40.5-USB_A_WIDTH/2,WALL_THICKNESS+HOLE_HEIGHT-USB_A_HEIGHT]) {
cube([WALL_THICKNESS,USB_A_WIDTH,USB_A_HEIGHT]);
}
// DFP 4 BARREL
translate([0,WALL_THICKNESS+WALL_SPACE+56-BARREL_WIDTH/2,WALL_THICKNESS+HOLE_HEIGHT-BARREL_HEIGHT]) {
cube([WALL_THICKNESS,BARREL_WIDTH,BARREL_HEIGHT]);
}
}
}
// top plate
SWITCH_WIDTH=3.0+0.5;
SWITCH_LENGTH=6.0+0.5;
translate([0,0,WALL_THICKNESS+HOLE_HEIGHT+BOARD_THICKNESS+INDUCTOR_HEIGHT]) {
difference() {
cube([BOARD_WIDTH+2*WALL_SPACE+2*WALL_THICKNESS, BOARD_HEIGHT+2*WALL_SPACE+2*WALL_THICKNESS, WALL_THICKNESS]);
// DFP 7
translate([WALL_THICKNESS+WALL_SPACE+20.0, WALL_THICKNESS+WALL_SPACE+6.7,WALL_THICKNESS/2]) {
cube([SWITCH_WIDTH, SWITCH_LENGTH, WALL_THICKNESS], center=true);
}
// DFP 6
translate([WALL_THICKNESS+WALL_SPACE+48.0, WALL_THICKNESS+WALL_SPACE+6.7,WALL_THICKNESS/2]) {
cube([SWITCH_WIDTH, SWITCH_LENGTH, WALL_THICKNESS], center=true);
}
// DFP 5
translate([WALL_THICKNESS+WALL_SPACE+76.0, WALL_THICKNESS+WALL_SPACE+6.7,WALL_THICKNESS/2]) {
cube([SWITCH_WIDTH, SWITCH_LENGTH, WALL_THICKNESS], center=true);
}
// DFP 4
translate([WALL_THICKNESS+WALL_SPACE+89.7, WALL_THICKNESS+WALL_SPACE+48.0,WALL_THICKNESS/2]) {
cube([SWITCH_LENGTH, SWITCH_WIDTH, WALL_THICKNESS], center=true);
}
// DFP 3
translate([WALL_THICKNESS+WALL_SPACE+76.0, WALL_THICKNESS+WALL_SPACE+89.3,WALL_THICKNESS/2]) {
cube([SWITCH_WIDTH, SWITCH_LENGTH, WALL_THICKNESS], center=true);
}
// DFP 2
translate([WALL_THICKNESS+WALL_SPACE+48.0, WALL_THICKNESS+WALL_SPACE+89.3,WALL_THICKNESS/2]) {
cube([SWITCH_WIDTH, SWITCH_LENGTH, WALL_THICKNESS], center=true);
}
// DFP 1
translate([WALL_THICKNESS+WALL_SPACE+20.0, WALL_THICKNESS+WALL_SPACE+89.3,WALL_THICKNESS/2]) {
cube([SWITCH_WIDTH, SWITCH_LENGTH, WALL_THICKNESS], center=true);
}
}
}
}

Binary file not shown.

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="103mm"
height="102mm"
viewBox="-103 -102 103 102"
version="1.1"
id="svg4172"
sodipodi:docname="top_plate.svg"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs4176" />
<sodipodi:namedview
id="namedview4174"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.0246119"
inkscape:cx="362.08831"
inkscape:cy="323.04914"
inkscape:window-width="1916"
inkscape:window-height="1041"
inkscape:window-x="0"
inkscape:window-y="37"
inkscape:window-maximized="1"
inkscape:current-layer="svg4172" />
<title
id="title4168">OpenSCAD Model</title>
<path
d=" M 0,-102 L -102.5,-102 L -102.5,-0 L 0,-0 z M -24.75,-89.05 L -24.75,-95.55 L -21.25,-95.55 L -21.25,-89.05 z M -52.75,-89.05 L -52.75,-95.55 L -49.25,-95.55 L -49.25,-89.05 z M -80.75,-89.05 L -80.75,-95.55 L -77.25,-95.55 L -77.25,-89.05 z M -95.95,-49.25 L -95.95,-52.75 L -89.45,-52.75 L -89.45,-49.25 z M -24.75,-6.45 L -24.75,-12.95 L -21.25,-12.95 L -21.25,-6.45 z M -52.75,-6.45 L -52.75,-12.95 L -49.25,-12.95 L -49.25,-6.45 z M -80.75,-6.45 L -80.75,-12.95 L -77.25,-12.95 L -77.25,-6.45 z "
stroke="black"
fill="lightgray"
stroke-width="0.5"
id="path4170"
style="stroke:#ff0000;fill:none" />
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,307 @@
# subcircuit generated using QEDA
li:pcb-rnd-subcircuit-v6 {
ha:subc.1 {
uid = CAPC1608X92N............
ha:attributes {
footprint = CAPC1608X92N
}
ha:data {
li:padstack_prototypes {
ha:ps_proto_v6.2 {
htop = 0
hbottom = 0
hdia = 0
hplated = 0
li:shape {
ha:ps_shape_v4 {
clearance = 0.200mm
li:ps_poly {
-0.625mm
-0.550mm
0.625mm
-0.550mm
0.625mm
0.550mm
-0.625mm
0.550mm
}
ha:layer_mask {
top = 1
copper = 1
}
ha:combining {
}
}
ha:ps_shape_v4 {
clearance = 0
li:ps_poly {
-0.675mm
-0.600mm
0.675mm
-0.600mm
0.675mm
0.600mm
-0.675mm
0.600mm
}
ha:layer_mask {
top = 1
mask = 1
}
ha:combining {
sub = 1
auto = 1
}
}
ha:ps_shape_v4 {
clearance = 0
li:ps_poly {
-0.625mm
-0.550mm
0.625mm
-0.550mm
0.625mm
0.550mm
-0.625mm
0.550mm
}
ha:layer_mask {
</