-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathuvc-setup.sh
executable file
·289 lines (240 loc) · 6.68 KB
/
uvc-setup.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
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
#!/bin/sh
# SPDX-License-Identifier: MIT
#set -e
#set -x
OP=$1
PLAT=$2
CONFIGFS="/sys/kernel/config"
GADGET="$CONFIGFS/usb_gadget"
VID="0x1d6b"
PID="0x0104"
SERIAL="0123456789"
MANUF=$(hostname)
PRODUCT="pizero"
#echo "pizero USB Device UVC" > $GADGET_CONFIGFS_ROOT/strings/0x409/product
BOARD=$(strings /proc/device-tree/model)
case $BOARD in
*)
UDC=`ls /sys/class/udc` # will identify the 'first' UDC
UDC_ROLE=/dev/null # Not generic
;;
esac
echo "Detecting platform:"
echo " board : $BOARD"
echo " udc : $UDC"
create_eth() {
CONFIG=$1
FUNCTION=$2
echo " Creating ECM.0 (ethernet) gadget functionality : $FUNCTION"
cd $GADGET/pizero
mkdir -p functions/$FUNCTION
# first byte of address must be even
HOST="48:6f:73:74:50:43" # "HostPC"
SELF="42:61:64:55:53:42" # "BadUSB"
echo $HOST > functions/$FUNCTION/host_addr
echo $SELF > functions/$FUNCTION/dev_addr
ln -s functions/$FUNCTION configs/c.1
}
create_serial() {
CONFIG=$1
FUNCTION=$2
echo " Creating ACM (serial) gadget functionality : $FUNCTION"
cd $GADGET/pizero
mkdir -p functions/$FUNCTION
# first byte of address must be even
ln -s functions/$FUNCTION configs/c.1
}
create_frame() {
# Example usage:
# create_frame <function name> <width> <height> <format> <name>
FUNCTION=$1
WIDTH=$2
HEIGHT=$3
FORMAT=$4
NAME=$5
wdir=functions/$FUNCTION/streaming/$FORMAT/$NAME/${HEIGHT}p
mkdir -p $wdir
#temp new values
#WIDTH=640
#HEIGHT=360
echo $WIDTH > $wdir/wWidth
echo $HEIGHT > $wdir/wHeight
#echo $(( $WIDTH * $HEIGHT * 1 )) > $wdir/dwMaxVideoFrameBufferSize
# each frame is 100ns
echo 500000 > $wdir/dwDefaultFrameInterval
cat <<EOF > $wdir/dwFrameInterval
166666
200000
333333
500000
EOF
echo $(( $WIDTH * $HEIGHT * 80 )) > $wdir/dwMinBitRate
echo $(( $WIDTH * $HEIGHT * 160 )) > $wdir/dwMaxBitRate
}
create_uvc() {
# create_uvc <target config> <function name>
# create_uvc config/c.1 uvc.0
CONFIG=$1
FUNCTION=$2
echo " Creating UVC gadget functionality : $FUNCTION"
mkdir functions/$FUNCTION
#create_frame $FUNCTION 640 360 uncompressed u
#create_frame $FUNCTION 736 480 uncompressed u
case "$PLAT" in
test)
create_frame $FUNCTION 1920 1080 mjpeg m
;;
mjpeg)
create_frame $FUNCTION 1280 720 mjpeg m
;;
yuyv)
create_frame $FUNCTION 1280 720 uncompressed u
;;
all)
create_frame $FUNCTION 1280 720 uncompressed u
create_frame $FUNCTION 1280 720 mjpeg m
;;
*)
echo "unknown format, exiting"
exit 1
#create_frame $FUNCTION 1280 720 uncompressed u
#create_frame $FUNCTION 1280 720 mjpeg m
;;
esac
mkdir functions/$FUNCTION/streaming/header/h
cd functions/$FUNCTION/streaming/header/h
ln -s ../../uncompressed/u
ln -s ../../mjpeg/m
cd ../../class/fs
ln -s ../../header/h
cd ../../class/hs
ln -s ../../header/h
cd ../../../control
mkdir header/h
ln -s header/h class/fs
#ln -s header/h class/ss
cd ../../../
# Set the packet size: uvc gadget max size is 3k...
#echo 3072 > functions/$FUNCTION/streaming_maxpacket .. yeah but ain't working
echo 2048 > functions/$FUNCTION/streaming_maxpacket
# echo 1024 > functions/$FUNCTION/streaming_maxpacket .. only if you want slow fps
#echo 15 > functions/$FUNCTION/streaming_maxburst
echo 1 > functions/$FUNCTION/streaming_interval
ln -s functions/$FUNCTION configs/c.1
}
delete_uvc() {
# delete_uvc <target config> <function name>
# delete_uvc config/c.1 uvc.0
CONFIG=$1
FUNCTION=$2
echo " Deleting UVC gadget functionality : $FUNCTION"
#rm $CONFIG/$FUNCTION
rmdir functions/$FUNCTION
rm functions/$FUNCTION/control/class/*/h
rm functions/$FUNCTION/streaming/class/*/h
rm functions/$FUNCTION/streaming/header/h/m
rm functions/$FUNCTION/streaming/header/h/u
rmdir functions/$FUNCTION/streaming/uncompressed/u/*/
rmdir functions/$FUNCTION/streaming/uncompressed/u
rmdir functions/$FUNCTION/streaming/mjpeg/m/*/
rmdir functions/$FUNCTION/streaming/mjpeg/m
rmdir functions/$FUNCTION/streaming/header/h
rmdir functions/$FUNCTION/control/header/h
rmdir functions/$FUNCTION
rm $CONFIG/$FUNCTION
#rm configs/c.1/uvc.0
}
delete_ethernet(){
CONFIG=$1
FUNCTION=$2
echo "function/$FUNCTION"
rmdir functions/$FUNCTION
rm $CONFIG/$FUNCTION
}
case "$OP" in
start)
echo "Creating the USB gadget"
#echo "Loading composite module"
#modprobe libcomposite
echo "Creating gadget directory pizero"
mkdir -p $GADGET/pizero
cd $GADGET/pizero
if [ $? -ne 0 ]; then
echo "Error creating usb gadget in configfs"
exit 1;
else
echo "OK"
fi
echo "Setting Vendor and Product ID's"
echo $VID > idVendor
echo $PID > idProduct
echo 0x0100 > bcdDevice
echo 0x0200 > bcdUSB
echo 0xEF > bDeviceClass
echo 0x02 > bDeviceSubClass
echo 0x01 > bDeviceProtocol
echo 64 > bMaxPacketSize0
echo "OK"
echo "Setting English strings"
mkdir -p strings/0x409
echo $SERIAL > strings/0x409/serialnumber
echo $MANUF > strings/0x409/manufacturer
echo $PRODUCT > strings/0x409/product
echo "OK"
echo "Creating Config"
mkdir configs/c.1
echo 500 > configs/c.1/MaxPower
mkdir configs/c.1/strings/0x409
echo "Creating functions..."
create_uvc configs/c.1 uvc.0
create_eth configs/c.1 ecm.usb0
#create_serial configs/c.1 acm.usb0
echo "OK"
echo "Binding USB Device Controller"
udevadm settle -t 5 || :
sleep 2
echo $UDC > UDC
echo peripheral > $UDC_ROLE
cat $UDC_ROLE
echo "OK"
;;
stop)
echo "Stopping the USB gadget"
echo "Sorry this doesn't work well"
echo "Please reboot Pi to fully stop USB gadget"
set +e # Ignore all errors here on a best effort
cd $GADGET/pizero
if [ $? -ne 0 ]; then
echo "Error: no configfs gadget found"
exit 1;
fi
echo "Unbinding USB Device Controller"
grep $UDC UDC && echo "" > UDC
echo "OK"
#delete_uvc configs/c.1 uvc.0
#delete_ethernet configs/c.1 ecm.usb0
echo "Clearing English strings"
rmdir strings/0x409
echo "OK"
delete_uvc configs/c.1 uvc.0
delete_ethernet configs/c.1 ecm.usb0
echo "Cleaning up configuration"
rmdir configs/c.1/strings/0x409
#rm configs/c.1/uvc.0
rmdir configs/c.1
rmdir functions/uvc.0 #try to put this in delete_uvc
rmdir functions/ecm.usb0
#rm string/0x409
echo "OK"
echo "Removing gadget directory"
cd $GADGET
rmdir pizero
cd /
echo "OK"
#echo "Disable composite USB gadgets"
#modprobe -r libcomposite
#echo "OK"
;;
*)
echo "Usage : $0 {start mjpeg|start yuyv|stop}"
esac