Compare commits
82 Commits
master
...
hdmi_firew
Author | SHA1 | Date | |
---|---|---|---|
8ea411fd8a | |||
18926c4cc9 | |||
94a112b154 | |||
23511e68e1 | |||
7358be50e2 | |||
bf869eee8d | |||
46d106d99c | |||
d72dba822c | |||
867e6949b7 | |||
4e82cef602 | |||
fa94f37ba8 | |||
58eacec914 | |||
3060b0dc05 | |||
ce234c7b01 | |||
034ddca6f0 | |||
759e93f5b7 | |||
84d4db186d | |||
4f18284b9e | |||
f3c0a314bc | |||
66a4f4a6c8 | |||
f0fe042e87 | |||
83f775ae09 | |||
0ed8f07910 | |||
ed8c064687 | |||
9581f99519 | |||
b66dfda066 | |||
8768c787f8 | |||
ecc0d8434e | |||
45681e2751 | |||
0527253b29 | |||
aaaa7a9e06 | |||
8ca03d7661 | |||
0230a77cd5 | |||
7b81cfd1ac | |||
f5707eb56d | |||
977d2d6cc7 | |||
0f76fd4089 | |||
b207b61db9 | |||
d83cfc5fe3 | |||
8b9c72f70c | |||
e72c683999 | |||
cafca73743 | |||
cb7aa78b06 | |||
bc8a9bfc1d | |||
ddfbc49814 | |||
c19bc12a7a | |||
d90cd5f8b5 | |||
2afed4573d | |||
9f2e004521 | |||
15302eeda9 | |||
5422ab7704 | |||
156ef34a0e | |||
e0d9b8377c | |||
0c9f27138d | |||
9446c621ae | |||
71caf5f793 | |||
932f0e07e9 | |||
9a67bac5f1 | |||
ece0aa4730 | |||
432de7d2c8 | |||
3d6d42d1d8 | |||
7531f02225 | |||
dabf167b5f | |||
473587a9e8 | |||
be24d31ddd | |||
588e570e0d | |||
fd9d7780c9 | |||
38f031e202 | |||
162f540837 | |||
b35c3526d2 | |||
9087beec8e | |||
ff3fe4f2c4 | |||
132f2e1317 | |||
daf23c9afe | |||
e59a0f732d | |||
dfc9010874 | |||
a23e5228da | |||
43cb77c7b6 | |||
7d6caee37e | |||
c9adea88e4 | |||
122543235d | |||
3b7e68fd46 |
46
.gitignore
vendored
46
.gitignore
vendored
@ -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
|
||||
|
11
.qeda.yaml
11
.qeda.yaml
@ -1,10 +1,17 @@
|
||||
config:
|
||||
output: coraleda
|
||||
output: kicad
|
||||
pattern:
|
||||
densityLevel: 'N'
|
||||
lineWidth:
|
||||
silkscreen: 0.2
|
||||
polarityMark: none
|
||||
preferManufacturer: false
|
||||
preferManufacturer: true
|
||||
smoothPadCorners: false
|
||||
library:
|
||||
- connector/hdmi-001s
|
||||
- ic/eeprom_ft24c16a-e@l
|
||||
- resistor/r0603
|
||||
- capacitor/c0603
|
||||
- mcu/st_stm8s003x3@p
|
||||
- mechanical/dip-switch_dsicxxls@dsic07ls
|
||||
- diode/led0805
|
||||
|
34
CHANGELOG.md
34
CHANGELOG.md
@ -0,0 +1,34 @@
|
||||
v2
|
||||
==
|
||||
|
||||
instead of an edge plug, the monitor connector is also a receptacle.
|
||||
this prevents the firewall from sticking out of the monitor too much, particularly when installed in tight spaces.
|
||||
it also allows to place the HDMI firewall inline even if you don't have access to the monitor's HDMI port.
|
||||
finally it also allows the board to be manufactured more easily.
|
||||
|
||||
the programmer is now included in the firewall.
|
||||
this offers very easy copy of the EDID data.
|
||||
no need to use complex linux commands or stand-alone separate programmer.
|
||||
the programmer uses the embedded EEPROM and acts as I²C slave.
|
||||
|
||||
a DIP switch allows to selectively block or forward interfaces.
|
||||
|
||||
v1
|
||||
==
|
||||
|
||||
this version comes as dongle, which can directly be plugged in the monitor.
|
||||
the impedance and length of the differential signal pairs are properly taken care of.
|
||||
a breakable tab replaces the WP switch.
|
||||
pads are still present to override the disabled WP and 5V.
|
||||
|
||||
the shield is not connected to ground, which causes EEPROM read errors with cheap HDMI cables skimping on the ground wire (pin 17).
|
||||
the workaround is to scratch the solder mask near one of the HDMI receptacle shell tab and solder it.
|
||||
|
||||
v0
|
||||
==
|
||||
|
||||
first working version.
|
||||
|
||||
based on the design of the original research.
|
||||
the HDMI connectors are on opposite sides of the board to make the routing easy (the differential signals are straight lines).
|
||||
the impedance does not seem to by optimal, leading to EMF leakage (reported by the original researchers).
|
@ -1,19 +1,23 @@
|
||||
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)
|
||||
- make: takes care of generating the output 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
|
||||
-------
|
||||
|
||||
@ -35,26 +39,23 @@ 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
|
||||
@ -62,21 +63,30 @@ 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.
|
||||
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/.
|
||||
it uses the footprints from the `kicad/` folder.
|
||||
most footprints are generated by QEDA as described above.
|
||||
|
||||
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
|
||||
|
11
JLCPCB_CORRECTION.csv
Normal file
11
JLCPCB_CORRECTION.csv
Normal file
@ -0,0 +1,11 @@
|
||||
package;x;y;rot
|
||||
LEDC2012X80N;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;180
|
||||
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
|
|
71
Makefile
Normal file
71
Makefile
Normal file
@ -0,0 +1,71 @@
|
||||
# project file name (use for schematic and board layout)
|
||||
NAME ?= hdmi_firewall
|
||||
# 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}
|
214
README.md
214
README.md
@ -1,7 +1,219 @@
|
||||
these are the hardware design files for **insert project name here**.
|
||||
The HDMI firewall prevents devices from hacking HDMI equipment, and vice-versa.
|
||||
|
||||
<img src="picture/front_v2.webp" title="front" height="250"/>
|
||||
<img src="picture/back_v2.webp" title="back" height="250"/>
|
||||
|
||||
purpose
|
||||
=======
|
||||
|
||||
HDMI is mainly used to transfer audio and video, but also offers a number of additional features (e.g. HDCP, CEC, HEC, ARC, MHL).
|
||||
This increases the attack surface, and since the security of their implement in embedded devices is far from ideal, an attacker could exploit them and inject malicious code.
|
||||
Now your unsuspicious video equipment is compromised and threatens your IT/network security.
|
||||
And your monitor could then in turn hack back any other device connected to it.
|
||||
|
||||
For example, let's imagine you invite an external guest for a presentation inside your company.
|
||||
You offer to connect to a smart TV or video-projector so he can show his slides.
|
||||
This is the perfect opportunity for the guest to hack it.
|
||||
Now your smart TV can act as a spy in your network.
|
||||
Or next time an employee connects to the projector, his laptop is hacked back.
|
||||
And voila, the innocent guest managed to infiltrate your company network, and can exfiltrate confidential information.
|
||||
|
||||
The HDMI firewall can block all additional interfaces, and only allow audio and video data transfer.
|
||||
It is based on the research of Pierre-Michel Ricordel and José Lopes Esteves from ANSSI/SDE/ST/LSF presented at the IT security conference [SSTIC 2021](https://sstic.org/2021/presentation/un_pare_feu_pour_le_hdmi/).
|
||||
Some security research and vulnerabilities around CEC and EDID are listed in [slide 4](https://www.sstic.org/media/SSTIC2021/SSTIC-actes/un_pare_feu_pour_le_hdmi/SSTIC2021-Slides-un_pare_feu_pour_le_hdmi-lopes-esteves_ricordel.pdf).
|
||||
|
||||
usage
|
||||
=====
|
||||
|
||||
First plug the HDMI cable going to the monitor on the HDMI firewall on the port labeled **MONITOR**.
|
||||
Then plug the HDMI cable going to the device on the HDMI firewall on the port labeled **DEVICE**.
|
||||
That's it, your equipment (monitor and device) are now protected.
|
||||
But the firewall should be fine tuned as described below.
|
||||
|
||||
The HDMI firewall comes with a generic HD profile, but this might not correspond to the capabilities of your monitor.
|
||||
The resulting image could be distorted, or completely missing.
|
||||
Thus, you first have to copy the Extended Display Identification Data (EDID) information of the equipment to protect.
|
||||
This data includes information such as the supported resolutions.
|
||||
The HDMI firewall can copy the EDID from the monitor:
|
||||
|
||||
1. ensure the firewall is connected to the monitor
|
||||
1. unplug the device from the firewall
|
||||
1. toggle the small switch labeled EDID/7 to the ALLOW/ON position
|
||||
1. ensure the SDA/2 and SCL/3 switches are on the BLOCK/OFF position
|
||||
1. plug the device to the firewall
|
||||
1. this will power the firewall, which will copy the monitor EDID onto its internal memory, shown by a short blink of the ERROR LED
|
||||
1. unplug the device, and switch back the EDID/7 switch to the BLOCK/OFF position so the firewall keeps and uses the copied EDID information
|
||||
1. when connecting the device back in, you should see the same name as the monitor, with a '|' at the end, indicating you are using the EDID from the firewall
|
||||
|
||||
The HDMI firewall allows to select which interfaces are blocked using the switches.
|
||||
The highest security is provided when blocking all lines by setting the switches to the BLOCK position.
|
||||
If you still trust your equipment enough and want to use a feature, you can set the corresponding switch to the ALLOW/ON position:
|
||||
|
||||
- 5V: some monitors require this line to detect when a device is plugged in, and since currently no other information is transferred over this line, it is rather safe to enable it
|
||||
- Display Data Channel (DDC): High-bandwidth Digital Content Protection (HDCP) uses this interface. To enable it, switch SDA and SCL on. Warning: since the EDID is also transferred over this interface, the firewall can't provide a write-protected copy of it. Instead the original monitor EDID is used, maybe not write-protected.
|
||||
- Consumer Electronics Control (CEC): this interface allows to remotely control equipment, such as setting the volume and powering on/off all connected devices and monitors at once
|
||||
- HDMI Ethernet Channel (HEC), Audio Return Channel (ARC), and Mobile High-Definition Link (MHL): to enable these interfaces, switch UTIL and HPD on to forward the HEAC+ and HEAC- lines
|
||||
|
||||
The HDMI firewall can also be used to provide custom EDID, as it sometimes is faulty in the monitor.
|
||||
For that you need to program the raw binary EDID (with up to 1 extension block) onto the STM8S103 EEPROM using the RST and SWIM lines made available on the back of the board.
|
||||
|
||||
limitations
|
||||
===========
|
||||
|
||||
The HDMI firewall use impedance controlled lines: 4-layer impedance controlled board, differential pair routing, intra- and inter-pair length matching.
|
||||
This should allow and audio any video signal to be transmitted to the monitor.
|
||||
But I only have 2K equipment I could test it on.
|
||||
I could not test the firewall against 4K, 8K, or 3D capable monitors.
|
||||
CEC remote control has been tested.
|
||||
But I don't have any equipment using HDCP, HEC, ARC, or MHL.
|
||||
Thus I could also not test these interfaces.
|
||||
|
||||
The firewall only supports EDID with up to 1 extension block.
|
||||
This is the case for all monitors I've seen.
|
||||
Some high end monitors supporting numerous features might have additional extensions blocks.
|
||||
Thus the firewall might prevent from using the monitor to its full potential.
|
||||
You can still use the original EDID from the monitor by setting the SDA/2 and SCL/3 switches to the ALLOW/ON position.
|
||||
The DDC channel won't be firewalled anymore though.
|
||||
|
||||
Feel free to report any success or issues to `hdmi@cuvoodoo.info`.
|
||||
|
||||
availability
|
||||
============
|
||||
|
||||
The HDMI firewall is available on [tindie](https://www.tindie.com/products/cuvoodoo/hdmi-firewall/).
|
||||
|
||||
The schematic pdf and board gerbers are available as [release](https://git.cuvoodoo.info/kingkevin/board/releases/tag/hdmi_firewall_v2).
|
||||
|
||||
firmware
|
||||
========
|
||||
|
||||
The firmware and sources for the HDMI firewall embedded programmer are available [here](https://git.cuvoodoo.info/kingkevin/stm8s/src/branch/hdmi_firewall).
|
||||
|
||||
troubleshooting
|
||||
===============
|
||||
|
||||
If the monitor does not detect the device or does not display anything (but should), try to re-enable the 5V forward (as per default) by switching the 5V/1 switch to ALLOW/ON.
|
||||
|
||||
If the ERROR LED stays on, it means copying the EDID failed:
|
||||
|
||||
- be sure the monitor is connected before you connect the device (which powers the firewall)
|
||||
- be sure the SDA/2 and SCL/3 switches are set to BLOCK so the firewall can use the DDC interface to read the EDID
|
||||
- the EDID of the monitor might be corrupted or have an invalid checksum, in which case the firewall will not copy it
|
||||
- the firewall EEPROM memory has worn out or is defective (it should last 300 thousand copies)
|
||||
|
||||
custom EDID
|
||||
===========
|
||||
|
||||
It is possible to write custom EDID on the HDMI firewall, for example because:
|
||||
|
||||
- the monitor's original EDID is corrupted
|
||||
- you want to disable a feature or resolution causing your device to misbehave
|
||||
- you want to re-enable a feature the monitor actually supports
|
||||
- the KVM switch does not reflect the HDMI monitor change
|
||||
- you want to do security research
|
||||
|
||||
For that you can use the debugging pins left on the board, and [program](https://git.cuvoodoo.info/kingkevin/stm8s/src/branch/hdmi_firewall/README.md) the raw EDID in the STM8S EEPROM area using an ST-LINK/V2 programmer.
|
||||
|
||||
If you switch EDID to the ALLOW position, the HDMI firewall's EEPROM is not write-protected (on devices shipped after 2022-08-19).
|
||||
This allows to use the HDMI connection to write the EEPROM content using the DDC's I²C bus, and does not required an external programmer.
|
||||
|
||||
These instructions are for Linux.
|
||||
For Windows see the instructions provided in the [original research slides](https://www.sstic.org/media/SSTIC2021/SSTIC-actes/un_pare_feu_pour_le_hdmi/SSTIC2021-Slides-un_pare_feu_pour_le_hdmi-lopes-esteves_ricordel.pdf) (untested).
|
||||
|
||||
Install tools to read/write I²C devices:
|
||||
|
||||
- for Debian-based distributions
|
||||
|
||||
~~~
|
||||
sudo apt install i2c-tools
|
||||
~~~
|
||||
|
||||
Make the I²C buses user accessible (under /dev/i2c-*):
|
||||
|
||||
~~~
|
||||
sudo modprobe i2c-dev
|
||||
~~~
|
||||
|
||||
Now we have to figure out which I²C bus corresponds to the HDMI port.
|
||||
First list the available buses:
|
||||
|
||||
~~~
|
||||
sudo i2cdetect -l
|
||||
~~~
|
||||
|
||||
You should see something like this:
|
||||
|
||||
~~~
|
||||
i2c-0 smbus SMBus PIIX4 adapter port 0 at 0b00 SMBus adapter
|
||||
i2c-1 smbus SMBus PIIX4 adapter port 2 at 0b00 SMBus adapter
|
||||
i2c-2 smbus SMBus PIIX4 adapter port 1 at 0b20 SMBus adapter
|
||||
i2c-3 i2c AMDGPU DM i2c hw bus 0 I2C adapter
|
||||
i2c-4 i2c AMDGPU DM i2c hw bus 1 I2C adapter
|
||||
i2c-5 i2c AMDGPU DM i2c hw bus 2 I2C adapter
|
||||
i2c-6 i2c AMDGPU DM i2c hw bus 3 I2C adapter
|
||||
i2c-7 i2c AMDGPU DM aux hw bus 0 I2C adapter
|
||||
i2c-8 i2c AMDGPU DM aux hw bus 2 I2C adapter
|
||||
i2c-9 i2c AMDGPU DM aux hw bus 3 I2C adapter
|
||||
i2c-10 i2c DPMST I2C adapter
|
||||
i2c-11 i2c DPMST I2C adapter
|
||||
~~~
|
||||
|
||||
Candidate buses are 3 to 9, used by the GPU (number after i2c- in the first column).
|
||||
|
||||
Disconnect everything from the HDMI port, and scan for devices on each I²C bus (replace BUS with the bus number):
|
||||
|
||||
~~~
|
||||
sudo i2cdetect -y BUS
|
||||
~~~
|
||||
|
||||
Since nothing is connected, no device should be detected, and the output should look like this:
|
||||
|
||||
~~~
|
||||
0 1 2 3 4 5 6 7 8 9 a b c d e f
|
||||
00: -- -- -- -- -- -- -- --
|
||||
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
70: -- -- -- -- -- -- -- --
|
||||
~~~
|
||||
|
||||
Now connect the HDMI firewall on the device side to your HDMI port and re-scan for devices.
|
||||
If you see the following result, you found the I²C bus of the HDMI port.
|
||||
Else continue with the next bus.
|
||||
|
||||
~~~
|
||||
0 1 2 3 4 5 6 7 8 9 a b c d e f
|
||||
00: -- -- -- -- -- -- -- --
|
||||
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
70: -- -- -- -- -- -- -- --
|
||||
~~~
|
||||
|
||||
Write your custom EDID data `edid.bin` to the HDMI firewall (replace BUS with corresponding bus number):
|
||||
|
||||
~~~
|
||||
for addr in `seq 0 255`; do echo $addr; sudo i2cset -y BUS 0x50 $addr 0x`xxd -p -l 1 -s $addr edid.bin`; done
|
||||
~~~
|
||||
|
||||
To verify the data has been written correctly, compare original data with the one on the EEPROM:
|
||||
|
||||
~~~
|
||||
# display original dumped data
|
||||
xxd -g 1 edid.bin
|
||||
# display data written on EEPROM
|
||||
sudo i2cdump -y BUS 0x50
|
||||
~~~
|
||||
|
||||
Once writing the EDID to the HDMI firewall memory succeeded:
|
||||
|
||||
- re-enable write protection by toggling the EDID switch to the BLOCK position
|
||||
- re-plug the HDMI firewall for the device to retrieve the newly written EDID
|
||||
|
||||
To read and play with EDID under Linux, you can use the tips provided for the previous [HDMI firewall v1](https://git.cuvoodoo.info/kingkevin/board/src/tag/hdmi_firewall_v1/README.md).
|
||||
|
181
Rakefile
181
Rakefile
@ -1,181 +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} 1> /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} 1> /dev/null"
|
||||
end
|
||||
|
||||
desc "archive gerbers"
|
||||
rule ".brd.zip" => ".versioned.lht" do |t|
|
||||
base = File.basename(t.source, ".versioned.lht")
|
||||
dir = "fabrication"
|
||||
sh "mkdir #{dir}" unless File.directory?(dir)
|
||||
sh "pcb-rnd -x cam gerber:JLC_PCB --outfile #{dir}/#{base}.brd #{t.source} 2> /dev/null"
|
||||
sh "zip --quiet #{t.name} #{dir}/*"
|
||||
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
Normal file
42
bom.ini
Normal 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
|
@ -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)
|
||||
}
|
||||
|
||||
element_line(x1*w + w/6, y*w + w/6, x1*w + w/6, (y+1)*w - w/6, |