-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathmanufacturing.sh
201 lines (180 loc) · 6.4 KB
/
manufacturing.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#!/bin/bash
# run this script from the `Marble` project directory:
# $ bash scripts/manufacturing.sh
#
# Versions tested on Debian Bullseye 2024-03-20:
# KiCad 6.0.11 (wish for more varied experience)
# KiBoM 1.8.0 (tested with commit ac29a12)
# kiauto 2.2.1 (tested natively, docker and chroot)
#
# Installation process for kiauto:
# sudo apt-get install xvfb xdotool python3-pip
# sudo apt-get install python3-xvfbwrapper python3-psutil
# (or let pip3 find xvfbwrapper and psutil)
# pip3 install kiauto==2.2.1
#
# No need to open the GUI! Everything can be done using this script,
# including generation of the BOM .xml and IPC-D-356 Netlist files.
#
# Make sure
# KiBoM is in $PYTHONPATH
# kiauto binaries are in $PATH
# Run this script using bash
#
set -e
export LC_COLLATE=C
umask 0022
A=Marble
# Make sure we're running under bash, so brace expansion and which works
if ! test "$(echo A{B,C})" = "AB AC"; then
echo "Error, not running under bash"
exit 1
fi
# KiBoM is cloned from
# https://github.com/SchrodingersGat/KiBoM
if ! python3 -m KiBOM_CLI --version; then
echo "KiBoM not found in \$PYTHONPATH"
exit 1
fi
# Check for kiauto (see installation instructions above)
if ! which eeschema_do pcbnew_do; then
echo "kiauto commands eeschema_do pcbnew_do not in \$PATH"
exit 1
fi
# kicad may or may not be in our $PATH
# kicad_exporter.py will fail quickly if pcbnew is not in its search path
if git diff | grep -q .; then
spec=xxxxxxxx
else
spec=$(git rev-parse --short=8 HEAD)
SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
# see https://reproducible-builds.org/docs/source-date-epoch/
fi
zipfile=marble-${spec}-fab.zip
echo "Final .zip file will be named $zipfile"
# Remove any stray stale files
rm -f marble*.dat ./*.pdf ./*.erc ./*.drc ./*.xml
echo "Generating PDF schematics"
# Export schematics to PDF, saving it as Marble.pdf
eeschema_do export -a $A.kicad_sch .
# Run ERC, saves a report Marble.erc
echo "Running ERC (schematic)"
if eeschema_do run_erc $A.kicad_sch . 2> $A.erc.log; then
echo "Passed ERC. Woo-hoo!"
else
echo "ERC errors found. Exiting."
echo "See $A.erc and $(wc -l $A.erc.log)"
exit 1
fi
echo "See $A.erc and $(wc -l $A.erc.log)"
# Run DRC, which saves a report file called Marble.drc
echo "Running DRC (layout)"
# -s or not?
if pcbnew_do run_drc -f drc_exclusion $A.kicad_pcb --ignore_unconnected -o $A.drc . 2> $A.drc.log; then
echo "Passed DRC. Woo-hoo!"
else
echo "DRC errors found, but not exiting. :-("
# exit 1
fi
echo "See $A.drc and $(wc -l $A.drc.log)"
# Generate the IPC-D-356 netlist file
echo "Generating IPC-D-356 netlist file"
pcbnew_do ipc_netlist $A.kicad_pcb -o $A.d356 .
# Generate the BOM .xml file
echo "Generating BOM .xml file"
eeschema_do bom_xml $A.kicad_sch .
# generate all the .drl, .pos and gerbers after DRC check
echo "Running kicad_exporter.py to generate .drl, .pos, and .gbr files"
python3 scripts/kicad_exporter.py --layers 10 $A.kicad_pcb PCB_layers --keep-thru
# Check that all the script-generated files are made
die=0
for f in PCB_layers/$A-all.pos PCB_layers/$A-{B_Cu,B_Mask,B_Paste,B_SilkS,Edge_Cuts,F_Cu,F_Mask,F_Paste,F_SilkS,In{1,2,3,4,5,6,7,8,9,10}_Cu}.gbr PCB_layers/$A-{,N}PTH.drl $A.{xml,d356}; do
if ! test -r "$f"; then echo "missing: $f"; die=1;
elif ! test "$f" = "$(find $f -newer $A.kicad_pcb)"; then echo "stale: $f"; die=1; else
echo "OK: $f"; fi
done
if test $die = 1; then echo Aborting; exit 1; fi
echo OK
# XXX shouldn't $A.xml stale-ness be tested against .kicad_sch files?
# Run KiBoM from the command line
echo running KiBoM
python3 -m KiBOM_CLI --cfg scripts/bom.ini $A.xml $A
echo KiBoM complete
# One more cross-check
bomfile=${A}_BOM.csv
bomfile2=${A}_BOMa.csv
echo "$bomfile"
test -r "$bomfile"
test "$bomfile" = "$(find "$bomfile" -newer $A.xml)"
echo generated files are OK
echo starting post-processing
# Map generics to orderables
# Implied dependence on file generic_subst
test -r scripts/generic_subst
python3 scripts/non_generic.py "$bomfile" "$bomfile2"
# Additional postprocessing
# input ${A}_BOM.csv $A-all.pos
# output marble-xy.pos
python3 scripts/xy_post.py ${A} marble v > marble-stuff.log
python3 scripts/xy_post.py ${A} marble
python3 scripts/find_tp.py ${A}.kicad_pcb > testpoint_map.gbr
# Assemble files into fab directory
# Includes stripping out date and revision info from KiCad exports,
# so we have a good chance of making reproducible output.
rm -rf fab
mkdir fab
cd PCB_layers
for f in *.gbr; do
sed \
-e '/TF.CreationDate/d' \
-e '/GenerationSoftware/s/Pcbnew,(\?6\.0\..*)\?\*/Pcbnew,(6.0.x)\*/' \
-e '/Created by KiCad/s/(PCBNEW (\?6\.0\..*\*/(PCBNEW (6.0.x))\*/' \
< "$f" > "../fab/marble${f#$A}"
done
for f in *.drl; do
sed \
-e '/TF.CreationDate/d' \
-e '/ DRILL file /s/ date .*//' \
-e '/GenerationSoftware/s/Pcbnew,(\?6\.0\..*)\?/Pcbnew,(6.0.x)/' \
-e '/DRILL file/s/{KiCad (\?6\.0\..*}/{KiCad (6.0.x)}/' \
< "$f" > "../fab/marble${f#$A}"
done
cd ..
sed \
-e '/Module positions/s/ - created on .*/ ###/' \
-e '/Module positions/s/ for .*/ ###/' \
< marble-xy.pos > fab/marble-xy.pos
sed \
-e '/^BoM Date:/d' \
-e '/Component Groups:/d' \
-e '/KiCad Version/s/Eeschema (\?6\.0\..*/Eeschema (6.0.x)/' \
< "$bomfile2" > fab/marble-bom.csv
mv marble-stuff.log fab/
cp $A.d356 fab/marble-ipc-d-356.txt
cp marble-stack.txt fab/marble-stack.txt
cp scripts/testpoint_map.gvp fab/testpoint_map.gvp
mv testpoint_map.gbr fab/testpoint_map.gbr
# Fancy file integrity feature. Presumably nobody besides Larry will ever care.
(cd fab && sha256sum -- * > marble-sha256.txt)
(cat ../docs/README_fab.txt; cd fab; sha256sum marble-sha256.txt) > fab/README_fab.txt
# Create the final zip file
rm -f "$zipfile"
if test -n "$SOURCE_DATE_EPOCH"; then
echo "Forcing timestamp $SOURCE_DATE_EPOCH"
touch --date="@$SOURCE_DATE_EPOCH" fab/*
TZ=UTC zip -X --latest-time "$zipfile" fab/*
# Note the -X flag, that keeps potentially bogus atime info out of the zipfile. See
# https://lists.reproducible-builds.org/pipermail/rb-general/2023-April/002927.html
# The TZ setup means that for full pedantic accuracy, you should unpack with
# TZ=UTC unzip "$zipfile".
else
zip "$zipfile" fab/*
fi
if [ "$1" != "debug" ]; then # clean-up step, can skip when debugging
rm -f marble*.dat marble-xy.pos $A.d356 $A.xml "$bomfile" "${bomfile}.tmp" "$bomfile2"
rm -rf PCB_layers fab
fi
# marble-${spec}-fab.zip is the only generated file that should remain
ls -l "$zipfile"
sha256sum "$zipfile"
echo DONE