aboutsummaryrefslogtreecommitdiff
path: root/lib/vusb
diff options
context:
space:
mode:
authorAkshay <[email protected]>2022-04-10 12:13:40 +0100
committerAkshay <[email protected]>2022-04-10 12:13:40 +0100
commitdc90387ce7d8ba7b607d9c48540bf6d8b560f14d (patch)
tree4ccb8fa5886b66fa9d480edef74236c27f035e16 /lib/vusb
Diffstat (limited to 'lib/vusb')
-rw-r--r--lib/vusb/.gitignore22
-rw-r--r--lib/vusb/Makefile60
-rw-r--r--lib/vusb/README.md33
-rw-r--r--lib/vusb/Readme.txt83
-rw-r--r--lib/vusb/circuits/Readme.txt79
-rw-r--r--lib/vusb/circuits/tiny45-rc.schbin0 -> 193502 bytes
-rw-r--r--lib/vusb/circuits/with-series-diodes.schbin0 -> 213956 bytes
-rw-r--r--lib/vusb/circuits/with-vreg.schbin0 -> 215922 bytes
-rw-r--r--lib/vusb/circuits/with-zener.schbin0 -> 225497 bytes
-rw-r--r--lib/vusb/examples/Readme.txt102
-rw-r--r--lib/vusb/examples/custom-class/Readme.txt64
-rw-r--r--lib/vusb/examples/custom-class/commandline/set-led.c134
-rw-r--r--lib/vusb/examples/custom-class/firmware/main.c97
-rw-r--r--lib/vusb/examples/custom-class/firmware/requests.h35
-rwxr-xr-xlib/vusb/examples/custom-class/make-files.sh43
-rw-r--r--lib/vusb/examples/drivertest/commandline/runtest.c151
-rw-r--r--lib/vusb/examples/drivertest/firmware/main.c128
-rw-r--r--lib/vusb/examples/drivertest/firmware/requests.h28
-rwxr-xr-xlib/vusb/examples/drivertest/make-files.sh33
-rw-r--r--lib/vusb/examples/hid-custom-rq/Readme.txt28
-rw-r--r--lib/vusb/examples/hid-custom-rq/firmware/main.c120
-rw-r--r--lib/vusb/examples/hid-custom-rq/firmware/requests.h31
-rwxr-xr-xlib/vusb/examples/hid-custom-rq/make-files.sh61
-rw-r--r--lib/vusb/examples/hid-data/Readme.txt75
-rw-r--r--lib/vusb/examples/hid-data/commandline/hidtool.c126
-rw-r--r--lib/vusb/examples/hid-data/firmware/main.c141
-rwxr-xr-xlib/vusb/examples/hid-data/make-files.sh44
-rw-r--r--lib/vusb/examples/hid-mouse/Readme.txt48
-rw-r--r--lib/vusb/examples/hid-mouse/firmware/main.c164
-rwxr-xr-xlib/vusb/examples/hid-mouse/make-files.sh38
-rw-r--r--lib/vusb/examples/usbtool/Makefile47
-rw-r--r--lib/vusb/examples/usbtool/Makefile.windows17
-rw-r--r--lib/vusb/examples/usbtool/Readme.txt209
-rwxr-xr-xlib/vusb/examples/usbtool/make-files.sh15
-rw-r--r--lib/vusb/examples/usbtool/usbtool.c355
-rw-r--r--lib/vusb/libs-device/Readme.txt22
-rw-r--r--lib/vusb/libs-device/osccal.c68
-rw-r--r--lib/vusb/libs-device/osccal.h62
-rw-r--r--lib/vusb/libs-device/osctune.h87
-rw-r--r--lib/vusb/libs-host/Readme.txt26
-rw-r--r--lib/vusb/libs-host/hiddata.c323
-rw-r--r--lib/vusb/libs-host/hiddata.h70
-rw-r--r--lib/vusb/libs-host/hidsdi.h48
-rw-r--r--lib/vusb/libs-host/opendevice.c202
-rw-r--r--lib/vusb/libs-host/opendevice.h76
-rwxr-xr-xlib/vusb/mkdist.sh149
-rw-r--r--lib/vusb/tests/Makefile128
-rw-r--r--lib/vusb/tests/Readme.txt13
-rwxr-xr-xlib/vusb/tests/compare-sizes.awk44
-rw-r--r--lib/vusb/tests/main.c158
-rw-r--r--lib/vusb/tests/null.c25
-rw-r--r--lib/vusb/tests/sizes-reference/sizes-20080418-gcc3.4.6.txt13
-rw-r--r--lib/vusb/tests/sizes-reference/sizes-20080418-gcc4.2.2.txt13
-rw-r--r--lib/vusb/tests/sizes-reference/sizes-20080513-gcc3.4.6.txt15
-rw-r--r--lib/vusb/tests/sizes-reference/sizes-20080513-gcc4.3.0.txt15
-rw-r--r--lib/vusb/tests/sizes-reference/sizes-20081022-gcc3.4.6.txt16
-rw-r--r--lib/vusb/tests/sizes-reference/sizes-20081022-gcc4.3.0.txt16
-rw-r--r--lib/vusb/tests/sizes-reference/sizes-20081126-gcc3.4.6.txt16
-rw-r--r--lib/vusb/tests/sizes-reference/sizes-20081126-gcc4.3.0.txt16
-rw-r--r--lib/vusb/tests/sizes-reference/sizes-20090323-gcc3.4.6.txt17
-rw-r--r--lib/vusb/tests/sizes-reference/sizes-20090323-gcc4.3.2.txt17
-rw-r--r--lib/vusb/tests/sizes-reference/sizes-20090415-gcc3.4.6.txt17
-rw-r--r--lib/vusb/tests/sizes-reference/sizes-20090415-gcc4.3.2.txt17
-rw-r--r--lib/vusb/tests/sizes-reference/sizes-20100715-gcc3.4.6.txt17
-rw-r--r--lib/vusb/tests/sizes-reference/sizes-20100715-gcc4.3.3.txt17
-rw-r--r--lib/vusb/tests/sizes-reference/sizes-20120109-gcc3.4.6.txt17
-rw-r--r--lib/vusb/tests/sizes-reference/sizes-20120109-gcc4.3.3.txt17
-rw-r--r--lib/vusb/tests/sizes-reference/sizes-20121206-gcc4.6.2.txt17
-rw-r--r--lib/vusb/tests/usbconfig.h299
-rw-r--r--lib/vusb/usbdrv/Changelog.txt329
-rw-r--r--lib/vusb/usbdrv/CommercialLicense.txt166
-rw-r--r--lib/vusb/usbdrv/License.txt361
-rw-r--r--lib/vusb/usbdrv/Readme.txt172
-rw-r--r--lib/vusb/usbdrv/USB-ID-FAQ.txt149
-rw-r--r--lib/vusb/usbdrv/USB-IDs-for-free.txt168
-rw-r--r--lib/vusb/usbdrv/asmcommon.inc209
-rw-r--r--lib/vusb/usbdrv/oddebug.c49
-rw-r--r--lib/vusb/usbdrv/oddebug.h122
-rw-r--r--lib/vusb/usbdrv/usbconfig-prototype.h394
-rw-r--r--lib/vusb/usbdrv/usbdrv.c661
-rw-r--r--lib/vusb/usbdrv/usbdrv.h786
-rw-r--r--lib/vusb/usbdrv/usbdrvasm.S391
-rw-r--r--lib/vusb/usbdrv/usbdrvasm.asm20
-rw-r--r--lib/vusb/usbdrv/usbdrvasm12.inc392
-rw-r--r--lib/vusb/usbdrv/usbdrvasm128.inc749
-rw-r--r--lib/vusb/usbdrv/usbdrvasm15.inc422
-rw-r--r--lib/vusb/usbdrv/usbdrvasm16.inc345
-rw-r--r--lib/vusb/usbdrv/usbdrvasm165.inc452
-rw-r--r--lib/vusb/usbdrv/usbdrvasm18-crc.inc706
-rw-r--r--lib/vusb/usbdrv/usbdrvasm18.inc557
-rw-r--r--lib/vusb/usbdrv/usbdrvasm20.inc359
-rw-r--r--lib/vusb/usbdrv/usbportability.h143
-rw-r--r--lib/vusb/v-usb.xcodeproj/project.pbxproj381
-rw-r--r--lib/vusb/v-usb.xcodeproj/project.xcworkspace/contents.xcworkspacedata7
94 files changed, 13174 insertions, 0 deletions
diff --git a/lib/vusb/.gitignore b/lib/vusb/.gitignore
new file mode 100644
index 000000000..20c204a9e
--- /dev/null
+++ b/lib/vusb/.gitignore
@@ -0,0 +1,22 @@
1.DS_Store
2._*
3*.o
4*.elf
5*.hex
6*.exe
7/*.xcodeproj/project.xcworkspace/xcuserdata
8examples/*/*/Makefile*
9examples/*/*/opendevice.*
10examples/*/opendevice.*
11examples/*/firmware/usbdrv
12examples/*/firmware/usbconfig.h
13examples/*/firmware/osccal.*
14examples/*/commandline/hiddata.*
15examples/*/commandline/hidsdi.h
16examples/hid-custom-rq/commandline
17examples/custom-class/commandline/set-led
18examples/drivertest/commandline/runtest
19examples/hid-data/commandline/hidtool
20examples/usbtool/usbtool
21tests/sizes.txt
22tests/usbdrv
diff --git a/lib/vusb/Makefile b/lib/vusb/Makefile
new file mode 100644
index 000000000..a6eb8a54b
--- /dev/null
+++ b/lib/vusb/Makefile
@@ -0,0 +1,60 @@
1# Name: Makefile
2# Project: v-usb
3# Author: Christian Starkjohann
4# Creation Date: 2012-12-05
5# Tabsize: 4
6# Copyright: (c) 2012 by OBJECTIVE DEVELOPMENT Software GmbH
7# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8
9# This is the main Makefile. The two primary targets are "all", to build
10# everything which can be built (except tests), and "clean" to remove all
11# dependent files. In a repository clone, derived source files are generated
12# and deleted as well.
13#
14# We distinguish between repository clones and source packages by the existence
15# of make-files.sh scripts in various subdirectories.
16
17
18all:
19 if [ ! -f examples/hid-mouse/firmware/Makefile ]; then \
20 $(MAKE) files; \
21 fi
22 if [ -n "$(uname -s | grep -i mingw)" ]; then \
23 $(MAKE) windows; \
24 else \
25 $(MAKE) unix; \
26 fi
27
28clean:
29 $(MAKE) unixclean
30 if cross-make.sh --help >/dev/null 2>&1; then \
31 $(MAKE) windowsclean; \
32 fi
33 $(MAKE) filesremove
34
35
36unix unixclean:
37 target=$$(echo $@ | sed -e 's/unix//g'); \
38 find . -mindepth 3 -name Makefile -print | while read i; do \
39 dir=$$(dirname $$i); \
40 dirname=$$(basename $$dir); \
41 pushd $$dir >/dev/null; \
42 if [ "$$dirname" = firmware -a -z "$$target" ]; then \
43 if ! $(MAKE) hex; then break; fi; \
44 else \
45 if ! $(MAKE) $$target; then break; fi;\
46 fi; \
47 popd >/dev/null; \
48 done
49
50
51windows windowsclean:
52 target=$$(echo $@ | sed -e 's/windows//g'); \
53 find . -mindepth 3 -name Makefile.windows -execdir cross-make.sh $$target \; ; \
54 if [ -z "$$target" ]; then target=hex; fi; \
55 find . -mindepth 2 -name firmware -exec sh -c "cd '{}'; $(MAKE) $$target" \;
56
57files filesremove:
58 target=$$(echo $@ | sed -e 's/files//g'); \
59 find . -mindepth 2 -name make-files.sh -execdir ./make-files.sh $$target \;
60
diff --git a/lib/vusb/README.md b/lib/vusb/README.md
new file mode 100644
index 000000000..88b29da28
--- /dev/null
+++ b/lib/vusb/README.md
@@ -0,0 +1,33 @@
1What is V-USB?
2==============
3V-USB is a firmware-only USB driver for Atmel's AVR microcontrollers.
4For more information please visit <http://www.obdev.at/vusb/>.
5
6What is in this Repository?
7===========================
8This repository contains the source code of the driver (in the usbdrv
9subdirectory), examples (in the examples) subdirectory and other things
10you might need when you design a device using V-USB.
11
12When you check out this repository, the resulting directory is *not* equivalent
13to the source code package which can be downloaded at
14<http://www.obdev.at/vusb/>. Some files in the source code package are generated
15by scripts when the package is created. On the other hand, the scripts which
16generate source files and the package are not contained in the package itself.
17
18If you want to know more about the files and directories, see the file
19Readme.txt in the top level directory.
20
21How do I Add the Driver to My Project?
22======================================
23Simply copy the entire usbdrv subdirectory into your project's firmware
24source code directory. Then edit the firmware's Makefile and add the following
25object files to your binary:
26
27 usbdrv/usbdrv.o
28 usbdrv/usbdrvasm.o
29 usbdrv/oddebug.o
30
31Then make sure that your Makefile contains rules to convert *.S and *.c to
32object files. See the Makefiles in the examples subdirectory for an
33inspiration.
diff --git a/lib/vusb/Readme.txt b/lib/vusb/Readme.txt
new file mode 100644
index 000000000..84d27f997
--- /dev/null
+++ b/lib/vusb/Readme.txt
@@ -0,0 +1,83 @@
1This is the Readme file for V-USB and related code. V-USB is Objective
2Development's firmware-only USB driver for Atmel's(r) AVR(r) microcontrollers.
3For more information please visit http://www.obdev.at/vusb/.
4
5To avoid name confusion: This project was formerly known as AVR-USB. Due to
6a trademark issue, it was renamed to V-USB in April 2009.
7
8
9WHAT IS INCLUDED IN THIS PACKAGE?
10=================================
11This package consists of the device side USB driver firmware, library code
12for device and host and fully working examples for device and host:
13
14 Readme.txt .............. The file you are currently reading.
15 usbdrv .................. V-USB firmware, to be included in your project.
16 examples ................ Example code for device and host side.
17 libs-device ............. Useful code snippets for the device firmware.
18 libs-host ............... Useful code snippets for host-side drivers.
19 circuits ................ Example circuits using this driver.
20 Changelog.txt ........... Documentation of changes between versions.
21 License.txt ............. Free Open Source license for this package (GPL).
22 CommercialLicense.txt ... Alternative commercial license for this package.
23 USB-ID-FAQ.txt .......... General infos about USB Product- and Vendor-IDs.
24 USB-IDs-for-free.txt .... List and terms of use for free shared PIDs.
25
26Each subdirectory contains a separate Readme file which explains its
27contents. We recommend that you also read the Readme.txt file in the
28usbdrv subdirectory.
29
30
31PREREQUISITES
32=============
33The AVR code of V-USB is written in C and assembler. You need either
34avr-gcc or IAR CC to compile the project. We recommend avr-gcc because it
35is free and easily available. Gcc version 3 generates slightly more
36efficient code than version 4 for V-USB. Not every release is tested with
37the IAR compiler. Previous versions have been tested with IAR 4.10B/W32 and
384.12A/W32 on an ATmega8 with the "small" and "tiny" memory model.
39
40Ready made avr-gcc tool chains are available for most operating systems:
41 * Windows: WinAVR http://winavr.sourceforge.net/
42 * Mac: CrossPack for AVR Development http://www.obdev.at/crosspack/
43 * Linux and other Unixes: Most free Unixes have optional packages for AVR
44 development. If not, follow the instructions at
45 http://www.nongnu.org/avr-libc/user-manual/install_tools.html
46
47Our host side examples are compiled with gcc on all platforms. Gcc is the
48default C compiler on Mac, Linux and many other Unixes. On windows, we
49recommend MinGW (http://www.mingw.org/). Use the automated MinGW installer
50for least troubles. You also need MSYS from the same site to work with
51standard Makefiles.
52
53Most examples also depend on libusb. Libusb is available from
54http://libusb.sourceforge.net/ for Unix and
55http://libusb-win32.sourceforge.net/ for Windows.
56
57
58TECHNICAL DOCUMENTATION
59=======================
60The API reference of the driver firmware can be found in usbdrv/usbdrv.h.
61Documentation for host and device library files are in the respective header
62files. For more information, see our documentation wiki at
63http://www.obdev.at/goto.php?t=vusb-wiki.
64
65See the file usbdrv/Readme.txt for more info about the driver itself.
66
67
68LICENSE
69=======
70V-USB and related code is distributed under the terms of the GNU General
71Public License (GPL) version 2 (see License.txt for details) and the GNU
72General Public License (GPL) version 3. It is your choice whether you apply
73the terms of version 2 or version 3. In addition to the terms of the GPL, we
74strongly encourage you to publish your entire project and mail OBJECTIVE
75DEVELOPMENT a link to your publication.
76
77Alternatively, we offer a commercial license without the restrictions of the
78GPL. See CommercialLicense.txt for details.
79
80
81----------------------------------------------------------------------------
82(c) 2010 by OBJECTIVE DEVELOPMENT Software GmbH.
83http://www.obdev.at/
diff --git a/lib/vusb/circuits/Readme.txt b/lib/vusb/circuits/Readme.txt
new file mode 100644
index 000000000..1aa52182e
--- /dev/null
+++ b/lib/vusb/circuits/Readme.txt
@@ -0,0 +1,79 @@
1This is the Readme file for the V-USB example circuits directory.
2
3
4CIRCUITS IN THIS DIRECTORY
5==========================
6Since USB requires 3.3 V levels on D+ and D- but delivers a power supply of
7ca. 5 V, some kind of level conversion must be performed. There are several
8ways to implement this level conversion, see the example circuits below.
9
10with-vreg.png and with-vreg.sch (EAGLE schematics):
11 This circuit uses a low drop voltage regulator to reduce the USB supply to
12 3.3 V. You MUST use a low drop regulator because standard regulators such
13 as the LM317 require at least ca. 2 V drop. The advantage of this approach
14 is that it comes closest to the voltage levels required by the USB
15 specification and that the circuit is powered from a regulated supply. If
16 no USB cable is used (connector directly soldered on PCB), you can even
17 omit the 68 Ohm series resistors. The disadvantage is that you may want to
18 use other chips in your design which require 5 V. Please check that the AVR
19 used in your design allows the chosen clock rate at 3.3 V.
20
21with-zener.png and with-zener.sch (EAGLE schematics):
22 This circuit enforces lower voltage levels on D+ and D- with zener diodes.
23 The zener diodes MUST be low power / low current types to ensure that the
24 1k5 pull-up resistor on D- generates a voltage of well above 2.5 V (but
25 below 3.6 V). The advantage of this circuit is its simplicity and that the
26 circuit can be powered at 5 V (usually precise enough if the cable drop is
27 neglected). The disadvantage is that some zener diodes have a lower voltage
28 than 3 V when powered through 1k5 and the choice of components becomes
29 relevant. In addition to that, the power consumption during USB data
30 transfer is increased because the current is only limited by the 68 Ohm
31 series resistor. The zeners may even distort the signal waveforms due to
32 their capacity.
33
34with-series-diodes.png and with-series-diodes.sch (EAGLE schematics):
35 This is a simplified low-cost version of the voltage regulator approach.
36 Instead of using a voltage regulator, we reduce the voltage by the forward
37 voltage of two silicon diodes (roughly 1.4 V). This gives ca. 3.6 V which
38 is practically inside the allowed range. The big disadvantage is that the
39 supply is not regulated -- it even depends strongly on the power
40 consumption. This cannot be tolerated for analog circuits.
41
42tiny45-rc.png and tiny45-rc.sch (EAGLE schematics):
43 This is mostly an example for connecting an 8 pin device using the internal
44 RC oscillator for system clock. This example uses series diodes to limit
45 the supply, but you may choose any other method. Please note that you must
46 choose a clock rate of 12.8 or 16.5 MHz because only the receiver modules
47 for these frequencies have a PLL to allow higher clock rate tolerances.
48
49
50GENERAL DESIGN NOTES
51====================
52All examples have D+ on hardware interrupt INT0 because this is the highest
53priority interrupt on AVRs. You may use other hardware interrupts (and
54configure the options at the end of usbconfig.h accordingly) if you make sure
55that no higher priority interrupt is used.
56
57If you use USB_SOF_HOOK or USB_COUNT_SOF in usbconfig.h, you must wire D- to
58the interrupt instead. This way the interrupt is triggered on USB Start Of
59Frame pulses as well.
60
61Most examples have a 1M pull-down resistor at D+. This pull-up ensures that
62in self-powered designs no interrupts occur while USB is not connected. You
63may omit this resistor in bus-powered designs. Older examples had a pull-up
64resistor instead. This is not compatible with the zener diode approach to
65level conversion: 1M pull-up in conjunction with a 3.6 V zener diode give an
66invalid logic level.
67
68All examples with ATMega8/88/168 have D+ at port D bit 2 (because this is
69hardware interrupt 0) and D- on port D bit 4 because it is also a clock input
70for timer/counter 0. This way the firmware can easily check for activity on
71D- (USB frame pulses) by checking the counter value in regular intervals. If
72no activity is found, the firmware should (according to the USB
73specification) put the system into a low power suspend mode.
74
75
76
77----------------------------------------------------------------------------
78(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH.
79http://www.obdev.at/
diff --git a/lib/vusb/circuits/tiny45-rc.sch b/lib/vusb/circuits/tiny45-rc.sch
new file mode 100644
index 000000000..349f1ad60
--- /dev/null
+++ b/lib/vusb/circuits/tiny45-rc.sch
Binary files differ
diff --git a/lib/vusb/circuits/with-series-diodes.sch b/lib/vusb/circuits/with-series-diodes.sch
new file mode 100644
index 000000000..d84d99e56
--- /dev/null
+++ b/lib/vusb/circuits/with-series-diodes.sch
Binary files differ
diff --git a/lib/vusb/circuits/with-vreg.sch b/lib/vusb/circuits/with-vreg.sch
new file mode 100644
index 000000000..1f1797bdd
--- /dev/null
+++ b/lib/vusb/circuits/with-vreg.sch
Binary files differ
diff --git a/lib/vusb/circuits/with-zener.sch b/lib/vusb/circuits/with-zener.sch
new file mode 100644
index 000000000..624177a7d
--- /dev/null
+++ b/lib/vusb/circuits/with-zener.sch
Binary files differ
diff --git a/lib/vusb/examples/Readme.txt b/lib/vusb/examples/Readme.txt
new file mode 100644
index 000000000..82b10fe3d
--- /dev/null
+++ b/lib/vusb/examples/Readme.txt
@@ -0,0 +1,102 @@
1This is the Readme file for the directory "examples" of V-USB, a firmware-
2only USB driver for AVR microcontrollers.
3
4WHAT IS IN THIS DIRECTORY?
5==========================
6This directory contains examples which are mostly for educational purposes.
7Examples can be device firmware only, host software only or both. Here is
8a summary:
9
10custom-class
11 A custom class device with host software based on libusb. It demonstrates
12 the straight forward way of sending small amounts of data to a device and
13 receiving data from the device. It does NOT demonstrate how to send large
14 amounts of data to the device or how to receive data generated on the fly
15 by the device (how to use usbFunctionWrite() and usbFunctionRead()). See
16 the hid-data example for how usbFunctionWrite() and usbFunctionRead() are
17 used.
18
19hid-custom-rq
20 This example implements the same functionality as the custom-class example
21 above, but declares the device as HID. This prevents the "give me a driver
22 CD" dialog on Windows. The device can still be controlled with libusb as in
23 the previous example (on Windows, the filter version of libusb-win32 must
24 be installed). In addition to the features presented in custom-class, this
25 example demonstrates how a HID class device is defined.
26
27hid-mouse
28 This example implements a mouse device. No host driver is required since
29 today's operating systems have drivers for USB mice built-in. It
30 demonstrates how a real-world HID class device is implemented and how
31 interrupt-in endpoints are used.
32
33hid-data
34 This example demonstrates how the HID class can be misused to transfer
35 arbitrary data over HID feature reports. This technique is of great value
36 on Windows because no driver DLLs are needed (the hid-custom-rq example
37 still requires the libusb-win32 DLL, although it may be in the program's
38 directory). The host side application requires no installation, it can
39 even be started directly from a CD. This example also demonstrates how
40 to transfer data using usbFunctionWrite() and usbFunctionRead().
41
42usbtool
43 This is a general purpose development and debugging tool for USB devices.
44 You can use it during development of your device to test various requests
45 without special test programs. But it is also an example how all the
46 libusb API functions are used.
47
48More information about each example can be found in the Readme file in the
49respective directory.
50
51Hardware dependencies of AVR code has been kept at a minimum. All examples
52should work on any AVR chip which has enough resources to run the driver.
53Makefile and usbconfig.h have been configured for the metaboard hardware (see
54http://www.obdev.at/goto.php?t=metaboard for details). Edit the target
55device, fuse values, clock rate and programmer in Makefile and the I/O pins
56dedicated to USB in usbconfig.h.
57
58
59WHAT IS NOT DEMONSTRATED IN THESE EXAMPLES?
60===========================================
61These examples show only the most basic functionality. More elaborate
62examples and real world applications showing more features of the driver are
63available at http://www.obdev.at/vusb/projects.html. Most of these
64features are described in our documentation wiki at
65http://www.obdev.at/goto.php?t=vusb-wiki.
66
67To mention just a few:
68
69Using RC oscillator for system clock
70 The 12.8 MHz and 16.5 MHz modules of V-USB have been designed to cope
71 with clock rate deviations up to 1%. This allows an RC oscillator to be
72 used. Since the AVR's RC oscillator has a factory precision of only 10%,
73 it must be calibrated to an external reference. The EasyLogger example
74 shows how this can be done.
75
76Dynamically generated descriptors
77 Sometimes you want to implement different typtes of USB device depending
78 on a jumper or other condition. V-USB has a very flexible interface for
79 providing USB descriptors. See AVR-Doper for how to provide descriptors
80 at runtime.
81
82Virtual COM port
83 Some people prefer a virtual serial interface to communicate with their
84 device. We strongly discourage this method because it does things
85 forbidden by the USB specification. If you still want to go this route,
86 see AVR-CDC.
87
88Implementing suspend mode
89 V-USB does not implement suspend mode. This means that the device does
90 not reduce power consumption when the host goes into sleep mode. Device
91 firmware is free to implement suspend mode, though. See USB2LPT for an
92 example.
93
94The projects mentioned above can best be found on
95
96 http://www.obdev.at/vusb/prjall.html
97
98where all projects are listed.
99
100----------------------------------------------------------------------------
101(c) 2009 by OBJECTIVE DEVELOPMENT Software GmbH.
102http://www.obdev.at/
diff --git a/lib/vusb/examples/custom-class/Readme.txt b/lib/vusb/examples/custom-class/Readme.txt
new file mode 100644
index 000000000..815518ea1
--- /dev/null
+++ b/lib/vusb/examples/custom-class/Readme.txt
@@ -0,0 +1,64 @@
1This is the Readme file for the custom-class example. In this example, we
2show how an LED can be controlled via USB.
3
4
5WHAT IS DEMONSTRATED?
6=====================
7This example shows how small amounts of data (several bytes) can be
8transferred between the device and the host. In addition to a very basic
9USB device, it demonstrates how to build a host side driver application
10using libusb or libusb-win32. It does NOT show how usbFunctionWrite() and
11usbFunctionRead() are used. See the hid-data example if you want to learn
12about these functions.
13
14
15PREREQUISITES
16=============
17Target hardware: You need an AVR based circuit based on one of the examples
18(see the "circuits" directory at the top level of this package), e.g. the
19metaboard (http://www.obdev.at/goto.php?t=metaboard).
20
21AVR development environment: You need the gcc tool chain for the AVR, see
22the Prerequisites section in the top level Readme file for how to obtain it.
23
24Host development environment: A C compiler and libusb. See the top level
25Readme file, section Prerequisites for more information.
26
27
28BUILDING THE FIRMWARE
29=====================
30Change to the "firmware" directory and modify Makefile according to your
31architecture (CPU clock, target device, fuse values) and ISP programmer. Then
32edit usbconfig.h according to your pin assignments for D+ and D-. The default
33settings are for the metaboard hardware. You should have wired an LED with a
34current limiting resistor of ca. 270 Ohm to a free I/O pin. Change the
35defines in main.c to match the port and bit number.
36
37Type "make hex" to build main.hex, then "make flash" to upload the firmware
38to the device. Don't forget to run "make fuse" once to program the fuses. If
39you use a prototyping board with boot loader, follow the instructions of the
40boot loader instead.
41
42Please note that the first "make hex" copies the driver from the top level
43into the firmware directory. If you use a different build system than our
44Makefile, you must copy the driver by hand.
45
46
47BUILDING THE HOST SOFTWARE
48==========================
49Since the host software is based on libusb or libusb-win32, make sure that
50this library is installed. On Unix, ensure that libusb-config is in your
51search PATH. On Windows, edit Makefile.windows and set the library path
52appropriately. Then type "make" on Unix or "make -f Makefile.windows" on
53Windows to build the command line tool.
54
55
56USING THE COMMAND LINE TOOL
57===========================
58The command line tool has three valid arguments: "status" to query the
59current LED status, "on" to turn on the LED and "off" to turn it off.
60
61
62----------------------------------------------------------------------------
63(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH.
64http://www.obdev.at/
diff --git a/lib/vusb/examples/custom-class/commandline/set-led.c b/lib/vusb/examples/custom-class/commandline/set-led.c
new file mode 100644
index 000000000..fe0d75d71
--- /dev/null
+++ b/lib/vusb/examples/custom-class/commandline/set-led.c
@@ -0,0 +1,134 @@
1/* Name: set-led.c
2 * Project: custom-class, a basic USB example
3 * Author: Christian Starkjohann
4 * Creation Date: 2008-04-10
5 * Tabsize: 4
6 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
7 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8 */
9
10/*
11General Description:
12This is the host-side driver for the custom-class example device. It searches
13the USB for the LEDControl device and sends the requests understood by this
14device.
15This program must be linked with libusb on Unix and libusb-win32 on Windows.
16See http://libusb.sourceforge.net/ or http://libusb-win32.sourceforge.net/
17respectively.
18*/
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <usb.h> /* this is libusb */
24#include "opendevice.h" /* common code moved to separate module */
25
26#include "../firmware/requests.h" /* custom request numbers */
27#include "../firmware/usbconfig.h" /* device's VID/PID and names */
28
29static void usage(char *name)
30{
31 fprintf(stderr, "usage:\n");
32 fprintf(stderr, " %s on ....... turn on LED\n", name);
33 fprintf(stderr, " %s off ...... turn off LED\n", name);
34 fprintf(stderr, " %s status ... ask current status of LED\n", name);
35#if ENABLE_TEST
36 fprintf(stderr, " %s test ..... run driver reliability test\n", name);
37#endif /* ENABLE_TEST */
38}
39
40int main(int argc, char **argv)
41{
42usb_dev_handle *handle = NULL;
43const unsigned char rawVid[2] = {USB_CFG_VENDOR_ID}, rawPid[2] = {USB_CFG_DEVICE_ID};
44char vendor[] = {USB_CFG_VENDOR_NAME, 0}, product[] = {USB_CFG_DEVICE_NAME, 0};
45char buffer[4];
46int cnt, vid, pid, isOn;
47
48 usb_init();
49 if(argc < 2){ /* we need at least one argument */
50 usage(argv[0]);
51 exit(1);
52 }
53 /* compute VID/PID from usbconfig.h so that there is a central source of information */
54 vid = rawVid[1] * 256 + rawVid[0];
55 pid = rawPid[1] * 256 + rawPid[0];
56 /* The following function is in opendevice.c: */
57 if(usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) != 0){
58 fprintf(stderr, "Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid, pid);
59 exit(1);
60 }
61 /* Since we use only control endpoint 0, we don't need to choose a
62 * configuration and interface. Reading device descriptor and setting a
63 * configuration and interface is done through endpoint 0 after all.
64 * However, newer versions of Linux require that we claim an interface
65 * even for endpoint 0. Enable the following code if your operating system
66 * needs it: */
67#if 0
68 int retries = 1, usbConfiguration = 1, usbInterface = 0;
69 if(usb_set_configuration(handle, usbConfiguration) && showWarnings){
70 fprintf(stderr, "Warning: could not set configuration: %s\n", usb_strerror());
71 }
72 /* now try to claim the interface and detach the kernel HID driver on
73 * Linux and other operating systems which support the call. */
74 while((len = usb_claim_interface(handle, usbInterface)) != 0 && retries-- > 0){
75#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
76 if(usb_detach_kernel_driver_np(handle, 0) < 0 && showWarnings){
77 fprintf(stderr, "Warning: could not detach kernel driver: %s\n", usb_strerror());
78 }
79#endif
80 }
81#endif
82
83 if(strcasecmp(argv[1], "status") == 0){
84 cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_GET_STATUS, 0, 0, buffer, sizeof(buffer), 5000);
85 if(cnt < 1){
86 if(cnt < 0){
87 fprintf(stderr, "USB error: %s\n", usb_strerror());
88 }else{
89 fprintf(stderr, "only %d bytes received.\n", cnt);
90 }
91 }else{
92 printf("LED is %s\n", buffer[0] ? "on" : "off");
93 }
94 }else if((isOn = (strcasecmp(argv[1], "on") == 0)) || strcasecmp(argv[1], "off") == 0){
95 cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, CUSTOM_RQ_SET_STATUS, isOn, 0, buffer, 0, 5000);
96 if(cnt < 0){
97 fprintf(stderr, "USB error: %s\n", usb_strerror());
98 }
99#if ENABLE_TEST
100 }else if(strcasecmp(argv[1], "test") == 0){
101 int i;
102 srandomdev();
103 for(i = 0; i < 50000; i++){
104 int value = random() & 0xffff, index = random() & 0xffff;
105 int rxValue, rxIndex;
106 if((i+1) % 100 == 0){
107 fprintf(stderr, "\r%05d", i+1);
108 fflush(stderr);
109 }
110 cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_ECHO, value, index, buffer, sizeof(buffer), 5000);
111 if(cnt < 0){
112 fprintf(stderr, "\nUSB error in iteration %d: %s\n", i, usb_strerror());
113 break;
114 }else if(cnt != 4){
115 fprintf(stderr, "\nerror in iteration %d: %d bytes received instead of 4\n", i, cnt);
116 break;
117 }
118 rxValue = ((int)buffer[0] & 0xff) | (((int)buffer[1] & 0xff) << 8);
119 rxIndex = ((int)buffer[2] & 0xff) | (((int)buffer[3] & 0xff) << 8);
120 if(rxValue != value || rxIndex != index){
121 fprintf(stderr, "\ndata error in iteration %d:\n", i);
122 fprintf(stderr, "rxValue = 0x%04x value = 0x%04x\n", rxValue, value);
123 fprintf(stderr, "rxIndex = 0x%04x index = 0x%04x\n", rxIndex, index);
124 }
125 }
126 fprintf(stderr, "\nTest completed.\n");
127#endif /* ENABLE_TEST */
128 }else{
129 usage(argv[0]);
130 exit(1);
131 }
132 usb_close(handle);
133 return 0;
134}
diff --git a/lib/vusb/examples/custom-class/firmware/main.c b/lib/vusb/examples/custom-class/firmware/main.c
new file mode 100644
index 000000000..5c07a7fb0
--- /dev/null
+++ b/lib/vusb/examples/custom-class/firmware/main.c
@@ -0,0 +1,97 @@
1/* Name: main.c
2 * Project: custom-class, a basic USB example
3 * Author: Christian Starkjohann
4 * Creation Date: 2008-04-09
5 * Tabsize: 4
6 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
7 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8 */
9
10/*
11This example should run on most AVRs with only little changes. No special
12hardware resources except INT0 are used. You may have to change usbconfig.h for
13different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or
14at least be connected to INT0 as well.
15We assume that an LED is connected to port B bit 0. If you connect it to a
16different port or bit, change the macros below:
17*/
18#define LED_PORT_DDR DDRB
19#define LED_PORT_OUTPUT PORTB
20#define LED_BIT 0
21
22#include <avr/io.h>
23#include <avr/wdt.h>
24#include <avr/interrupt.h> /* for sei() */
25#include <util/delay.h> /* for _delay_ms() */
26
27#include <avr/pgmspace.h> /* required by usbdrv.h */
28#include "usbdrv.h"
29#include "oddebug.h" /* This is also an example for using debug macros */
30#include "requests.h" /* The custom request numbers we use */
31
32/* ------------------------------------------------------------------------- */
33/* ----------------------------- USB interface ----------------------------- */
34/* ------------------------------------------------------------------------- */
35
36usbMsgLen_t usbFunctionSetup(uchar data[8])
37{
38usbRequest_t *rq = (void *)data;
39static uchar dataBuffer[4]; /* buffer must stay valid when usbFunctionSetup returns */
40
41 if(rq->bRequest == CUSTOM_RQ_ECHO){ /* echo -- used for reliability tests */
42 dataBuffer[0] = rq->wValue.bytes[0];
43 dataBuffer[1] = rq->wValue.bytes[1];
44 dataBuffer[2] = rq->wIndex.bytes[0];
45 dataBuffer[3] = rq->wIndex.bytes[1];
46 usbMsgPtr = dataBuffer; /* tell the driver which data to return */
47 return 4;
48 }else if(rq->bRequest == CUSTOM_RQ_SET_STATUS){
49 if(rq->wValue.bytes[0] & 1){ /* set LED */
50 LED_PORT_OUTPUT |= _BV(LED_BIT);
51 }else{ /* clear LED */
52 LED_PORT_OUTPUT &= ~_BV(LED_BIT);
53 }
54 }else if(rq->bRequest == CUSTOM_RQ_GET_STATUS){
55 dataBuffer[0] = ((LED_PORT_OUTPUT & _BV(LED_BIT)) != 0);
56 usbMsgPtr = dataBuffer; /* tell the driver which data to return */
57 return 1; /* tell the driver to send 1 byte */
58 }
59 return 0; /* default for not implemented requests: return no data back to host */
60}
61
62/* ------------------------------------------------------------------------- */
63
64int __attribute__((noreturn)) main(void)
65{
66uchar i;
67
68 wdt_enable(WDTO_1S);
69 /* If you don't use the watchdog, replace the call above with a wdt_disable().
70 * On newer devices, the status of the watchdog (on/off, period) is PRESERVED
71 * OVER RESET!
72 */
73 /* RESET status: all port bits are inputs without pull-up.
74 * That's the way we need D+ and D-. Therefore we don't need any
75 * additional hardware initialization.
76 */
77 odDebugInit();
78 DBG1(0x00, 0, 0); /* debug output: main starts */
79 usbInit();
80 usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
81 i = 0;
82 while(--i){ /* fake USB disconnect for > 250 ms */
83 wdt_reset();
84 _delay_ms(1);
85 }
86 usbDeviceConnect();
87 LED_PORT_DDR |= _BV(LED_BIT); /* make the LED bit an output */
88 sei();
89 DBG1(0x01, 0, 0); /* debug output: main loop starts */
90 for(;;){ /* main event loop */
91 DBG1(0x02, 0, 0); /* debug output: main loop iterates */
92 wdt_reset();
93 usbPoll();
94 }
95}
96
97/* ------------------------------------------------------------------------- */
diff --git a/lib/vusb/examples/custom-class/firmware/requests.h b/lib/vusb/examples/custom-class/firmware/requests.h
new file mode 100644
index 000000000..3d09e66e8
--- /dev/null
+++ b/lib/vusb/examples/custom-class/firmware/requests.h
@@ -0,0 +1,35 @@
1/* Name: requests.h
2 * Project: custom-class, a basic USB example
3 * Author: Christian Starkjohann
4 * Creation Date: 2008-04-09
5 * Tabsize: 4
6 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
7 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8 */
9
10/* This header is shared between the firmware and the host software. It
11 * defines the USB request numbers (and optionally data types) used to
12 * communicate between the host and the device.
13 */
14
15#ifndef __REQUESTS_H_INCLUDED__
16#define __REQUESTS_H_INCLUDED__
17
18#define CUSTOM_RQ_ECHO 0
19/* Request that the device sends back wValue and wIndex. This is used with
20 * random data to test the reliability of the communication.
21 */
22#define CUSTOM_RQ_SET_STATUS 1
23/* Set the LED status. Control-OUT.
24 * The requested status is passed in the "wValue" field of the control
25 * transfer. No OUT data is sent. Bit 0 of the low byte of wValue controls
26 * the LED.
27 */
28
29#define CUSTOM_RQ_GET_STATUS 2
30/* Get the current LED status. Control-IN.
31 * This control transfer involves a 1 byte data phase where the device sends
32 * the current status to the host. The status is in bit 0 of the byte.
33 */
34
35#endif /* __REQUESTS_H_INCLUDED__ */
diff --git a/lib/vusb/examples/custom-class/make-files.sh b/lib/vusb/examples/custom-class/make-files.sh
new file mode 100755
index 000000000..df3fa5eed
--- /dev/null
+++ b/lib/vusb/examples/custom-class/make-files.sh
@@ -0,0 +1,43 @@
1#!/bin/sh
2# Author: Christian Starkjohann
3# Creation Date: 2008-04-17
4# Tabsize: 4
5# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
6# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
7
8
9if [ "$1" = remove ]; then
10 (cd firmware; make clean)
11 rm -f firmware/usbconfig.h
12 rm -rf firmware/usbdrv
13 rm -f commandline/Makefile.windows
14 rm -f commandline/Makefile
15 rm -f commandline/opendevice.[ch]
16 exit
17fi
18
19cat << \EOF | sed -n -f /dev/stdin ../../usbdrv/usbconfig-prototype.h >firmware/usbconfig.h
20/^\( [*] \)\{0,1\}[+].*$/ d
21s/^#define USB_CFG_DMINUS_BIT .*$/#define USB_CFG_DMINUS_BIT 4/g
22s|^.*#define USB_CFG_CLOCK_KHZ.*$|#define USB_CFG_CLOCK_KHZ (F_CPU/1000)|g
23s/^#define USB_CFG_DEVICE_NAME .*$/#define USB_CFG_DEVICE_NAME 'L', 'E', 'D', 'C', 'o', 'n', 't', 'r', 'o', 'l'/g
24s/^#define USB_CFG_DEVICE_NAME_LEN .*$/#define USB_CFG_DEVICE_NAME_LEN 10/g
25
26s/^#define USB_CFG_MAX_BUS_POWER .*$/#define USB_CFG_MAX_BUS_POWER 40/g
27p
28EOF
29
30cat << \EOF | sed -n -f /dev/stdin ../usbtool/Makefile.windows >commandline/Makefile.windows
31/^\( [*] \)\{0,1\}[+].*$/ d
32s/^# Project: .*$/# Project: custom-class example/g
33p
34EOF
35
36cat << \EOF | sed -n -f /dev/stdin ../usbtool/Makefile >commandline/Makefile
37/^\( [*] \)\{0,1\}[+].*$/ d
38s/^# Project: .*$/# Project: custom-class example/g
39s/^NAME = .*$/NAME = set-led/g
40p
41EOF
42
43cp ../../libs-host/opendevice.[ch] commandline/
diff --git a/lib/vusb/examples/drivertest/commandline/runtest.c b/lib/vusb/examples/drivertest/commandline/runtest.c
new file mode 100644
index 000000000..3d04421f4
--- /dev/null
+++ b/lib/vusb/examples/drivertest/commandline/runtest.c
@@ -0,0 +1,151 @@
1/* Name: runtest.c
2 * Author: Christian Starkjohann
3 * Creation Date: 2008-04-10
4 * Tabsize: 4
5 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
6 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
7 */
8
9/*
10General Description:
11*/
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <usb.h> /* this is libusb */
17#include "opendevice.h" /* common code moved to separate module */
18
19#include "../firmware/requests.h" /* custom request numbers */
20#include "../firmware/usbconfig.h" /* device's VID/PID and names */
21
22#define uchar unsigned char
23
24static void hexdump(char *_buffer, int len, FILE *fp)
25{
26int i;
27uchar *buffer = (uchar *)_buffer;
28
29 for(i = 0; i < len; i++){
30 if(i != 0){
31 if(i % 16 == 0){
32 fprintf(fp, "\n");
33 }else{
34 fprintf(fp, " ");
35 }
36 }
37 fprintf(fp, "%02x", buffer[i]);
38 }
39 if(i != 0)
40 fprintf(fp, "\n");
41}
42
43static void fillBuffer(char *buffer, int len)
44{
45static int type = 0;
46
47 if(type == 0){ /* all 0 */
48 bzero(buffer, len);
49 }else if(type == 1){ /* all 0xff */
50 memset(buffer, 0xff, len);
51 }else{ /* random */
52 int i;
53 for(i = 0; i < len; i++){
54 buffer[i] = random() & 0xff;
55 }
56 }
57 if(++type >= 1000)
58 type = 0;
59}
60
61static int compareBuffers(char *txBuffer, char *rxBuffer, int len)
62{
63int i, rval = 0;
64
65 for(i = 0; i < len; i++){
66 if(rxBuffer[i] != txBuffer[i]){
67 fprintf(stderr, "compare error at index %d: byte is 0x%x instead of 0x%x\n", i, rxBuffer[i], txBuffer[i]);
68 rval = 1;
69 }
70 }
71 if(rval){
72 fprintf(stderr, "txBuffer was:\n");
73 hexdump(txBuffer, len, stderr);
74 fprintf(stderr, "rxBuffer is:\n");
75 hexdump(rxBuffer, len, stderr);
76 }
77 return rval;
78}
79
80int main(int argc, char **argv)
81{
82usb_dev_handle *handle = NULL;
83const uchar rawVid[2] = {USB_CFG_VENDOR_ID}, rawPid[2] = {USB_CFG_DEVICE_ID};
84char vendor[] = {USB_CFG_VENDOR_NAME, 0}, product[] = {USB_CFG_DEVICE_NAME, 0};
85char txBuffer[64], rxBuffer[64];
86int cnt, vid, pid, i, j;
87
88 usb_init();
89 /* compute VID/PID from usbconfig.h so that there is a central source of information */
90 vid = rawVid[1] * 256 + rawVid[0];
91 pid = rawPid[1] * 256 + rawPid[0];
92 /* The following function is in opendevice.c: */
93 if(usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) != 0){
94 fprintf(stderr, "Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid, pid);
95 exit(1);
96 }
97 if(argc > 1 && strcasecmp(argv[1], "osccal") == 0){
98 if(argc > 2){ /* set osccal */
99 int osccal = atoi(argv[2]);
100 printf("setting osccal to %d\n", osccal);
101 cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_SET_OSCCAL, osccal, 0, txBuffer, 0, 5000);
102 if(cnt < 0){
103 fprintf(stderr, "\nUSB error setting osccal: %s\n", usb_strerror());
104 }
105 }else{
106 cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_GET_OSCCAL, 0, 0, rxBuffer, 1, 5000);
107 if(cnt < 0){
108 fprintf(stderr, "\nUSB error getting osccal: %s\n", usb_strerror());
109 }else{
110 printf("osccal = %d\n", (unsigned char)rxBuffer[0]);
111 }
112 }
113 }else{
114 srandomdev();
115 for(i = 0; i <= 100000; i++){
116 fillBuffer(txBuffer, sizeof(txBuffer));
117 cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, CUSTOM_RQ_SET_DATA, 0, 0, txBuffer, sizeof(txBuffer), 5000);
118 if(cnt < 0){
119 fprintf(stderr, "\nUSB tx error in iteration %d: %s\n", i, usb_strerror());
120 break;
121 }else if(cnt != sizeof(txBuffer)){
122 fprintf(stderr, "\nerror in iteration %d: %d bytes sent instead of %d\n", i, cnt, (int)sizeof(txBuffer));
123 break;
124 }
125 for(j = 0; j < sizeof(rxBuffer); j++){
126 rxBuffer[j] = ~txBuffer[j];
127 }
128 cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_GET_DATA, 0, 0, rxBuffer, sizeof(rxBuffer), 5000);
129 if(cnt < 0){
130 fprintf(stderr, "\nUSB rx error in iteration %d: %s\n", i, usb_strerror());
131 break;
132 }else if(cnt != sizeof(txBuffer)){
133 fprintf(stderr, "\nerror in iteration %d: %d bytes received instead of %d\n", i, cnt, (int)sizeof(rxBuffer));
134 break;
135 }
136 if(compareBuffers(txBuffer, rxBuffer, sizeof(rxBuffer))){
137 fprintf(stderr, "\ncompare error in iteration %d.\n", i);
138 break;
139 }
140 if(i != 0 && i % 100 == 0){
141 printf(".");
142 fflush(stdout);
143 if(i % 5000 == 0)
144 printf(" %6d\n", i);
145 }
146 }
147 fprintf(stderr, "\nTest completed.\n");
148 }
149 usb_close(handle);
150 return 0;
151}
diff --git a/lib/vusb/examples/drivertest/firmware/main.c b/lib/vusb/examples/drivertest/firmware/main.c
new file mode 100644
index 000000000..d24e50f67
--- /dev/null
+++ b/lib/vusb/examples/drivertest/firmware/main.c
@@ -0,0 +1,128 @@
1/* Name: main.c
2 * Project: hid-custom-rq example
3 * Author: Christian Starkjohann
4 * Creation Date: 2008-04-07
5 * Tabsize: 4
6 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
7 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8 */
9
10/*
11This example should run on most AVRs with only little changes. No special
12hardware resources except INT0 are used. You may have to change usbconfig.h for
13different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or
14at least be connected to INT0 as well.
15*/
16
17#include <avr/io.h>
18#include <avr/wdt.h>
19#include <avr/interrupt.h> /* for sei() */
20#include <util/delay.h> /* for _delay_ms() */
21
22#include <avr/pgmspace.h> /* required by usbdrv.h */
23#include "usbdrv.h"
24#include "oddebug.h" /* This is also an example for using debug macros */
25#include "requests.h" /* The custom request numbers we use */
26
27#if TUNE_OSCCAL
28uchar lastTimer0Value;
29#endif
30
31#if CALIBRATE_OSCCAL
32#include "osccal.c"
33#endif
34
35
36/* ------------------------------------------------------------------------- */
37/* ----------------------------- USB interface ----------------------------- */
38/* ------------------------------------------------------------------------- */
39
40static uchar dataBuffer[64];
41static uchar writeIndex;
42
43uchar usbFunctionWrite(uchar *data, uchar len)
44{
45
46 if(writeIndex + len <= sizeof(dataBuffer)){
47 uchar i;
48 for(i = 0; i < len; i++){
49 dataBuffer[writeIndex++] = *data++;
50 }
51 }
52 return writeIndex >= sizeof(dataBuffer);
53}
54
55usbMsgLen_t usbFunctionSetup(uchar data[8])
56{
57usbRequest_t *rq = (void *)data;
58
59 DBG1(0x50, &rq->bRequest, 1); /* debug output: print our request */
60 if(rq->bRequest == CUSTOM_RQ_SET_DATA){
61 writeIndex = 0;
62 return USB_NO_MSG;
63 }else if(rq->bRequest == CUSTOM_RQ_GET_DATA){
64 usbMsgPtr = dataBuffer; /* tell the driver which data to return */
65 return sizeof(dataBuffer); /* tell the driver how many bytes to send */
66 }else if(rq->bRequest == CUSTOM_RQ_SET_OSCCAL){
67 OSCCAL = rq->wValue.bytes[0];
68 }else if(rq->bRequest == CUSTOM_RQ_GET_OSCCAL){
69 usbMsgPtr = (uchar *)&OSCCAL;
70 return 1;
71 }
72 return 0; /* default for not implemented requests: return no data back to host */
73}
74
75/* ------------------------------------------------------------------------- */
76
77int __attribute__((noreturn)) main(void)
78{
79uchar i;
80
81 wdt_enable(WDTO_1S);
82 /* If you don't use the watchdog, replace the call above with a wdt_disable().
83 * On newer devices, the status of the watchdog (on/off, period) is PRESERVED
84 * OVER RESET!
85 */
86 odDebugInit();
87 DBG1(0x00, 0, 0); /* debug output: main starts */
88 /* RESET status: all port bits are inputs without pull-up.
89 * That's the way we need D+ and D-. Therefore we don't need any
90 * additional hardware initialization.
91 */
92 TCCR2 = 9 | (1 << COM20);
93 OCR2 = 3; /* should give F_CPU/8 clock */
94
95 DDRB = (1 << 2) | (1 << 3);
96 TCCR0 = 3; /* 1/64 prescaler */
97 usbInit();
98 usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
99 i = 0;
100 while(--i){ /* fake USB disconnect for > 250 ms */
101 wdt_reset();
102 _delay_ms(1);
103 }
104 usbDeviceConnect();
105 sei();
106 DBG1(0x01, 0, 0); /* debug output: main loop starts */
107 for(;;){ /* main event loop */
108 wdt_reset();
109 usbPoll();
110 cli(); /* disable interrupts for some cycles, use other cli as nop */
111 cli();
112 cli();
113 cli();
114 cli();
115 cli();
116 cli();
117 cli();
118 cli();
119 cli();
120 cli();
121 cli();
122 cli();
123 cli();
124 sei();
125 }
126}
127
128/* ------------------------------------------------------------------------- */
diff --git a/lib/vusb/examples/drivertest/firmware/requests.h b/lib/vusb/examples/drivertest/firmware/requests.h
new file mode 100644
index 000000000..475101a37
--- /dev/null
+++ b/lib/vusb/examples/drivertest/firmware/requests.h
@@ -0,0 +1,28 @@
1/* Name: requests.h
2 * Project: custom-class, a basic USB example
3 * Author: Christian Starkjohann
4 * Creation Date: 2008-04-09
5 * Tabsize: 4
6 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
7 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8 */
9
10/* This header is shared between the firmware and the host software. It
11 * defines the USB request numbers (and optionally data types) used to
12 * communicate between the host and the device.
13 */
14
15#ifndef __REQUESTS_H_INCLUDED__
16#define __REQUESTS_H_INCLUDED__
17
18#define CUSTOM_RQ_SET_DATA 1
19/* Send data to device. Control-OUT with 64 bytes data.
20 */
21
22#define CUSTOM_RQ_GET_DATA 2
23/* Get data from device. Control-IN with 64 bytes data.
24 */
25#define CUSTOM_RQ_SET_OSCCAL 3
26#define CUSTOM_RQ_GET_OSCCAL 4
27
28#endif /* __REQUESTS_H_INCLUDED__ */
diff --git a/lib/vusb/examples/drivertest/make-files.sh b/lib/vusb/examples/drivertest/make-files.sh
new file mode 100755
index 000000000..af4ef7950
--- /dev/null
+++ b/lib/vusb/examples/drivertest/make-files.sh
@@ -0,0 +1,33 @@
1#!/bin/sh
2# Author: Christian Starkjohann
3# Creation Date: 2008-04-17
4# Tabsize: 4
5# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
6# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
7
8
9if [ "$1" = remove ]; then
10 (cd firmware; make clean)
11 rm -rf firmware/usbdrv
12 rm -f firmware/osccal.[ch]
13 rm -f commandline/Makefile.windows
14 rm -f commandline/Makefile
15 rm -f commandline/opendevice.[ch]
16 exit
17fi
18
19cat << \EOF | sed -n -f /dev/stdin ../usbtool/Makefile.windows >commandline/Makefile.windows
20/^\( [*] \)\{0,1\}[+].*$/ d
21s/^# Project: .*$/# Project: hid-custom-rq example/g
22p
23EOF
24
25cat << \EOF | sed -n -f /dev/stdin ../usbtool/Makefile >commandline/Makefile
26/^\( [*] \)\{0,1\}[+].*$/ d
27s/^# Project: .*$/# Project: hid-custom-rq example/g
28s/^NAME = .*$/NAME = runtest/g
29p
30EOF
31
32cp ../../libs-host/opendevice.[ch] commandline/
33cp ../../libs-device/osccal.[ch] firmware/
diff --git a/lib/vusb/examples/hid-custom-rq/Readme.txt b/lib/vusb/examples/hid-custom-rq/Readme.txt
new file mode 100644
index 000000000..6a2ab3b6c
--- /dev/null
+++ b/lib/vusb/examples/hid-custom-rq/Readme.txt
@@ -0,0 +1,28 @@
1This is the Readme file for the hid-custom-rq example. This is basically the
2same as the custom-class example, except that the device conforms to the USB
3HID class.
4
5
6WHAT IS DEMONSTRATED?
7=====================
8This example demonstrates how custom requests can be sent to devices which
9are otherwise HID compliant. This mechanism can be used to prevent the
10"driver CD" dialog on Windows and still control the device with libusb-win32.
11It can also be used to extend the functionality of the USB class, e.g. by
12setting parameters.
13
14Please note that you should install the filter version of libusb-win32 to
15take full advantage or this mode. The device driver version only has access
16to devices which have been registered for it with a *.inf file. The filter
17version has access to all devices.
18
19
20MORE INFORMATION
21================
22For information about how to build this example and how to use the command
23line tool see the Readme file in the custom-class example.
24
25
26----------------------------------------------------------------------------
27(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH.
28http://www.obdev.at/
diff --git a/lib/vusb/examples/hid-custom-rq/firmware/main.c b/lib/vusb/examples/hid-custom-rq/firmware/main.c
new file mode 100644
index 000000000..605d58b47
--- /dev/null
+++ b/lib/vusb/examples/hid-custom-rq/firmware/main.c
@@ -0,0 +1,120 @@
1/* Name: main.c
2 * Project: hid-custom-rq example
3 * Author: Christian Starkjohann
4 * Creation Date: 2008-04-07
5 * Tabsize: 4
6 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
7 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8 */
9
10/*
11This example should run on most AVRs with only little changes. No special
12hardware resources except INT0 are used. You may have to change usbconfig.h for
13different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or
14at least be connected to INT0 as well.
15We assume that an LED is connected to port B bit 0. If you connect it to a
16different port or bit, change the macros below:
17*/
18#define LED_PORT_DDR DDRB
19#define LED_PORT_OUTPUT PORTB
20#define LED_BIT 0
21
22#include <avr/io.h>
23#include <avr/wdt.h>
24#include <avr/interrupt.h> /* for sei() */
25#include <util/delay.h> /* for _delay_ms() */
26
27#include <avr/pgmspace.h> /* required by usbdrv.h */
28#include "usbdrv.h"
29#include "oddebug.h" /* This is also an example for using debug macros */
30#include "requests.h" /* The custom request numbers we use */
31
32/* ------------------------------------------------------------------------- */
33/* ----------------------------- USB interface ----------------------------- */
34/* ------------------------------------------------------------------------- */
35
36PROGMEM const char usbHidReportDescriptor[22] = { /* USB report descriptor */
37 0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop)
38 0x09, 0x01, // USAGE (Vendor Usage 1)
39 0xa1, 0x01, // COLLECTION (Application)
40 0x15, 0x00, // LOGICAL_MINIMUM (0)
41 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
42 0x75, 0x08, // REPORT_SIZE (8)
43 0x95, 0x01, // REPORT_COUNT (1)
44 0x09, 0x00, // USAGE (Undefined)
45 0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf)
46 0xc0 // END_COLLECTION
47};
48/* The descriptor above is a dummy only, it silences the drivers. The report
49 * it describes consists of one byte of undefined data.
50 * We don't transfer our data through HID reports, we use custom requests
51 * instead.
52 */
53
54/* ------------------------------------------------------------------------- */
55
56usbMsgLen_t usbFunctionSetup(uchar data[8])
57{
58usbRequest_t *rq = (void *)data;
59
60 if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_VENDOR){
61 DBG1(0x50, &rq->bRequest, 1); /* debug output: print our request */
62 if(rq->bRequest == CUSTOM_RQ_SET_STATUS){
63 if(rq->wValue.bytes[0] & 1){ /* set LED */
64 LED_PORT_OUTPUT |= _BV(LED_BIT);
65 }else{ /* clear LED */
66 LED_PORT_OUTPUT &= ~_BV(LED_BIT);
67 }
68 }else if(rq->bRequest == CUSTOM_RQ_GET_STATUS){
69 static uchar dataBuffer[1]; /* buffer must stay valid when usbFunctionSetup returns */
70 dataBuffer[0] = ((LED_PORT_OUTPUT & _BV(LED_BIT)) != 0);
71 usbMsgPtr = dataBuffer; /* tell the driver which data to return */
72 return 1; /* tell the driver to send 1 byte */
73 }
74 }else{
75 /* calss requests USBRQ_HID_GET_REPORT and USBRQ_HID_SET_REPORT are
76 * not implemented since we never call them. The operating system
77 * won't call them either because our descriptor defines no meaning.
78 */
79 }
80 return 0; /* default for not implemented requests: return no data back to host */
81}
82
83/* ------------------------------------------------------------------------- */
84
85int __attribute__((noreturn)) main(void)
86{
87uchar i;
88
89 wdt_enable(WDTO_1S);
90 /* If you don't use the watchdog, replace the call above with a wdt_disable().
91 * On newer devices, the status of the watchdog (on/off, period) is PRESERVED
92 * OVER RESET!
93 */
94 /* RESET status: all port bits are inputs without pull-up.
95 * That's the way we need D+ and D-. Therefore we don't need any
96 * additional hardware initialization.
97 */
98 odDebugInit();
99 DBG1(0x00, 0, 0); /* debug output: main starts */
100 usbInit();
101 usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
102 i = 0;
103 while(--i){ /* fake USB disconnect for > 250 ms */
104 wdt_reset();
105 _delay_ms(1);
106 }
107 usbDeviceConnect();
108 LED_PORT_DDR |= _BV(LED_BIT); /* make the LED bit an output */
109 sei();
110 DBG1(0x01, 0, 0); /* debug output: main loop starts */
111 for(;;){ /* main event loop */
112#if 0 /* this is a bit too aggressive for a debug output */
113 DBG2(0x02, 0, 0); /* debug output: main loop iterates */
114#endif
115 wdt_reset();
116 usbPoll();
117 }
118}
119
120/* ------------------------------------------------------------------------- */
diff --git a/lib/vusb/examples/hid-custom-rq/firmware/requests.h b/lib/vusb/examples/hid-custom-rq/firmware/requests.h
new file mode 100644
index 000000000..630a68551
--- /dev/null
+++ b/lib/vusb/examples/hid-custom-rq/firmware/requests.h
@@ -0,0 +1,31 @@
1/* Name: requests.h
2 * Project: custom-class, a basic USB example
3 * Author: Christian Starkjohann
4 * Creation Date: 2008-04-09
5 * Tabsize: 4
6 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
7 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8 */
9
10/* This header is shared between the firmware and the host software. It
11 * defines the USB request numbers (and optionally data types) used to
12 * communicate between the host and the device.
13 */
14
15#ifndef __REQUESTS_H_INCLUDED__
16#define __REQUESTS_H_INCLUDED__
17
18#define CUSTOM_RQ_SET_STATUS 1
19/* Set the LED status. Control-OUT.
20 * The requested status is passed in the "wValue" field of the control
21 * transfer. No OUT data is sent. Bit 0 of the low byte of wValue controls
22 * the LED.
23 */
24
25#define CUSTOM_RQ_GET_STATUS 2
26/* Get the current LED status. Control-IN.
27 * This control transfer involves a 1 byte data phase where the device sends
28 * the current status to the host. The status is in bit 0 of the byte.
29 */
30
31#endif /* __REQUESTS_H_INCLUDED__ */
diff --git a/lib/vusb/examples/hid-custom-rq/make-files.sh b/lib/vusb/examples/hid-custom-rq/make-files.sh
new file mode 100755
index 000000000..844761489
--- /dev/null
+++ b/lib/vusb/examples/hid-custom-rq/make-files.sh
@@ -0,0 +1,61 @@
1#!/bin/sh
2# Author: Christian Starkjohann
3# Creation Date: 2008-04-17
4# Tabsize: 4
5# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
6# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
7
8
9if [ "$1" = remove ]; then
10 (cd firmware; make clean)
11 rm -f firmware/usbconfig.h
12 rm -rf firmware/usbdrv
13 rm -f firmware/Makefile
14 rm -rf commandline
15 exit
16fi
17
18cat << \EOF | sed -n -f /dev/stdin ../../usbdrv/usbconfig-prototype.h >firmware/usbconfig.h
19/^\( [*] \)\{0,1\}[+].*$/ d
20s/^#define USB_CFG_DMINUS_BIT .*$/#define USB_CFG_DMINUS_BIT 4/g
21s|^.*#define USB_CFG_CLOCK_KHZ.*$|#define USB_CFG_CLOCK_KHZ (F_CPU/1000)|g
22s/^#define USB_CFG_HAVE_INTRIN_ENDPOINT .*$/#define USB_CFG_HAVE_INTRIN_ENDPOINT 1/g
23s|^#define USB_CFG_DEVICE_ID .*$|#define USB_CFG_DEVICE_ID 0xdf, 0x05 /* obdev's shared PID for HIDs */|g
24s/^#define USB_CFG_DEVICE_NAME .*$/#define USB_CFG_DEVICE_NAME 'L', 'E', 'D', 'C', 't', 'l', 'H', 'I', 'D'/g
25s/^#define USB_CFG_DEVICE_NAME_LEN .*$/#define USB_CFG_DEVICE_NAME_LEN 9/g
26
27s/^#define USB_CFG_INTR_POLL_INTERVAL .*$/#define USB_CFG_INTR_POLL_INTERVAL 100/g
28s/^#define USB_CFG_MAX_BUS_POWER .*$/#define USB_CFG_MAX_BUS_POWER 40/g
29s/^#define USB_CFG_DEVICE_CLASS .*$/#define USB_CFG_DEVICE_CLASS 0/g
30s/^#define USB_CFG_INTERFACE_CLASS .*$/#define USB_CFG_INTERFACE_CLASS 3/g
31s/^.*#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH.*$/#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 22/g
32p
33EOF
34
35cat << \EOF | sed -n -f /dev/stdin ../custom-class/firmware/Makefile >firmware/Makefile
36/^\( [*] \)\{0,1\}[+].*$/ d
37s/^# Project: .*$/# Project: hid-custom-rq example/g
38p
39EOF
40
41mkdir commandline 2>/dev/null
42cat << \EOF | sed -n -f /dev/stdin ../custom-class/commandline/set-led.c >commandline/set-led.c
43/^\( [*] \)\{0,1\}[+].*$/ d
44s/^ [*] Project: .*$/ * Project: hid-custom-rq example/g
45p
46EOF
47
48cat << \EOF | sed -n -f /dev/stdin ../usbtool/Makefile.windows >commandline/Makefile.windows
49/^\( [*] \)\{0,1\}[+].*$/ d
50s/^# Project: .*$/# Project: hid-custom-rq example/g
51p
52EOF
53
54cat << \EOF | sed -n -f /dev/stdin ../usbtool/Makefile >commandline/Makefile
55/^\( [*] \)\{0,1\}[+].*$/ d
56s/^# Project: .*$/# Project: hid-custom-rq example/g
57s/^NAME = .*$/NAME = set-led/g
58p
59EOF
60
61cp ../../libs-host/opendevice.[ch] commandline/
diff --git a/lib/vusb/examples/hid-data/Readme.txt b/lib/vusb/examples/hid-data/Readme.txt
new file mode 100644
index 000000000..cb17baa01
--- /dev/null
+++ b/lib/vusb/examples/hid-data/Readme.txt
@@ -0,0 +1,75 @@
1This is the Readme file for the hid-data example. In this example, we show
2how blocks of data can be exchanged with the device using only functionality
3compliant to the HID class. Since class drivers for HID are included with
4Windows, you don't need to install drivers on Windows.
5
6
7WHAT IS DEMONSTRATED?
8=====================
9This example demonstrates how the HID class can be misused to transfer fixed
10size blocks of data (up to the driver's transfer size limit) over HID feature
11reports. This technique is of great value on Windows because no driver DLLs
12are needed (the hid-custom-rq example still requires the libusb-win32 DLL,
13although it may be in the program's directory). The host side application
14requires no installation, it can even be started directly from a CD. This
15example also demonstrates how to transfer data using usbFunctionWrite() and
16usbFunctionRead().
17
18
19PREREQUISITES
20=============
21Target hardware: You need an AVR based circuit based on one of the examples
22(see the "circuits" directory at the top level of this package), e.g. the
23metaboard (http://www.obdev.at/goto.php?t=metaboard).
24
25AVR development environment: You need the gcc tool chain for the AVR, see
26the Prerequisites section in the top level Readme file for how to obtain it.
27
28Host development environment: A C compiler and libusb on Unix. On Windows
29you need the Driver Development Kit (DDK) Instead of libusb. MinGW ships
30with a free version of the DDK.
31
32
33BUILDING THE FIRMWARE
34=====================
35Change to the "firmware" directory and modify Makefile according to your
36architecture (CPU clock, target device, fuse values) and ISP programmer. Then
37edit usbconfig.h according to your pin assignments for D+ and D-. The default
38settings are for the metaboard hardware.
39
40Type "make hex" to build main.hex, then "make flash" to upload the firmware
41to the device. Don't forget to run "make fuse" once to program the fuses. If
42you use a prototyping board with boot loader, follow the instructions of the
43boot loader instead.
44
45Please note that the first "make hex" copies the driver from the top level
46into the firmware directory. If you use a different build system than our
47Makefile, you must copy the driver by hand.
48
49
50BUILDING THE HOST SOFTWARE
51==========================
52Make sure that you have libusb (on Unix) or the DDK (on Windows) installed.
53We recommend MinGW on Windows since it includes a free version of the DDK.
54Then change to directory "commandline" and run "make" on Unix or
55"make -f Makefile.windows" on Windows.
56
57
58USING THE COMMAND LINE TOOL
59===========================
60The device implements a data store of 128 bytes in EEPROM. You can send a
61block of 128 bytes to the device or read the block using the command line
62tool.
63
64To send a block to the device, use e.g.
65
66 hidtool write 0x01,0x02,0x03,0x04,...
67
68and to receive the block, use
69
70 hidtool read
71
72
73----------------------------------------------------------------------------
74(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH.
75http://www.obdev.at/
diff --git a/lib/vusb/examples/hid-data/commandline/hidtool.c b/lib/vusb/examples/hid-data/commandline/hidtool.c
new file mode 100644
index 000000000..609531253
--- /dev/null
+++ b/lib/vusb/examples/hid-data/commandline/hidtool.c
@@ -0,0 +1,126 @@
1/* Name: hidtool.c
2 * Project: hid-data example
3 * Author: Christian Starkjohann
4 * Creation Date: 2008-04-11
5 * Tabsize: 4
6 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
7 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8 */
9
10#include <stdio.h>
11#include <string.h>
12#include <stdlib.h>
13#include "hiddata.h"
14#include "../firmware/usbconfig.h" /* for device VID, PID, vendor name and product name */
15
16/* ------------------------------------------------------------------------- */
17
18static char *usbErrorMessage(int errCode)
19{
20static char buffer[80];
21
22 switch(errCode){
23 case USBOPEN_ERR_ACCESS: return "Access to device denied";
24 case USBOPEN_ERR_NOTFOUND: return "The specified device was not found";
25 case USBOPEN_ERR_IO: return "Communication error with device";
26 default:
27 sprintf(buffer, "Unknown USB error %d", errCode);
28 return buffer;
29 }
30 return NULL; /* not reached */
31}
32
33static usbDevice_t *openDevice(void)
34{
35usbDevice_t *dev = NULL;
36unsigned char rawVid[2] = {USB_CFG_VENDOR_ID}, rawPid[2] = {USB_CFG_DEVICE_ID};
37char vendorName[] = {USB_CFG_VENDOR_NAME, 0}, productName[] = {USB_CFG_DEVICE_NAME, 0};
38int vid = rawVid[0] + 256 * rawVid[1];
39int pid = rawPid[0] + 256 * rawPid[1];
40int err;
41
42 if((err = usbhidOpenDevice(&dev, vid, vendorName, pid, productName, 0)) != 0){
43 fprintf(stderr, "error finding %s: %s\n", productName, usbErrorMessage(err));
44 return NULL;
45 }
46 return dev;
47}
48
49/* ------------------------------------------------------------------------- */
50
51static void hexdump(char *buffer, int len)
52{
53int i;
54FILE *fp = stdout;
55
56 for(i = 0; i < len; i++){
57 if(i != 0){
58 if(i % 16 == 0){
59 fprintf(fp, "\n");
60 }else{
61 fprintf(fp, " ");
62 }
63 }
64 fprintf(fp, "0x%02x", buffer[i] & 0xff);
65 }
66 if(i != 0)
67 fprintf(fp, "\n");
68}
69
70static int hexread(char *buffer, char *string, int buflen)
71{
72char *s;
73int pos = 0;
74
75 while((s = strtok(string, ", ")) != NULL && pos < buflen){
76 string = NULL;
77 buffer[pos++] = (char)strtol(s, NULL, 0);
78 }
79 return pos;
80}
81
82/* ------------------------------------------------------------------------- */
83
84static void usage(char *myName)
85{
86 fprintf(stderr, "usage:\n");
87 fprintf(stderr, " %s read\n", myName);
88 fprintf(stderr, " %s write <listofbytes>\n", myName);
89}
90
91int main(int argc, char **argv)
92{
93usbDevice_t *dev;
94char buffer[129]; /* room for dummy report ID */
95int err;
96
97 if(argc < 2){
98 usage(argv[0]);
99 exit(1);
100 }
101 if((dev = openDevice()) == NULL)
102 exit(1);
103 if(strcasecmp(argv[1], "read") == 0){
104 int len = sizeof(buffer);
105 if((err = usbhidGetReport(dev, 0, buffer, &len)) != 0){
106 fprintf(stderr, "error reading data: %s\n", usbErrorMessage(err));
107 }else{
108 hexdump(buffer + 1, sizeof(buffer) - 1);
109 }
110 }else if(strcasecmp(argv[1], "write") == 0){
111 int i, pos;
112 memset(buffer, 0, sizeof(buffer));
113 for(pos = 1, i = 2; i < argc && pos < sizeof(buffer); i++){
114 pos += hexread(buffer + pos, argv[i], sizeof(buffer) - pos);
115 }
116 if((err = usbhidSetReport(dev, buffer, sizeof(buffer))) != 0) /* add a dummy report ID */
117 fprintf(stderr, "error writing data: %s\n", usbErrorMessage(err));
118 }else{
119 usage(argv[0]);
120 exit(1);
121 }
122 usbhidCloseDevice(dev);
123 return 0;
124}
125
126/* ------------------------------------------------------------------------- */
diff --git a/lib/vusb/examples/hid-data/firmware/main.c b/lib/vusb/examples/hid-data/firmware/main.c
new file mode 100644
index 000000000..7c8c85e4b
--- /dev/null
+++ b/lib/vusb/examples/hid-data/firmware/main.c
@@ -0,0 +1,141 @@
1/* Name: main.c
2 * Project: hid-data, example how to use HID for data transfer
3 * Author: Christian Starkjohann
4 * Creation Date: 2008-04-11
5 * Tabsize: 4
6 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
7 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8 */
9
10/*
11This example should run on most AVRs with only little changes. No special
12hardware resources except INT0 are used. You may have to change usbconfig.h for
13different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or
14at least be connected to INT0 as well.
15*/
16
17#include <avr/io.h>
18#include <avr/wdt.h>
19#include <avr/interrupt.h> /* for sei() */
20#include <util/delay.h> /* for _delay_ms() */
21#include <avr/eeprom.h>
22
23#include <avr/pgmspace.h> /* required by usbdrv.h */
24#include "usbdrv.h"
25#include "oddebug.h" /* This is also an example for using debug macros */
26
27/* ------------------------------------------------------------------------- */
28/* ----------------------------- USB interface ----------------------------- */
29/* ------------------------------------------------------------------------- */
30
31PROGMEM const char usbHidReportDescriptor[22] = { /* USB report descriptor */
32 0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop)
33 0x09, 0x01, // USAGE (Vendor Usage 1)
34 0xa1, 0x01, // COLLECTION (Application)
35 0x15, 0x00, // LOGICAL_MINIMUM (0)
36 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
37 0x75, 0x08, // REPORT_SIZE (8)
38 0x95, 0x80, // REPORT_COUNT (128)
39 0x09, 0x00, // USAGE (Undefined)
40 0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf)
41 0xc0 // END_COLLECTION
42};
43/* Since we define only one feature report, we don't use report-IDs (which
44 * would be the first byte of the report). The entire report consists of 128
45 * opaque data bytes.
46 */
47
48/* The following variables store the status of the current data transfer */
49static uchar currentAddress;
50static uchar bytesRemaining;
51
52/* ------------------------------------------------------------------------- */
53
54/* usbFunctionRead() is called when the host requests a chunk of data from
55 * the device. For more information see the documentation in usbdrv/usbdrv.h.
56 */
57uchar usbFunctionRead(uchar *data, uchar len)
58{
59 if(len > bytesRemaining)
60 len = bytesRemaining;
61 eeprom_read_block(data, (uchar *)0 + currentAddress, len);
62 currentAddress += len;
63 bytesRemaining -= len;
64 return len;
65}
66
67/* usbFunctionWrite() is called when the host sends a chunk of data to the
68 * device. For more information see the documentation in usbdrv/usbdrv.h.
69 */
70uchar usbFunctionWrite(uchar *data, uchar len)
71{
72 if(bytesRemaining == 0)
73 return 1; /* end of transfer */
74 if(len > bytesRemaining)
75 len = bytesRemaining;
76 eeprom_write_block(data, (uchar *)0 + currentAddress, len);
77 currentAddress += len;
78 bytesRemaining -= len;
79 return bytesRemaining == 0; /* return 1 if this was the last chunk */
80}
81
82/* ------------------------------------------------------------------------- */
83
84usbMsgLen_t usbFunctionSetup(uchar data[8])
85{
86usbRequest_t *rq = (void *)data;
87
88 if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* HID class request */
89 if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */
90 /* since we have only one report type, we can ignore the report-ID */
91 bytesRemaining = 128;
92 currentAddress = 0;
93 return USB_NO_MSG; /* use usbFunctionRead() to obtain data */
94 }else if(rq->bRequest == USBRQ_HID_SET_REPORT){
95 /* since we have only one report type, we can ignore the report-ID */
96 bytesRemaining = 128;
97 currentAddress = 0;
98 return USB_NO_MSG; /* use usbFunctionWrite() to receive data from host */
99 }
100 }else{
101 /* ignore vendor type requests, we don't use any */
102 }
103 return 0;
104}
105
106/* ------------------------------------------------------------------------- */
107
108int main(void)
109{
110uchar i;
111
112 wdt_enable(WDTO_1S);
113 /* If you don't use the watchdog, replace the call above with a wdt_disable().
114 * On newer devices, the status of the watchdog (on/off, period) is PRESERVED
115 * OVER RESET!
116 */
117 /* RESET status: all port bits are inputs without pull-up.
118 * That's the way we need D+ and D-. Therefore we don't need any
119 * additional hardware initialization.
120 */
121 odDebugInit();
122 DBG1(0x00, 0, 0); /* debug output: main starts */
123 usbInit();
124 usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
125 i = 0;
126 while(--i){ /* fake USB disconnect for > 250 ms */
127 wdt_reset();
128 _delay_ms(1);
129 }
130 usbDeviceConnect();
131 sei();
132 DBG1(0x01, 0, 0); /* debug output: main loop starts */
133 for(;;){ /* main event loop */
134 DBG1(0x02, 0, 0); /* debug output: main loop iterates */
135 wdt_reset();
136 usbPoll();
137 }
138 return 0;
139}
140
141/* ------------------------------------------------------------------------- */
diff --git a/lib/vusb/examples/hid-data/make-files.sh b/lib/vusb/examples/hid-data/make-files.sh
new file mode 100755
index 000000000..3da9bd549
--- /dev/null
+++ b/lib/vusb/examples/hid-data/make-files.sh
@@ -0,0 +1,44 @@
1#!/bin/sh
2# Author: Christian Starkjohann
3# Creation Date: 2008-04-17
4# Tabsize: 4
5# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
6# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
7
8
9if [ "$1" = remove ]; then
10 (cd firmware; make clean)
11 rm -f firmware/usbconfig.h
12 rm -rf firmware/usbdrv
13 rm -f firmware/Makefile
14 rm -f commandline/hiddata.[ch]
15 rm -f commandline/hidsdi.h
16 exit
17fi
18
19cat << \EOF | sed -n -f /dev/stdin ../../usbdrv/usbconfig-prototype.h >firmware/usbconfig.h
20/^\( [*] \)\{0,1\}[+].*$/ d
21s/^#define USB_CFG_DMINUS_BIT .*$/#define USB_CFG_DMINUS_BIT 4/g
22s|^.*#define USB_CFG_CLOCK_KHZ.*$|#define USB_CFG_CLOCK_KHZ (F_CPU/1000)|g
23s/^#define USB_CFG_HAVE_INTRIN_ENDPOINT .*$/#define USB_CFG_HAVE_INTRIN_ENDPOINT 1/g
24s|^#define USB_CFG_DEVICE_ID .*$|#define USB_CFG_DEVICE_ID 0xdf, 0x05 /* obdev's shared PID for HIDs */|g
25s/^#define USB_CFG_DEVICE_NAME .*$/#define USB_CFG_DEVICE_NAME 'D', 'a', 't', 'a', 'S', 't', 'o', 'r', 'e'/g
26s/^#define USB_CFG_DEVICE_NAME_LEN .*$/#define USB_CFG_DEVICE_NAME_LEN 9/g
27
28s/^#define USB_CFG_INTR_POLL_INTERVAL .*$/#define USB_CFG_INTR_POLL_INTERVAL 100/g
29s/^#define USB_CFG_MAX_BUS_POWER .*$/#define USB_CFG_MAX_BUS_POWER 20/g
30s/^#define USB_CFG_IMPLEMENT_FN_WRITE .*$/#define USB_CFG_IMPLEMENT_FN_WRITE 1/g
31s/^#define USB_CFG_IMPLEMENT_FN_READ .*$/#define USB_CFG_IMPLEMENT_FN_READ 1/g
32s/^#define USB_CFG_DEVICE_CLASS .*$/#define USB_CFG_DEVICE_CLASS 0/g
33s/^#define USB_CFG_INTERFACE_CLASS .*$/#define USB_CFG_INTERFACE_CLASS 3/g
34s/^.*#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH.*$/#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 22/g
35p
36EOF
37
38cat << \EOF | sed -n -f /dev/stdin ../custom-class/firmware/Makefile >firmware/Makefile
39/^\( [*] \)\{0,1\}[+].*$/ d
40s/^# Project: .*$/# Project: hid-data example/g
41p
42EOF
43
44cp ../../libs-host/hiddata.[ch] ../../libs-host/hidsdi.h commandline
diff --git a/lib/vusb/examples/hid-mouse/Readme.txt b/lib/vusb/examples/hid-mouse/Readme.txt
new file mode 100644
index 000000000..e0c814281
--- /dev/null
+++ b/lib/vusb/examples/hid-mouse/Readme.txt
@@ -0,0 +1,48 @@
1This is the Readme file for hid-mouse, an example of a USB mouse device. In
2order to have as little dependencies on hardware and architecture as
3possible, mouse movements are computed internally so that the mouse pointer
4moves in a circle.
5
6
7WHAT IS DEMONSTRATED?
8=====================
9This example demonstrates how HID class devices are implemented. The example
10is kept as simple as possible, except the report descriptor which is taken
11from a real-world mouse.
12
13It does NOT include a host side driver because all modern operating systems
14include one. It does NOT implement USBRQ_HID_SET_REPORT and report-IDs. See
15the "hid-data" example for this topic. It does NOT implement any special
16features such as suspend mode etc.
17
18
19PREREQUISITES
20=============
21Target hardware: You need an AVR based circuit based on one of the examples
22(see the "circuits" directory at the top level of this package), e.g. the
23metaboard (http://www.obdev.at/goto.php?t=metaboard).
24
25AVR development environment: You need the gcc tool chain for the AVR, see
26the Prerequisites section in the top level Readme file for how to obtain it.
27
28
29BUILDING THE FIRMWARE
30=====================
31Change to the "firmware" directory and modify Makefile according to your
32architecture (CPU clock, target device, fuse values) and ISP programmer. Then
33edit usbconfig.h according to your pin assignments for D+ and D-. The default
34settings are for the metaboard hardware.
35
36Type "make hex" to build main.hex, then "make flash" to upload the firmware
37to the device. Don't forget to run "make fuse" once to program the fuses. If
38you use a prototyping board with boot loader, follow the instructions of the
39boot loader instead.
40
41Please note that the first "make hex" copies the driver from the top level
42into the firmware directory. If you use a different build system than our
43Makefile, you must copy the driver by hand.
44
45
46----------------------------------------------------------------------------
47(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH.
48http://www.obdev.at/
diff --git a/lib/vusb/examples/hid-mouse/firmware/main.c b/lib/vusb/examples/hid-mouse/firmware/main.c
new file mode 100644
index 000000000..e98673123
--- /dev/null
+++ b/lib/vusb/examples/hid-mouse/firmware/main.c
@@ -0,0 +1,164 @@
1/* Name: main.c
2 * Project: hid-mouse, a very simple HID example
3 * Author: Christian Starkjohann
4 * Creation Date: 2008-04-07
5 * Tabsize: 4
6 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
7 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8 */
9
10/*
11This example should run on most AVRs with only little changes. No special
12hardware resources except INT0 are used. You may have to change usbconfig.h for
13different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or
14at least be connected to INT0 as well.
15
16We use VID/PID 0x046D/0xC00E which is taken from a Logitech mouse. Don't
17publish any hardware using these IDs! This is for demonstration only!
18*/
19
20#include <avr/io.h>
21#include <avr/wdt.h>
22#include <avr/interrupt.h> /* for sei() */
23#include <util/delay.h> /* for _delay_ms() */
24
25#include <avr/pgmspace.h> /* required by usbdrv.h */
26#include "usbdrv.h"
27#include "oddebug.h" /* This is also an example for using debug macros */
28
29/* ------------------------------------------------------------------------- */
30/* ----------------------------- USB interface ----------------------------- */
31/* ------------------------------------------------------------------------- */
32
33PROGMEM const char usbHidReportDescriptor[52] = { /* USB report descriptor, size must match usbconfig.h */
34 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
35 0x09, 0x02, // USAGE (Mouse)
36 0xa1, 0x01, // COLLECTION (Application)
37 0x09, 0x01, // USAGE (Pointer)
38 0xA1, 0x00, // COLLECTION (Physical)
39 0x05, 0x09, // USAGE_PAGE (Button)
40 0x19, 0x01, // USAGE_MINIMUM
41 0x29, 0x03, // USAGE_MAXIMUM
42 0x15, 0x00, // LOGICAL_MINIMUM (0)
43 0x25, 0x01, // LOGICAL_MAXIMUM (1)
44 0x95, 0x03, // REPORT_COUNT (3)
45 0x75, 0x01, // REPORT_SIZE (1)
46 0x81, 0x02, // INPUT (Data,Var,Abs)
47 0x95, 0x01, // REPORT_COUNT (1)
48 0x75, 0x05, // REPORT_SIZE (5)
49 0x81, 0x03, // INPUT (Const,Var,Abs)
50 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
51 0x09, 0x30, // USAGE (X)
52 0x09, 0x31, // USAGE (Y)
53 0x09, 0x38, // USAGE (Wheel)
54 0x15, 0x81, // LOGICAL_MINIMUM (-127)
55 0x25, 0x7F, // LOGICAL_MAXIMUM (127)
56 0x75, 0x08, // REPORT_SIZE (8)
57 0x95, 0x03, // REPORT_COUNT (3)
58 0x81, 0x06, // INPUT (Data,Var,Rel)
59 0xC0, // END_COLLECTION
60 0xC0, // END COLLECTION
61};
62/* This is the same report descriptor as seen in a Logitech mouse. The data
63 * described by this descriptor consists of 4 bytes:
64 * . . . . . B2 B1 B0 .... one byte with mouse button states
65 * X7 X6 X5 X4 X3 X2 X1 X0 .... 8 bit signed relative coordinate x
66 * Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 .... 8 bit signed relative coordinate y
67 * W7 W6 W5 W4 W3 W2 W1 W0 .... 8 bit signed relative coordinate wheel
68 */
69typedef struct{
70 uchar buttonMask;
71 char dx;
72 char dy;
73 char dWheel;
74}report_t;
75
76static report_t reportBuffer;
77static int sinus = 7 << 6, cosinus = 0;
78static uchar idleRate; /* repeat rate for keyboards, never used for mice */
79
80
81/* The following function advances sin/cos by a fixed angle
82 * and stores the difference to the previous coordinates in the report
83 * descriptor.
84 * The algorithm is the simulation of a second order differential equation.
85 */
86static void advanceCircleByFixedAngle(void)
87{
88char d;
89
90#define DIVIDE_BY_64(val) (val + (val > 0 ? 32 : -32)) >> 6 /* rounding divide */
91 reportBuffer.dx = d = DIVIDE_BY_64(cosinus);
92 sinus += d;
93 reportBuffer.dy = d = DIVIDE_BY_64(sinus);
94 cosinus -= d;
95}
96
97/* ------------------------------------------------------------------------- */
98
99usbMsgLen_t usbFunctionSetup(uchar data[8])
100{
101usbRequest_t *rq = (void *)data;
102
103 /* The following requests are never used. But since they are required by
104 * the specification, we implement them in this example.
105 */
106 if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */
107 DBG1(0x50, &rq->bRequest, 1); /* debug output: print our request */
108 if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */
109 /* we only have one report type, so don't look at wValue */
110 usbMsgPtr = (void *)&reportBuffer;
111 return sizeof(reportBuffer);
112 }else if(rq->bRequest == USBRQ_HID_GET_IDLE){
113 usbMsgPtr = &idleRate;
114 return 1;
115 }else if(rq->bRequest == USBRQ_HID_SET_IDLE){
116 idleRate = rq->wValue.bytes[1];
117 }
118 }else{
119 /* no vendor specific requests implemented */
120 }
121 return 0; /* default for not implemented requests: return no data back to host */
122}
123
124/* ------------------------------------------------------------------------- */
125
126int __attribute__((noreturn)) main(void)
127{
128uchar i;
129
130 wdt_enable(WDTO_1S);
131 /* If you don't use the watchdog, replace the call above with a wdt_disable().
132 * On newer devices, the status of the watchdog (on/off, period) is PRESERVED
133 * OVER RESET!
134 */
135 /* RESET status: all port bits are inputs without pull-up.
136 * That's the way we need D+ and D-. Therefore we don't need any
137 * additional hardware initialization.
138 */
139 odDebugInit();
140 DBG1(0x00, 0, 0); /* debug output: main starts */
141 usbInit();
142 usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
143 i = 0;
144 while(--i){ /* fake USB disconnect for > 250 ms */
145 wdt_reset();
146 _delay_ms(1);
147 }
148 usbDeviceConnect();
149 sei();
150 DBG1(0x01, 0, 0); /* debug output: main loop starts */
151 for(;;){ /* main event loop */
152 DBG1(0x02, 0, 0); /* debug output: main loop iterates */
153 wdt_reset();
154 usbPoll();
155 if(usbInterruptIsReady()){
156 /* called after every poll of the interrupt endpoint */
157 advanceCircleByFixedAngle();
158 DBG1(0x03, 0, 0); /* debug output: interrupt report prepared */
159 usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer));
160 }
161 }
162}
163
164/* ------------------------------------------------------------------------- */
diff --git a/lib/vusb/examples/hid-mouse/make-files.sh b/lib/vusb/examples/hid-mouse/make-files.sh
new file mode 100755
index 000000000..3e931c4ee
--- /dev/null
+++ b/lib/vusb/examples/hid-mouse/make-files.sh
@@ -0,0 +1,38 @@
1#!/bin/sh
2# Author: Christian Starkjohann
3# Creation Date: 2008-04-17
4# Tabsize: 4
5# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
6# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
7
8
9if [ "$1" = remove ]; then
10 (cd firmware; make clean)
11 rm -f firmware/usbconfig.h
12 rm -rf firmware/usbdrv
13 rm -f firmware/Makefile
14 exit
15fi
16
17cat << \EOF | sed -n -f /dev/stdin ../../usbdrv/usbconfig-prototype.h >firmware/usbconfig.h
18/^\( [*] \)\{0,1\}[+].*$/ d
19s/^#define USB_CFG_DMINUS_BIT .*$/#define USB_CFG_DMINUS_BIT 4/g
20s|^.*#define USB_CFG_CLOCK_KHZ.*$|#define USB_CFG_CLOCK_KHZ (F_CPU/1000)|g
21s/^#define USB_CFG_HAVE_INTRIN_ENDPOINT .*$/#define USB_CFG_HAVE_INTRIN_ENDPOINT 1/g
22s|^#define USB_CFG_DEVICE_ID .*$|#define USB_CFG_DEVICE_ID 0xe8, 0x03 /* VOTI's lab use PID */|g
23s/^#define USB_CFG_DEVICE_NAME .*$/#define USB_CFG_DEVICE_NAME 'M', 'o', 'u', 's', 'e'/g
24s/^#define USB_CFG_DEVICE_NAME_LEN .*$/#define USB_CFG_DEVICE_NAME_LEN 5/g
25
26s/^#define USB_CFG_INTR_POLL_INTERVAL .*$/#define USB_CFG_INTR_POLL_INTERVAL 100/g
27s/^#define USB_CFG_MAX_BUS_POWER .*$/#define USB_CFG_MAX_BUS_POWER 20/g
28s/^#define USB_CFG_DEVICE_CLASS .*$/#define USB_CFG_DEVICE_CLASS 0/g
29s/^#define USB_CFG_INTERFACE_CLASS .*$/#define USB_CFG_INTERFACE_CLASS 3/g
30s/^.*#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH.*$/#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 52/g
31p
32EOF
33
34cat << \EOF | sed -n -f /dev/stdin ../custom-class/firmware/Makefile >firmware/Makefile
35/^\( [*] \)\{0,1\}[+].*$/ d
36s/^# Project: .*$/# Project: hid-mouse example/g
37p
38EOF
diff --git a/lib/vusb/examples/usbtool/Makefile b/lib/vusb/examples/usbtool/Makefile
new file mode 100644
index 000000000..1f2a8ab81
--- /dev/null
+++ b/lib/vusb/examples/usbtool/Makefile
@@ -0,0 +1,47 @@
1# Name: Makefile
2# Project: usbtool
3# Author: Christian Starkjohann
4# Creation Date: 2008-04-06
5# Tabsize: 4
6# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
7# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8
9
10# Concigure the following definitions according to your system.
11# This Makefile has been tested on Mac OS X, Linux and Windows.
12
13# Use the following 3 lines on Unix (uncomment the framework on Mac OS X):
14USBFLAGS = `libusb-config --cflags`
15USBLIBS = `libusb-config --libs`
16EXE_SUFFIX =
17
18# Use the following 3 lines on Windows and comment out the 3 above. You may
19# have to change the include paths to where you installed libusb-win32
20#USBFLAGS = -I/usr/local/include
21#USBLIBS = -L/usr/local/lib -lusb
22#EXE_SUFFIX = .exe
23
24NAME = usbtool
25
26OBJECTS = opendevice.o $(NAME).o
27
28CC = gcc
29CFLAGS = $(CPPFLAGS) $(USBFLAGS) -O -g -Wall
30LIBS = $(USBLIBS)
31
32PROGRAM = $(NAME)$(EXE_SUFFIX)
33
34
35all: $(PROGRAM)
36
37.c.o:
38 $(CC) $(CFLAGS) -c $<
39
40$(PROGRAM): $(OBJECTS)
41 $(CC) -o $(PROGRAM) $(OBJECTS) $(LIBS)
42
43strip: $(PROGRAM)
44 strip $(PROGRAM)
45
46clean:
47 rm -f *.o $(PROGRAM)
diff --git a/lib/vusb/examples/usbtool/Makefile.windows b/lib/vusb/examples/usbtool/Makefile.windows
new file mode 100644
index 000000000..8298dd3b1
--- /dev/null
+++ b/lib/vusb/examples/usbtool/Makefile.windows
@@ -0,0 +1,17 @@
1# Name: Makefile.windows
2# Project: usbtool
3# Author: Christian Starkjohann
4# Creation Date: 2008-04-06
5# Tabsize: 4
6# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
7# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8
9# You may use this file with
10# make -f Makefile.windows
11# on Windows with MinGW instead of editing the main Makefile.
12
13include Makefile
14
15USBFLAGS = -I/usr/local/mingw/include
16USBLIBS = -L/usr/local/mingw/lib -lusb
17EXE_SUFFIX = .exe
diff --git a/lib/vusb/examples/usbtool/Readme.txt b/lib/vusb/examples/usbtool/Readme.txt
new file mode 100644
index 000000000..33f527cc4
--- /dev/null
+++ b/lib/vusb/examples/usbtool/Readme.txt
@@ -0,0 +1,209 @@
1This is the Readme file for usbtool, a general purpose command line utility
2which can send USB requests to arbitrary devices. Usbtool is based on libusb.
3
4
5WHAT IS USBTOOL GOOD FOR?
6=========================
7When you implement a communication protocol like USB, you must usually write
8two programs: one on each end of the communication. For USB, this means that
9you must write a firmware for the device and driver software for the host.
10
11Usbtool can save you the work of writing the host software, at least during
12firmware development and testing. Usbtool can send control-in and -out
13requests to arbitrary devices and send and receive data on interrupt- and
14bulk-endpoints.
15
16Usbtool is not only a useful developer tool, it's also an example for using
17libusb for communication with the device.
18
19
20SYNOPSIS
21========
22 usbtool [options] <command>
23
24
25COMMANDS
26========
27 list
28 This command prints a list of devices found on all available USB busses.
29 Options -v, -V, -p and -P can be used to filter the list.
30
31 control in|out <type> <recipient> <request> <value> <index>
32 Sends a control-in or control-out request to the device. The request
33 parameters are:
34 type ........ Type of request, can be "standard", "class", "vendor" or
35 "reserved". The type determines which software module in
36 the device is responsible for answering the request:
37 Standard requests are answered by the driver, class
38 requests by the class implementation (e.g. HID, CDC) and
39 vendor requests by custom code.
40 recipient ... Recipient of the request in the device. Can be "device",
41 "interface", "endpoint" or "other". For standard and
42 class requests, the specification defines a recipient for
43 each request. For vendor requests, choose whatever your
44 code expects.
45 request ..... 8 bit numeric value identifying the request.
46 value ....... 16 bit numeric value passed to the device.
47 index ....... another 16 bit numeric value passed to the device.
48 Use options -v, -V, -p and -P to single out a particular device. Use
49 options -d or -D to to send data in an OUT request. Use options -n, -O
50 and -b to determine what to do with data received in an IN request.
51
52 interrupt in|out
53 Sends or receives data on an interrupt-out resp. -in endpoint.
54 Use options -v, -V, -p and -P to single out a particular device. Use
55 options -d or -D to to send data to an OUT endpoint. Use options -n, -O
56 and -b to determine what to do with data received from an IN endpoint.
57 Use option -e to set the endpoint number, -c to choose a configuration
58 -i to claim a particular interface.
59
60 bulk in|out
61 Same as "interrupt in" and "interrupt out", but for bulk endpoints.
62
63
64OPTIONS
65=======
66Most options have already been mentioned at the commands which use them.
67here is a complete list:
68
69 -h or -?
70 Prints a short help.
71
72 -v <vendor-id>
73 Numeric vendor ID, can be "*" to allow any VID. Take only devices with
74 matching vendor ID into account.
75
76 -p <product-id>
77 Numeric product ID, can be "*" to allow any PID. Take only devices with
78 matching product ID into account.
79
80 -V <vendor-name-pattern>
81 Shell style matching pattern for vendor name. Take only devices into
82 account which have a vendor name that matches this pattern.
83
84 -P <product-name-pattern>
85 Shell style matching pattern for product name. Take only devices into
86 account which have a product name that matches this pattern.
87
88 -S <serial-pattern>
89 Shell style matching pattern for serial number. Take only devices into
90 account which have a serial number that matches this pattern.
91
92 -d <databytes>
93 Data bytes to send to the device, comma separated list of numeric values.
94 E.g.: "1,2,3,4,5".
95
96 -D <file>
97 Binary data sent to the device should be taken from this file.
98
99 -O <file>
100 Write received data bytes to the given file. Format is either hex or
101 binary, depending on the -b flag. By default, received data is printed
102 to standard output.
103
104 -b
105 Request binary output format for files and standard output. Default is
106 a hexadecimal listing.
107
108 -n <count>
109 Numeric value: Maximum number of bytes to receive. This value is passed
110 directly to the libusb API functions.
111
112 -e <endpoint>
113 Numeric value: Endpoint number for interrupt and bulk commands.
114
115 -t <timeout>
116 Numeric value: Timeout in milliseconds for the request. This value is
117 passed directly to the libusb API functions.
118
119 -c <configuration>
120 Numeric value: Interrupt and bulk endpoints can usually only be used if
121 a configuration and an interface has been chosen. Use -c and -i to
122 specify configuration and interface values.
123
124 -i <interface>
125 Numeric value: Interrupt and bulk endpoints can usually only be used if
126 a configuration and an interface has been chosen. Use -c and -i to
127 specify configuration and interface values.
128
129 -w
130 Usbtool may be too verbose with warnings for some applications. Use this
131 option to suppress USB warnings.
132
133
134NUMERIC VALUES
135==============
136All numeric values can be given in hexadecimal, decimal or octal. Hex values
137are identified by their 0x or 0X prefix, octal values by a leading "0" (the
138digit zero) and decimal values because they start with a non-zero digit. An
139optional sign character is allowed. The special value "*" is translated to
140zero and stands for "any value" in some contexts.
141
142
143SHELL STYLE MATCHING PATTERNS
144=============================
145Some options take shell style matching patterns as an argument. This refers
146to Unix shells and their file wildcard operations:
147 + "*" (asterisk character) matches any number (0 to infinite) of any
148 characters.
149 + "?" matches exactly one arbitrary character.
150 + A list of characters in square brackets (e.g. "[abc]") matches any of the
151 characters in the list. If a dash ("-") is in the list, it must be the
152 first or the last character. If a caret ("^") is in the list, it must
153 not be the first character. A closing square bracket ("]") must be the
154 first character in the list. A range of characters can be specified in
155 the way "[a-z]". This matches all characters with numeric representation
156 (usually ASCII) starting with "a" and ending with "z". The entire
157 construct matches only one character.
158 + A list of characters in square brackets starting with a caret ("^"), e.g.
159 ("[^abc]") matches any character NOT in the list. The other rules are as
160 above.
161 + "\" (backslash) followed by any character matches that following
162 character. This can be used to escape "*", "?", "[" and "\".
163
164
165BUILDING USBTOOL
166================
167Usbtool uses libusb on Unix and libusb-win32 on Windows. These libraries can
168be obtained from http://libusb.sourceforge.net/ and
169http://libusb-win32.sourceforge.net/ respectively. On Unix, a simple "make"
170should compile the sources (although you may have to edit Makefile to
171include or remove additional libraries). On Windows, we recommend that you
172use MinGW and MSYS. See the top level Readme file for details. Edit
173Makefile.windows according to your library installation paths and build with
174"make -f Makefile.windows".
175
176
177EXAMPLES
178========
179To list all devices connected to your computer, do
180
181 usbtool -w list
182
183To check whether our selection options single out the desired device, use eg.
184
185 usbtool -w -P LEDControl list
186
187This command shows all LEDControl devices connected or prints nothing if
188none is found. LEDControl is the device from the "custom-class" example.
189
190You can also send commands to the LEDControl device using usbtool. From
191the file requests.h in custom-class/firmware, we know that the set-status
192request has numeric value 1 and the get-status request is 2. See this file
193for details of the protocol used. We can therefore query the status with
194
195 usbtool -w -P LEDControl control in vendor device 2 0 0
196
197This command prints 0x00 if the LED is off or 0x01 if it is on. To turn the
198LED on, use
199
200 usbtool -w -P LEDControl control out vendor device 1 1 0
201
202and to turn it off, use
203
204 usbtool -w -P LEDControl control out vendor device 1 0 0
205
206
207----------------------------------------------------------------------------
208(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH.
209http://www.obdev.at/
diff --git a/lib/vusb/examples/usbtool/make-files.sh b/lib/vusb/examples/usbtool/make-files.sh
new file mode 100755
index 000000000..8519514a8
--- /dev/null
+++ b/lib/vusb/examples/usbtool/make-files.sh
@@ -0,0 +1,15 @@
1#!/bin/sh
2# Author: Christian Starkjohann
3# Creation Date: 2008-04-17
4# Tabsize: 4
5# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
6# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
7
8
9if [ "$1" = remove ]; then
10 make clean
11 rm -f opendevice.[ch]
12 exit
13fi
14
15cp ../../libs-host/opendevice.[ch] .
diff --git a/lib/vusb/examples/usbtool/usbtool.c b/lib/vusb/examples/usbtool/usbtool.c
new file mode 100644
index 000000000..56bdac109
--- /dev/null
+++ b/lib/vusb/examples/usbtool/usbtool.c
@@ -0,0 +1,355 @@
1/* Name: usbtool.c
2 * Project: V-USB examples, host side
3 * Author: Christian Starkjohann
4 * Creation Date: 2008-04-06
5 * Tabsize: 4
6 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
7 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8 */
9
10/*
11General Description:
12This command line tool can perform various USB requests at arbitrary
13USB devices. It is intended as universal host side tool for experimentation
14and debugging purposes. It must be linked with libusb, a library for accessing
15the USB bus from Linux, FreeBSD, Mac OS X and other Unix operating systems.
16Libusb can be obtained from http://libusb.sourceforge.net/.
17On Windows use libusb-win32 from http://libusb-win32.sourceforge.net/.
18*/
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <unistd.h>
24#include <stdarg.h>
25#include <ctype.h>
26#include <errno.h>
27
28#include <usb.h> /* this is libusb, see http://libusb.sourceforge.net/ */
29#include "opendevice.h" /* common code moved to separate module */
30
31#define DEFAULT_USB_VID 0 /* any */
32#define DEFAULT_USB_PID 0 /* any */
33
34static void usage(char *name)
35{
36 fprintf(stderr, "usage: %s [options] <command>\n", name);
37 fprintf(stderr,
38 "Options are:\n"
39 " -h or -? (print this help and exit)\n"
40 " -v <vendor-id> (defaults to 0x%x, can be '*' for any VID)\n"
41 " -p <product-id> (defaults to 0x%x, can be '*' for any PID)\n"
42 " -V <vendor-name-pattern> (shell style matching, defaults to '*')\n"
43 " -P <product-name-pattern> (shell style matching, defaults to '*')\n"
44 " -S <serial-pattern> (shell style matching, defaults to '*')\n"
45 " -d <databytes> (data byte for request, comma separated list)\n"
46 " -D <file> (binary data for request taken from file)\n"
47 " -O <file> (write received data bytes to file)\n"
48 " -b (binary output format, default is hex)\n"
49 " -n <count> (maximum number of bytes to receive)\n"
50 " -e <endpoint> (specify endpoint for some commands)\n"
51 " -t <timeout> (specify USB timeout in milliseconds)\n"
52 " -c <configuration> (device configuration to choose)\n"
53 " -i <interface> (configuration interface to claim)\n"
54 " -w (suppress USB warnings, default is verbose)\n"
55 "\n"
56 "Commands are:\n"
57 " list (list all matching devices by name)\n"
58 " control in|out <type> <recipient> <request> <value> <index> (send control request)\n"
59 " interrupt in|out (send or receive interrupt data)\n"
60 " bulk in|out (send or receive bulk data)\n"
61 "For valid enum values for <type> and <recipient> pass \"x\" for the value.\n"
62 "Objective Development's free VID/PID pairs are:\n"
63 " 5824/1500 for vendor class devices\n"
64 " 5824/1503 for HID class devices excluding mice and keyboards\n"
65 " 5824/1505 for CDC-ACM class devices\n"
66 " 5824/1508 for MIDI class devices\n"
67 , DEFAULT_USB_VID, DEFAULT_USB_PID
68 );
69
70
71}
72
73static int vendorID = DEFAULT_USB_VID;
74static int productID = DEFAULT_USB_PID;
75static char *vendorNamePattern = "*";
76static char *productNamePattern = "*";
77static char *serialPattern = "*";
78static char *sendBytes = NULL;
79static int sendByteCount;
80static char *outputFile = NULL;
81static int endpoint = 0;
82static int outputFormatIsBinary = 0;
83static int showWarnings = 1;
84static int usbTimeout = 5000;
85static int usbCount = 128;
86static int usbConfiguration = 1;
87static int usbInterface = 0;
88
89static int usbDirection, usbType, usbRecipient, usbRequest, usbValue, usbIndex; /* arguments of control transfer */
90
91/* ------------------------------------------------------------------------- */
92
93/* ASCII to integer (number parsing) which allows hex (0x prefix),
94 * octal (0 prefix) and decimal (1-9 prefix) input.
95 */
96static int myAtoi(char *text)
97{
98long l;
99char *endPtr;
100
101 if(strcmp(text, "*") == 0)
102 return 0;
103 l = strtol(text, &endPtr, 0);
104 if(endPtr == text){
105 fprintf(stderr, "warning: can't parse numeric parameter ->%s<-, defaults to 0.\n", text);
106 l = 0;
107 }else if(*endPtr != 0){
108 fprintf(stderr, "warning: numeric parameter ->%s<- only partially parsed.\n", text);
109 }
110 return l;
111}
112
113static int parseEnum(char *text, ...)
114{
115va_list vlist;
116char *entries[64];
117int i, numEntries;
118
119 va_start(vlist, text);
120 for(i = 0; i < 64; i++){
121 entries[i] = va_arg(vlist, char *);
122 if(entries[i] == NULL)
123 break;
124 }
125 numEntries = i;
126 va_end(vlist);
127 for(i = 0; i < numEntries; i++){
128 if(strcasecmp(text, entries[i]) == 0)
129 return i;
130 }
131 if(isdigit(*text)){
132 return myAtoi(text);
133 }
134 fprintf(stderr, "Enum value \"%s\" not allowed. Allowed values are:\n", text);
135 for(i = 0; i < numEntries; i++){
136 fprintf(stderr, " %s\n", entries[i]);
137 }
138 exit(1);
139}
140
141/* ------------------------------------------------------------------------- */
142
143#define ACTION_LIST 0
144#define ACTION_CONTROL 1
145#define ACTION_INTERRUPT 2
146#define ACTION_BULK 3
147
148int main(int argc, char **argv)
149{
150usb_dev_handle *handle = NULL;
151int opt, len, action, argcnt;
152char *myName = argv[0], *s, *rxBuffer = NULL;
153FILE *fp;
154
155 while((opt = getopt(argc, argv, "?hv:p:V:P:S:d:D:O:e:n:tbw")) != -1){
156 switch(opt){
157 case 'h':
158 case '?': /* -h or -? (print this help and exit) */
159 usage(myName);
160 exit(1);
161 case 'v': /* -v <vendor-id> (defaults to 0x%x, can be '*' for any VID) */
162 vendorID = myAtoi(optarg);
163 break;
164 case 'p': /* -p <product-id> (defaults to 0x%x, can be '*' for any PID) */
165 productID = myAtoi(optarg);
166 break;
167 case 'V': /* -V <vendor-name-pattern> (shell style matching, defaults to '*') */
168 vendorNamePattern = optarg;
169 break;
170 case 'P': /* -P <product-name-pattern> (shell style matching, defaults to '*') */
171 productNamePattern = optarg;
172 break;
173 case 'S': /* -S <serial-pattern> (shell style matching, defaults to '*') */
174 serialPattern = optarg;
175 break;
176 case 'd': /* -d <databytes> (data bytes for requests given on command line) */
177 while((s = strtok(optarg, ", ")) != NULL){
178 optarg = NULL;
179 if(sendBytes != NULL){
180 sendBytes = realloc(sendBytes, sendByteCount + 1);
181 }else{
182 sendBytes = malloc(sendByteCount + 1);
183 }
184 sendBytes[sendByteCount++] = myAtoi(s);
185 }
186 break;
187 case 'D': /* -D <file> (data bytes for request taken from file) */
188 if((fp = fopen(optarg, "rb")) == NULL){
189 fprintf(stderr, "error opening %s: %s\n", optarg, strerror(errno));
190 exit(1);
191 }
192 fseek(fp, 0, SEEK_END);
193 len = ftell(fp);
194 fseek(fp, 0, SEEK_SET);
195 if(sendBytes != NULL){
196 sendBytes = realloc(sendBytes, sendByteCount + len);
197 }else{
198 sendBytes = malloc(sendByteCount + len);
199 }
200 fread(sendBytes + sendByteCount, 1, len, fp); /* would need error checking */
201 sendByteCount += len;
202 fclose(fp);
203 break;
204 case 'O': /* -O <file> (write received data bytes to file) */
205 outputFile = optarg;
206 break;
207 case 'e': /* -e <endpoint> (specify endpoint for some commands) */
208 endpoint = myAtoi(optarg);
209 break;
210 case 't': /* -t <timeout> (specify USB timeout in milliseconds) */
211 usbTimeout = myAtoi(optarg);
212 break;
213 case 'b': /* -b (binary output format, default is hex) */
214 outputFormatIsBinary = 1;
215 break;
216 case 'n': /* -n <count> (maximum number of bytes to receive) */
217 usbCount = myAtoi(optarg);
218 break;
219 case 'c': /* -c <configuration> (device configuration to choose) */
220 usbConfiguration = myAtoi(optarg);
221 break;
222 case 'i': /* -i <interface> (configuration interface to claim) */
223 usbInterface = myAtoi(optarg);
224 break;
225 case 'w': /* -w (suppress USB warnings, default is verbose) */
226 showWarnings = 0;
227 break;
228 default:
229 fprintf(stderr, "Option -%c unknown\n", opt);
230 exit(1);
231 }
232 }
233 argc -= optind;
234 argv += optind;
235 if(argc < 1){
236 usage(myName);
237 exit(1);
238 }
239 argcnt = 2;
240 if(strcasecmp(argv[0], "list") == 0){
241 action = ACTION_LIST;
242 argcnt = 1;
243 }else if(strcasecmp(argv[0], "control") == 0){
244 action = ACTION_CONTROL;
245 argcnt = 7;
246 }else if(strcasecmp(argv[0], "interrupt") == 0){
247 action = ACTION_INTERRUPT;
248 }else if(strcasecmp(argv[0], "bulk") == 0){
249 action = ACTION_BULK;
250 }else{
251 fprintf(stderr, "command %s not known\n", argv[0]);
252 usage(myName);
253 exit(1);
254 }
255 if(argc < argcnt){
256 fprintf(stderr, "Not enough arguments.\n");
257 usage(myName);
258 exit(1);
259 }
260 if(argc > argcnt){
261 fprintf(stderr, "Warning: only %d arguments expected, rest ignored.\n", argcnt);
262 }
263 usb_init();
264 if(usbOpenDevice(&handle, vendorID, vendorNamePattern, productID, productNamePattern, serialPattern, action == ACTION_LIST ? stdout : NULL, showWarnings ? stderr : NULL) != 0){
265 fprintf(stderr, "Could not find USB device with VID=0x%x PID=0x%x Vname=%s Pname=%s Serial=%s\n", vendorID, productID, vendorNamePattern, productNamePattern, serialPattern);
266 exit(1);
267 }
268 if(action == ACTION_LIST)
269 exit(0); /* we've done what we were asked to do already */
270 usbDirection = parseEnum(argv[1], "out", "in", NULL);
271 if(usbDirection){ /* IN transfer */
272 rxBuffer = malloc(usbCount);
273 }
274 if(action == ACTION_CONTROL){
275 int requestType;
276 usbType = parseEnum(argv[2], "standard", "class", "vendor", "reserved", NULL);
277 usbRecipient = parseEnum(argv[3], "device", "interface", "endpoint", "other", NULL);
278 usbRequest = myAtoi(argv[4]);
279 usbValue = myAtoi(argv[5]);
280 usbIndex = myAtoi(argv[6]);
281 requestType = ((usbDirection & 1) << 7) | ((usbType & 3) << 5) | (usbRecipient & 0x1f);
282 if(usbDirection){ /* IN transfer */
283 len = usb_control_msg(handle, requestType, usbRequest, usbValue, usbIndex, rxBuffer, usbCount, usbTimeout);
284 }else{ /* OUT transfer */
285 len = usb_control_msg(handle, requestType, usbRequest, usbValue, usbIndex, sendBytes, sendByteCount, usbTimeout);
286 }
287 }else{ /* must be ACTION_INTERRUPT or ACTION_BULK */
288 int retries = 1;
289 if(usb_set_configuration(handle, usbConfiguration) && showWarnings){
290 fprintf(stderr, "Warning: could not set configuration: %s\n", usb_strerror());
291 }
292 /* now try to claim the interface and detach the kernel HID driver on
293 * linux and other operating systems which support the call.
294 */
295 while((len = usb_claim_interface(handle, usbInterface)) != 0 && retries-- > 0){
296#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
297 if(usb_detach_kernel_driver_np(handle, 0) < 0 && showWarnings){
298 fprintf(stderr, "Warning: could not detach kernel driver: %s\n", usb_strerror());
299 }
300#endif
301 }
302 if(len != 0 && showWarnings)
303 fprintf(stderr, "Warning: could not claim interface: %s\n", usb_strerror());
304 if(action == ACTION_INTERRUPT){
305 if(usbDirection){ /* IN transfer */
306 len = usb_interrupt_read(handle, endpoint, rxBuffer, usbCount, usbTimeout);
307 }else{
308 len = usb_interrupt_write(handle, endpoint, sendBytes, sendByteCount, usbTimeout);
309 }
310 }else{
311 if(usbDirection){ /* IN transfer */
312 len = usb_bulk_read(handle, endpoint, rxBuffer, usbCount, usbTimeout);
313 }else{
314 len = usb_bulk_write(handle, endpoint, sendBytes, sendByteCount, usbTimeout);
315 }
316 }
317 }
318 if(len < 0){
319 fprintf(stderr, "USB error: %s\n", usb_strerror());
320 exit(1);
321 }
322 if(usbDirection == 0) /* OUT */
323 printf("%d bytes sent.\n", len);
324 if(rxBuffer != NULL){
325 FILE *fp = stdout;
326 if(outputFile != NULL){
327 fp = fopen(outputFile, outputFormatIsBinary ? "wb" : "w");
328 if(fp == NULL){
329 fprintf(stderr, "Error writing \"%s\": %s\n", outputFile, strerror(errno));
330 exit(1);
331 }
332 }
333 if(outputFormatIsBinary){
334 fwrite(rxBuffer, 1, len, fp);
335 }else{
336 int i;
337 for(i = 0; i < len; i++){
338 if(i != 0){
339 if(i % 16 == 0){
340 fprintf(fp, "\n");
341 }else{
342 fprintf(fp, " ");
343 }
344 }
345 fprintf(fp, "0x%02x", rxBuffer[i] & 0xff);
346 }
347 if(i != 0)
348 fprintf(fp, "\n");
349 }
350 }
351 usb_close(handle);
352 if(rxBuffer != NULL)
353 free(rxBuffer);
354 return 0;
355}
diff --git a/lib/vusb/libs-device/Readme.txt b/lib/vusb/libs-device/Readme.txt
new file mode 100644
index 000000000..76518dc90
--- /dev/null
+++ b/lib/vusb/libs-device/Readme.txt
@@ -0,0 +1,22 @@
1This is the Readme file for the libs-device directory. This directory contains
2code snippets which may be useful for USB device firmware.
3
4
5WHAT IS INCLUDED IN THIS DIRECTORY?
6===================================
7
8osccal.c and osccal.h
9 This module contains a function which calibrates the AVR's built-in RC
10 oscillator based on the USB frame clock. See osccal.h for a documentation
11 of the API.
12
13osctune.h
14 This header file contains a code snippet for usbconfig.h. With this code,
15 you can keep the AVR's internal RC oscillator in sync with the USB frame
16 clock. This is a continuous synchronization, not a single calibration at
17 USB reset as with osccal.c above. Please note that this code works only
18 if D- is wired to the interrupt, not D+.
19
20----------------------------------------------------------------------------
21(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH.
22http://www.obdev.at/
diff --git a/lib/vusb/libs-device/osccal.c b/lib/vusb/libs-device/osccal.c
new file mode 100644
index 000000000..ea170ec66
--- /dev/null
+++ b/lib/vusb/libs-device/osccal.c
@@ -0,0 +1,68 @@
1/* Name: osccal.c
2 * Author: Christian Starkjohann
3 * Creation Date: 2008-04-10
4 * Tabsize: 4
5 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
6 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
7 */
8
9#include <avr/io.h>
10
11#ifndef uchar
12#define uchar unsigned char
13#endif
14
15/* ------------------------------------------------------------------------- */
16/* ------------------------ Oscillator Calibration ------------------------- */
17/* ------------------------------------------------------------------------- */
18
19/* This is a "C" implementation. You can customize it to your needs easily.
20 * If you want smaller code size, there is an improved version in the
21 * micronucleous project. See
22 * https://github.com/micronucleus/micronucleus/blob/master/firmware/osccalASM.S
23 */
24
25/* Calibrate the RC oscillator. Our timing reference is the Start Of Frame
26 * signal (a single SE0 bit) repeating every millisecond immediately after
27 * a USB RESET. We first do a binary search for the OSCCAL value and then
28 * optimize this value with a neighboorhod search.
29 */
30void calibrateOscillator(void)
31{
32uchar step = 128;
33uchar trialValue = 0, optimumValue;
34int x, optimumDev, targetValue = (unsigned)(1499 * (double)F_CPU / 10.5e6 + 0.5);
35
36 /* do a binary search: */
37 do{
38 OSCCAL = trialValue + step;
39 x = usbMeasureFrameLength(); /* proportional to current real frequency */
40 if(x < targetValue) /* frequency still too low */
41 trialValue += step;
42 step >>= 1;
43 }while(step > 0);
44 /* We have a precision of +/- 1 for optimum OSCCAL here */
45 /* now do a neighborhood search for optimum value */
46 optimumValue = trialValue;
47 optimumDev = x; /* this is certainly far away from optimum */
48 for(OSCCAL = trialValue - 1; OSCCAL <= trialValue + 1; OSCCAL++){
49 x = usbMeasureFrameLength() - targetValue;
50 if(x < 0)
51 x = -x;
52 if(x < optimumDev){
53 optimumDev = x;
54 optimumValue = OSCCAL;
55 }
56 }
57 OSCCAL = optimumValue;
58}
59/*
60Note: This calibration algorithm may try OSCCAL values of up to 192 even if
61the optimum value is far below 192. It may therefore exceed the allowed clock
62frequency of the CPU in low voltage designs!
63You may replace this search algorithm with any other algorithm you like if
64you have additional constraints such as a maximum CPU clock.
65For version 5.x RC oscillators (those with a split range of 2x128 steps, e.g.
66ATTiny25, ATTiny45, ATTiny85), it may be useful to search for the optimum in
67both regions.
68*/
diff --git a/lib/vusb/libs-device/osccal.h b/lib/vusb/libs-device/osccal.h
new file mode 100644
index 000000000..1ed600697
--- /dev/null
+++ b/lib/vusb/libs-device/osccal.h
@@ -0,0 +1,62 @@
1/* Name: osccal.h
2 * Author: Christian Starkjohann
3 * Creation Date: 2008-04-10
4 * Tabsize: 4
5 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
6 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
7 */
8
9/*
10General Description:
11This module contains a function which calibrates the AVR's internal RC
12oscillator so that the CPU runs at F_CPU (F_CPU is a macro which must be
13defined when the module is compiled, best passed in the compiler command
14line). The time reference is the USB frame clock of 1 kHz available
15immediately after a USB RESET condition. Timing is done by counting CPU
16cycles, so all interrupts must be disabled while the calibration runs. For
17low level timing measurements, usbMeasureFrameLength() is called. This
18function must be enabled in usbconfig.h by defining
19USB_CFG_HAVE_MEASURE_FRAME_LENGTH to 1. It is recommended to call
20calibrateOscillator() from the reset hook in usbconfig.h:
21
22#ifndef __ASSEMBLER__
23#include <avr/interrupt.h> // for sei()
24extern void calibrateOscillator(void);
25#endif
26#define USB_RESET_HOOK(resetStarts) if(!resetStarts){cli(); calibrateOscillator(); sei();}
27
28This routine is an alternative to the continuous synchronization described
29in osctune.h.
30
31Algorithm used:
32calibrateOscillator() first does a binary search in the OSCCAL register for
33the best matching oscillator frequency. Then it does a next neighbor search
34to find the value with the lowest clock rate deviation. It is guaranteed to
35find the best match among neighboring values, but for version 5 oscillators
36(which have a discontinuous relationship between OSCCAL and frequency) a
37better match might be available in another OSCCAL region.
38
39Limitations:
40This calibration algorithm may try OSCCAL values of up to 192 even if the
41optimum value is far below 192. It may therefore exceed the allowed clock
42frequency of the CPU in low voltage designs!
43Precision depends on the OSCCAL vs. frequency dependency of the oscillator.
44Typical precision for an ATMega168 (derived from the OSCCAL vs. F_RC diagram
45in the data sheet) should be in the range of 0.4%. Only the 12.8 MHz and
4616.5 MHz versions of V-USB (with built-in receiver PLL) can tolerate this
47deviation! All other frequency modules require at least 0.2% precision.
48*/
49
50#ifndef __OSCCAL_H_INCLUDED__
51#define __OSCCAL_H_INCLUDED__
52
53void calibrateOscillator(void);
54/* This function calibrates the RC oscillator so that the CPU runs at F_CPU.
55 * It MUST be called immediately after the end of a USB RESET condition!
56 * Disable all interrupts during the call!
57 * It is recommended that you store the resulting value in EEPROM so that a
58 * good guess value is available after the next reset.
59 */
60
61
62#endif /* __OSCCAL_H_INCLUDED__ */
diff --git a/lib/vusb/libs-device/osctune.h b/lib/vusb/libs-device/osctune.h
new file mode 100644
index 000000000..12961e504
--- /dev/null
+++ b/lib/vusb/libs-device/osctune.h
@@ -0,0 +1,87 @@
1/* Name: osctune.h
2 * Author: Christian Starkjohann
3 * Creation Date: 2008-10-18
4 * Tabsize: 4
5 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
6 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
7 */
8
9/*
10General Description:
11This file is declared as C-header file although it is mostly documentation
12how the RC oscillator can be kept in sync to the USB frame rate. The code
13shown here must be added to usbconfig.h or this header file is included from
14there. This code works only if D- is wired to the interrupt, not D+!!!
15
16This is an alternative to the osccal routine in osccal.c. It has the advantage
17that the synchronization is done continuously and that it has more compact
18code size. The disadvantages are slow synchronization (it may take a while
19until the driver works), that messages immediately after the SOF pulse may be
20lost (and need to be retried by the host) and that the interrupt is on D-
21contrary to most examples.
22
23You may want to store a good calibration value in EEPROM for the next startup.
24You know that the calibration value is good when the first USB message is
25received. Do not store the value on every received message because the EEPROM
26has a limited endurance.
27
28Notes:
29(*) You must declare the global character variable "lastTimer0Value" in your
30main code.
31
32(*) Timer 0 must be free running (not written by your code) and the prescaling
33must be consistent with the TIMER0_PRESCALING define.
34
35(*) Good values for Timer 0 prescaling depend on how precise the clock must
36be tuned and how far away from the default clock rate the target clock is.
37For precise tuning, choose a low prescaler factor, for a broad range of tuning
38choose a high one. A prescaler factor of 64 is good for the entire OSCCAL
39range and allows a precision of better than +/-1%. A prescaler factor of 8
40allows tuning to slightly more than +/-6% of the default frequency and is
41more precise than one step of OSCCAL. It is therefore not suitable to tune an
428 MHz oscillator to 12.5 MHz.
43
44Thanks to Henrik Haftmann for the idea to this routine!
45*/
46
47#define TIMER0_PRESCALING 64 /* must match the configuration for TIMER0 in main */
48#define TOLERATED_DEVIATION_PPT 5 /* max clock deviation before we tune in 1/10 % */
49/* derived constants: */
50#define EXPECTED_TIMER0_INCREMENT ((F_CPU / (1000 * TIMER0_PRESCALING)) & 0xff)
51#define TOLERATED_DEVIATION (TOLERATED_DEVIATION_PPT * F_CPU / (1000000 * TIMER0_PRESCALING))
52
53#ifdef __ASSEMBLER__
54macro tuneOsccal
55 push YH ;[0]
56 in YL, TCNT0 ;[2]
57 lds YH, lastTimer0Value ;[3]
58 sts lastTimer0Value, YL ;[5]
59 sub YL, YH ;[7] time passed since last frame
60 subi YL, EXPECTED_TIMER0_INCREMENT ;[8]
61#if OSCCAL > 0x3f /* outside I/O addressable range */
62 lds YH, OSCCAL ;[6]
63#else
64 in YH, OSCCAL ;[6] assembler modle uses __SFR_OFFSET == 0
65#endif
66 cpi YL, TOLERATED_DEVIATION + 1 ;[10]
67 brmi notTooHigh ;[11]
68 subi YH, 1 ;[12] clock rate was too high
69; brcs tuningOverflow ; optionally check for overflow
70 rjmp osctuneDone ;[13]
71notTooHigh:
72 cpi YL, -TOLERATED_DEVIATION ;[13]
73 brpl osctuneDone ;[14] not too low
74 inc YH ;[15] clock rate was too low
75; breq tuningOverflow ; optionally check for overflow
76osctuneDone:
77#if OSCCAL > 0x3f /* outside I/O addressable range */
78 sts OSCCAL, YH ;[12-13] store tuned value
79#else
80 out OSCCAL, YH ;[12-13] store tuned value
81#endif
82tuningOverflow:
83 pop YH ;[17]
84 endm ;[19] max number of cycles
85#endif
86
87#define USB_SOF_HOOK tuneOsccal
diff --git a/lib/vusb/libs-host/Readme.txt b/lib/vusb/libs-host/Readme.txt
new file mode 100644
index 000000000..5117d18f7
--- /dev/null
+++ b/lib/vusb/libs-host/Readme.txt
@@ -0,0 +1,26 @@
1This is the Readme file for the libs-host directory. This directory contains
2code snippets which may be useful for host side USB software.
3
4
5WHAT IS INCLUDED IN THIS DIRECTORY?
6===================================
7
8opendevice.c and opendevice.h
9 This module contains a function to find and open a device given its
10 numeric IDs (VID, PID), names (vendor name and product name) and serial
11 number. It is based on libusb/libusb-win32 and returns a libusb device
12 handle. See opendevice.h for an API documentation.
13
14hiddata.c and hiddata.h
15 This module contains functions for data transfer over HID feature reports.
16 It is based on libusb on Unix and native Windows functions on Windows. No
17 driver DLL is needed on Windows. See hiddata.h for an API documentation.
18
19hidsdi.h
20 This DDK header file is missing in the free MinGW version of the Windows
21 DDK. Use this version if you get an "include file not found" error.
22
23
24----------------------------------------------------------------------------
25(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH.
26http://www.obdev.at/
diff --git a/lib/vusb/libs-host/hiddata.c b/lib/vusb/libs-host/hiddata.c
new file mode 100644
index 000000000..203ed19d6
--- /dev/null
+++ b/lib/vusb/libs-host/hiddata.c
@@ -0,0 +1,323 @@
1/* Name: hiddata.c
2 * Author: Christian Starkjohann
3 * Creation Date: 2008-04-11
4 * Tabsize: 4