From d481bd5061bd55acff17667ff8c77cc8b90478c2 Mon Sep 17 00:00:00 2001 From: optixx Date: Sat, 2 May 2009 13:19:58 +0200 Subject: [PATCH] o cleanup --- tools/avrusb/Changelog.txt | 270 ------- tools/avrusb/CommercialLicense.txt | 156 ---- tools/avrusb/License.txt | 361 --------- tools/avrusb/Readme.txt | 76 -- tools/avrusb/USBID-License.txt | 146 ---- tools/avrusb/circuits/Readme.txt | 79 -- tools/avrusb/circuits/tiny45-rc.png | Bin 8316 -> 0 bytes tools/avrusb/circuits/tiny45-rc.sch | Bin 193502 -> 0 bytes tools/avrusb/circuits/with-series-diodes.png | Bin 13285 -> 0 bytes tools/avrusb/circuits/with-series-diodes.sch | Bin 213956 -> 0 bytes tools/avrusb/circuits/with-vreg.png | Bin 14060 -> 0 bytes tools/avrusb/circuits/with-vreg.sch | Bin 215922 -> 0 bytes tools/avrusb/circuits/with-zener.png | Bin 13421 -> 0 bytes tools/avrusb/circuits/with-zener.sch | Bin 225561 -> 0 bytes tools/avrusb/examples/Readme.txt | 102 --- tools/avrusb/examples/custom-class/Readme.txt | 64 -- .../custom-class/commandline/Makefile | 48 -- .../custom-class/commandline/Makefile.windows | 18 - .../custom-class/commandline/opendevice.c | 203 ----- .../custom-class/commandline/opendevice.h | 77 -- .../examples/custom-class/commandline/set-led | Bin 23225 -> 0 bytes .../custom-class/commandline/set-led.c | 135 ---- .../examples/custom-class/firmware/Makefile | 164 ---- .../examples/custom-class/firmware/main.c | 98 --- .../examples/custom-class/firmware/requests.h | 36 - .../custom-class/firmware/usbconfig.h | 350 -------- .../firmware/usbdrv/Changelog.txt | 270 ------- .../firmware/usbdrv/CommercialLicense.txt | 156 ---- .../custom-class/firmware/usbdrv/License.txt | 361 --------- .../custom-class/firmware/usbdrv/Readme.txt | 158 ---- .../firmware/usbdrv/USBID-License.txt | 146 ---- .../firmware/usbdrv/asmcommon.inc | 188 ----- .../custom-class/firmware/usbdrv/oddebug.c | 50 -- .../custom-class/firmware/usbdrv/oddebug.h | 123 --- .../firmware/usbdrv/usbconfig-prototype.h | 357 --------- .../custom-class/firmware/usbdrv/usbdrv.c | 625 --------------- .../custom-class/firmware/usbdrv/usbdrv.h | 733 ----------------- .../custom-class/firmware/usbdrv/usbdrvasm.S | 305 ------- .../firmware/usbdrv/usbdrvasm.asm | 21 - .../firmware/usbdrv/usbdrvasm12.inc | 393 --------- .../firmware/usbdrv/usbdrvasm128.inc | 752 ------------------ .../firmware/usbdrv/usbdrvasm15.inc | 423 ---------- .../firmware/usbdrv/usbdrvasm16.inc | 343 -------- .../firmware/usbdrv/usbdrvasm165.inc | 453 ----------- .../firmware/usbdrv/usbdrvasm18-crc.inc | 707 ---------------- .../firmware/usbdrv/usbdrvasm20.inc | 360 --------- .../firmware/usbdrv/usbportability.h | 140 ---- .../avrusb/examples/hid-custom-rq/Readme.txt | 28 - .../hid-custom-rq/commandline/Makefile | 48 -- .../commandline/Makefile.windows | 18 - .../hid-custom-rq/commandline/opendevice.c | 203 ----- .../hid-custom-rq/commandline/opendevice.h | 77 -- .../hid-custom-rq/commandline/set-led.c | 135 ---- .../examples/hid-custom-rq/firmware/Makefile | 164 ---- .../examples/hid-custom-rq/firmware/main.c | 121 --- .../hid-custom-rq/firmware/requests.h | 32 - .../hid-custom-rq/firmware/usbconfig.h | 350 -------- tools/avrusb/examples/hid-data/Readme.txt | 75 -- .../examples/hid-data/commandline/Makefile | 42 - .../hid-data/commandline/Makefile.windows | 18 - .../examples/hid-data/commandline/hiddata.c | 317 -------- .../examples/hid-data/commandline/hiddata.h | 71 -- .../examples/hid-data/commandline/hidsdi.h | 49 -- .../examples/hid-data/commandline/hidtool | Bin 14265 -> 0 bytes .../examples/hid-data/commandline/hidtool.c | 127 --- .../examples/hid-data/firmware/Makefile | 164 ---- .../avrusb/examples/hid-data/firmware/main.c | 141 ---- .../examples/hid-data/firmware/usbconfig.h | 350 -------- .../hid-data/firmware/usbdrv/Changelog.txt | 270 ------- .../firmware/usbdrv/CommercialLicense.txt | 156 ---- .../hid-data/firmware/usbdrv/License.txt | 361 --------- .../hid-data/firmware/usbdrv/Readme.txt | 158 ---- .../firmware/usbdrv/USBID-License.txt | 146 ---- .../hid-data/firmware/usbdrv/asmcommon.inc | 188 ----- .../hid-data/firmware/usbdrv/oddebug.c | 50 -- .../hid-data/firmware/usbdrv/oddebug.h | 123 --- .../firmware/usbdrv/usbconfig-prototype.h | 357 --------- .../hid-data/firmware/usbdrv/usbdrv.c | 625 --------------- .../hid-data/firmware/usbdrv/usbdrv.h | 733 ----------------- .../hid-data/firmware/usbdrv/usbdrvasm.S | 305 ------- .../hid-data/firmware/usbdrv/usbdrvasm.asm | 21 - .../hid-data/firmware/usbdrv/usbdrvasm12.inc | 393 --------- .../hid-data/firmware/usbdrv/usbdrvasm128.inc | 752 ------------------ .../hid-data/firmware/usbdrv/usbdrvasm15.inc | 423 ---------- .../hid-data/firmware/usbdrv/usbdrvasm16.inc | 343 -------- .../hid-data/firmware/usbdrv/usbdrvasm165.inc | 453 ----------- .../firmware/usbdrv/usbdrvasm18-crc.inc | 707 ---------------- .../hid-data/firmware/usbdrv/usbdrvasm20.inc | 360 --------- .../hid-data/firmware/usbdrv/usbportability.h | 140 ---- tools/avrusb/examples/hid-mouse/Readme.txt | 48 -- .../examples/hid-mouse/firmware/Makefile | 164 ---- .../avrusb/examples/hid-mouse/firmware/main.c | 165 ---- .../examples/hid-mouse/firmware/usbconfig.h | 350 -------- tools/avrusb/examples/usbtool/Makefile | 48 -- .../avrusb/examples/usbtool/Makefile.windows | 18 - tools/avrusb/examples/usbtool/Readme.txt | 209 ----- tools/avrusb/examples/usbtool/opendevice.c | 203 ----- tools/avrusb/examples/usbtool/opendevice.h | 77 -- tools/avrusb/examples/usbtool/usbtool.c | 356 --------- tools/avrusb/libs-device/Readme.txt | 22 - tools/avrusb/libs-device/osccal.c | 59 -- tools/avrusb/libs-device/osccal.h | 63 -- tools/avrusb/libs-device/osctune.h | 88 -- tools/avrusb/libs-host/Readme.txt | 26 - tools/avrusb/libs-host/hiddata.c | 317 -------- tools/avrusb/libs-host/hiddata.h | 71 -- tools/avrusb/libs-host/hidsdi.h | 49 -- tools/avrusb/libs-host/opendevice.c | 203 ----- tools/avrusb/libs-host/opendevice.h | 77 -- tools/avrusb/tests/Makefile | 127 --- tools/avrusb/tests/Readme.txt | 13 - tools/avrusb/tests/compare-sizes.awk | 45 -- tools/avrusb/tests/main.c | 159 ---- tools/avrusb/tests/null.c | 26 - .../sizes-20080418-gcc3.4.6.txt | 13 - .../sizes-20080418-gcc4.2.2.txt | 13 - .../sizes-20080513-gcc3.4.6.txt | 15 - .../sizes-20080513-gcc4.3.0.txt | 15 - .../sizes-20081022-gcc3.4.6.txt | 16 - .../sizes-20081022-gcc4.3.0.txt | 16 - .../sizes-20081126-gcc3.4.6.txt | 16 - .../sizes-20081126-gcc4.3.0.txt | 16 - .../sizes-20090323-gcc3.4.6.txt | 17 - .../sizes-20090323-gcc4.3.2.txt | 17 - tools/avrusb/tests/usbconfig.h | 317 -------- tools/avrusb/usbdrv/Changelog.txt | 270 ------- tools/avrusb/usbdrv/CommercialLicense.txt | 156 ---- tools/avrusb/usbdrv/License.txt | 361 --------- tools/avrusb/usbdrv/Readme.txt | 158 ---- tools/avrusb/usbdrv/USBID-License.txt | 146 ---- tools/avrusb/usbdrv/asmcommon.inc | 188 ----- tools/avrusb/usbdrv/oddebug.c | 50 -- tools/avrusb/usbdrv/oddebug.h | 123 --- tools/avrusb/usbdrv/usbconfig-prototype.h | 357 --------- tools/avrusb/usbdrv/usbdrv.c | 625 --------------- tools/avrusb/usbdrv/usbdrv.h | 733 ----------------- tools/avrusb/usbdrv/usbdrvasm.S | 305 ------- tools/avrusb/usbdrv/usbdrvasm.asm | 21 - tools/avrusb/usbdrv/usbdrvasm12.inc | 393 --------- tools/avrusb/usbdrv/usbdrvasm128.inc | 752 ------------------ tools/avrusb/usbdrv/usbdrvasm15.inc | 423 ---------- tools/avrusb/usbdrv/usbdrvasm16.inc | 343 -------- tools/avrusb/usbdrv/usbdrvasm165.inc | 453 ----------- tools/avrusb/usbdrv/usbdrvasm18-crc.inc | 707 ---------------- tools/avrusb/usbdrv/usbdrvasm20.inc | 360 --------- tools/avrusb/usbdrv/usbportability.h | 140 ---- 146 files changed, 29559 deletions(-) delete mode 100644 tools/avrusb/Changelog.txt delete mode 100644 tools/avrusb/CommercialLicense.txt delete mode 100644 tools/avrusb/License.txt delete mode 100644 tools/avrusb/Readme.txt delete mode 100644 tools/avrusb/USBID-License.txt delete mode 100644 tools/avrusb/circuits/Readme.txt delete mode 100644 tools/avrusb/circuits/tiny45-rc.png delete mode 100644 tools/avrusb/circuits/tiny45-rc.sch delete mode 100644 tools/avrusb/circuits/with-series-diodes.png delete mode 100644 tools/avrusb/circuits/with-series-diodes.sch delete mode 100644 tools/avrusb/circuits/with-vreg.png delete mode 100644 tools/avrusb/circuits/with-vreg.sch delete mode 100644 tools/avrusb/circuits/with-zener.png delete mode 100644 tools/avrusb/circuits/with-zener.sch delete mode 100644 tools/avrusb/examples/Readme.txt delete mode 100644 tools/avrusb/examples/custom-class/Readme.txt delete mode 100644 tools/avrusb/examples/custom-class/commandline/Makefile delete mode 100644 tools/avrusb/examples/custom-class/commandline/Makefile.windows delete mode 100644 tools/avrusb/examples/custom-class/commandline/opendevice.c delete mode 100644 tools/avrusb/examples/custom-class/commandline/opendevice.h delete mode 100644 tools/avrusb/examples/custom-class/commandline/set-led delete mode 100644 tools/avrusb/examples/custom-class/commandline/set-led.c delete mode 100644 tools/avrusb/examples/custom-class/firmware/Makefile delete mode 100644 tools/avrusb/examples/custom-class/firmware/main.c delete mode 100644 tools/avrusb/examples/custom-class/firmware/requests.h delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbconfig.h delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/Changelog.txt delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/CommercialLicense.txt delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/License.txt delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/Readme.txt delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/USBID-License.txt delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/asmcommon.inc delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/oddebug.c delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/oddebug.h delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/usbconfig-prototype.h delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrv.c delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrv.h delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm.S delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm.asm delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm12.inc delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm128.inc delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm15.inc delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm16.inc delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm165.inc delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm18-crc.inc delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm20.inc delete mode 100644 tools/avrusb/examples/custom-class/firmware/usbdrv/usbportability.h delete mode 100644 tools/avrusb/examples/hid-custom-rq/Readme.txt delete mode 100644 tools/avrusb/examples/hid-custom-rq/commandline/Makefile delete mode 100644 tools/avrusb/examples/hid-custom-rq/commandline/Makefile.windows delete mode 100644 tools/avrusb/examples/hid-custom-rq/commandline/opendevice.c delete mode 100644 tools/avrusb/examples/hid-custom-rq/commandline/opendevice.h delete mode 100644 tools/avrusb/examples/hid-custom-rq/commandline/set-led.c delete mode 100644 tools/avrusb/examples/hid-custom-rq/firmware/Makefile delete mode 100644 tools/avrusb/examples/hid-custom-rq/firmware/main.c delete mode 100644 tools/avrusb/examples/hid-custom-rq/firmware/requests.h delete mode 100644 tools/avrusb/examples/hid-custom-rq/firmware/usbconfig.h delete mode 100644 tools/avrusb/examples/hid-data/Readme.txt delete mode 100644 tools/avrusb/examples/hid-data/commandline/Makefile delete mode 100644 tools/avrusb/examples/hid-data/commandline/Makefile.windows delete mode 100644 tools/avrusb/examples/hid-data/commandline/hiddata.c delete mode 100644 tools/avrusb/examples/hid-data/commandline/hiddata.h delete mode 100644 tools/avrusb/examples/hid-data/commandline/hidsdi.h delete mode 100644 tools/avrusb/examples/hid-data/commandline/hidtool delete mode 100644 tools/avrusb/examples/hid-data/commandline/hidtool.c delete mode 100644 tools/avrusb/examples/hid-data/firmware/Makefile delete mode 100644 tools/avrusb/examples/hid-data/firmware/main.c delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbconfig.h delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/Changelog.txt delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/CommercialLicense.txt delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/License.txt delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/Readme.txt delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/USBID-License.txt delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/asmcommon.inc delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/oddebug.c delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/oddebug.h delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/usbconfig-prototype.h delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrv.c delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrv.h delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm.S delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm.asm delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm12.inc delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm128.inc delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm15.inc delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm16.inc delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm165.inc delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm18-crc.inc delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm20.inc delete mode 100644 tools/avrusb/examples/hid-data/firmware/usbdrv/usbportability.h delete mode 100644 tools/avrusb/examples/hid-mouse/Readme.txt delete mode 100644 tools/avrusb/examples/hid-mouse/firmware/Makefile delete mode 100644 tools/avrusb/examples/hid-mouse/firmware/main.c delete mode 100644 tools/avrusb/examples/hid-mouse/firmware/usbconfig.h delete mode 100644 tools/avrusb/examples/usbtool/Makefile delete mode 100644 tools/avrusb/examples/usbtool/Makefile.windows delete mode 100644 tools/avrusb/examples/usbtool/Readme.txt delete mode 100644 tools/avrusb/examples/usbtool/opendevice.c delete mode 100644 tools/avrusb/examples/usbtool/opendevice.h delete mode 100644 tools/avrusb/examples/usbtool/usbtool.c delete mode 100644 tools/avrusb/libs-device/Readme.txt delete mode 100644 tools/avrusb/libs-device/osccal.c delete mode 100644 tools/avrusb/libs-device/osccal.h delete mode 100644 tools/avrusb/libs-device/osctune.h delete mode 100644 tools/avrusb/libs-host/Readme.txt delete mode 100644 tools/avrusb/libs-host/hiddata.c delete mode 100644 tools/avrusb/libs-host/hiddata.h delete mode 100644 tools/avrusb/libs-host/hidsdi.h delete mode 100644 tools/avrusb/libs-host/opendevice.c delete mode 100644 tools/avrusb/libs-host/opendevice.h delete mode 100644 tools/avrusb/tests/Makefile delete mode 100644 tools/avrusb/tests/Readme.txt delete mode 100644 tools/avrusb/tests/compare-sizes.awk delete mode 100644 tools/avrusb/tests/main.c delete mode 100644 tools/avrusb/tests/null.c delete mode 100644 tools/avrusb/tests/sizes-reference/sizes-20080418-gcc3.4.6.txt delete mode 100644 tools/avrusb/tests/sizes-reference/sizes-20080418-gcc4.2.2.txt delete mode 100644 tools/avrusb/tests/sizes-reference/sizes-20080513-gcc3.4.6.txt delete mode 100644 tools/avrusb/tests/sizes-reference/sizes-20080513-gcc4.3.0.txt delete mode 100644 tools/avrusb/tests/sizes-reference/sizes-20081022-gcc3.4.6.txt delete mode 100644 tools/avrusb/tests/sizes-reference/sizes-20081022-gcc4.3.0.txt delete mode 100644 tools/avrusb/tests/sizes-reference/sizes-20081126-gcc3.4.6.txt delete mode 100644 tools/avrusb/tests/sizes-reference/sizes-20081126-gcc4.3.0.txt delete mode 100644 tools/avrusb/tests/sizes-reference/sizes-20090323-gcc3.4.6.txt delete mode 100644 tools/avrusb/tests/sizes-reference/sizes-20090323-gcc4.3.2.txt delete mode 100644 tools/avrusb/tests/usbconfig.h delete mode 100644 tools/avrusb/usbdrv/Changelog.txt delete mode 100644 tools/avrusb/usbdrv/CommercialLicense.txt delete mode 100644 tools/avrusb/usbdrv/License.txt delete mode 100644 tools/avrusb/usbdrv/Readme.txt delete mode 100644 tools/avrusb/usbdrv/USBID-License.txt delete mode 100644 tools/avrusb/usbdrv/asmcommon.inc delete mode 100644 tools/avrusb/usbdrv/oddebug.c delete mode 100644 tools/avrusb/usbdrv/oddebug.h delete mode 100644 tools/avrusb/usbdrv/usbconfig-prototype.h delete mode 100644 tools/avrusb/usbdrv/usbdrv.c delete mode 100644 tools/avrusb/usbdrv/usbdrv.h delete mode 100644 tools/avrusb/usbdrv/usbdrvasm.S delete mode 100644 tools/avrusb/usbdrv/usbdrvasm.asm delete mode 100644 tools/avrusb/usbdrv/usbdrvasm12.inc delete mode 100644 tools/avrusb/usbdrv/usbdrvasm128.inc delete mode 100644 tools/avrusb/usbdrv/usbdrvasm15.inc delete mode 100644 tools/avrusb/usbdrv/usbdrvasm16.inc delete mode 100644 tools/avrusb/usbdrv/usbdrvasm165.inc delete mode 100644 tools/avrusb/usbdrv/usbdrvasm18-crc.inc delete mode 100644 tools/avrusb/usbdrv/usbdrvasm20.inc delete mode 100644 tools/avrusb/usbdrv/usbportability.h diff --git a/tools/avrusb/Changelog.txt b/tools/avrusb/Changelog.txt deleted file mode 100644 index c07bca9..0000000 --- a/tools/avrusb/Changelog.txt +++ /dev/null @@ -1,270 +0,0 @@ -This file documents changes in the firmware-only USB driver for atmel's AVR -microcontrollers. New entries are always appended to the end of the file. -Scroll down to the bottom to see the most recent changes. - -2005-04-01: - - Implemented endpoint 1 as interrupt-in endpoint. - - Moved all configuration options to usbconfig.h which is not part of the - driver. - - Changed interface for usbVendorSetup(). - - Fixed compatibility with ATMega8 device. - - Various minor optimizations. - -2005-04-11: - - Changed interface to application: Use usbFunctionSetup(), usbFunctionRead() - and usbFunctionWrite() now. Added configuration options to choose which - of these functions to compile in. - - Assembler module delivers receive data non-inverted now. - - Made register and bit names compatible with more AVR devices. - -2005-05-03: - - Allow address of usbRxBuf on any memory page as long as the buffer does - not cross 256 byte page boundaries. - - Better device compatibility: works with Mega88 now. - - Code optimization in debugging module. - - Documentation updates. - -2006-01-02: - - Added (free) default Vendor- and Product-IDs bought from voti.nl. - - Added USBID-License.txt file which defines the rules for using the free - shared VID/PID pair. - - Added Readme.txt to the usbdrv directory which clarifies administrative - issues. - -2006-01-25: - - Added "configured state" to become more standards compliant. - - Added "HALT" state for interrupt endpoint. - - Driver passes the "USB Command Verifier" test from usb.org now. - - Made "serial number" a configuration option. - - Minor optimizations, we now recommend compiler option "-Os" for best - results. - - Added a version number to usbdrv.h - -2006-02-03: - - New configuration variable USB_BUFFER_SECTION for the memory section where - the USB rx buffer will go. This defaults to ".bss" if not defined. Since - this buffer MUST NOT cross 256 byte pages (not even touch a page at the - end), the user may want to pass a linker option similar to - "-Wl,--section-start=.mybuffer=0x800060". - - Provide structure for usbRequest_t. - - New defines for USB constants. - - Prepared for HID implementations. - - Increased data size limit for interrupt transfers to 8 bytes. - - New macro usbInterruptIsReady() to query interrupt buffer state. - -2006-02-18: - - Ensure that the data token which is sent as an ack to an OUT transfer is - always zero sized. This fixes a bug where the host reports an error after - sending an out transfer to the device, although all data arrived at the - device. - - Updated docs in usbdrv.h to reflect changed API in usbFunctionWrite(). - -* Release 2006-02-20 - - - Give a compiler warning when compiling with debugging turned on. - - Added Oleg Semyonov's changes for IAR-cc compatibility. - - Added new (optional) functions usbDeviceConnect() and usbDeviceDisconnect() - (also thanks to Oleg!). - - Rearranged tests in usbPoll() to save a couple of instructions in the most - likely case that no actions are pending. - - We need a delay between the SET ADDRESS request until the new address - becomes active. This delay was handled in usbPoll() until now. Since the - spec says that the delay must not exceed 2ms, previous versions required - aggressive polling during the enumeration phase. We have now moved the - handling of the delay into the interrupt routine. - - We must not reply with NAK to a SETUP transaction. We can only achieve this - by making sure that the rx buffer is empty when SETUP tokens are expected. - We therefore don't pass zero sized data packets from the status phase of - a transfer to usbPoll(). This change MAY cause troubles if you rely on - receiving a less than 8 bytes long packet in usbFunctionWrite() to - identify the end of a transfer. usbFunctionWrite() will NEVER be called - with a zero length. - -* Release 2006-03-14 - - - Improved IAR C support: tiny memory model, more devices - - Added template usbconfig.h file under the name usbconfig-prototype.h - -* Release 2006-03-26 - - - Added provision for one more interrupt-in endpoint (endpoint 3). - - Added provision for one interrupt-out endpoint (endpoint 1). - - Added flowcontrol macros for USB. - - Added provision for custom configuration descriptor. - - Allow ANY two port bits for D+ and D-. - - Merged (optional) receive endpoint number into global usbRxToken variable. - - Use USB_CFG_IOPORTNAME instead of USB_CFG_IOPORT. We now construct the - variable name from the single port letter instead of computing the address - of related ports from the output-port address. - -* Release 2006-06-26 - - - Updated documentation in usbdrv.h and usbconfig-prototype.h to reflect the - new features. - - Removed "#warning" directives because IAR does not understand them. Use - unused static variables instead to generate a warning. - - Do not include when compiling with IAR. - - Introduced USB_CFG_DESCR_PROPS_* in usbconfig.h to configure how each - USB descriptor should be handled. It is now possible to provide descriptor - data in Flash, RAM or dynamically at runtime. - - STALL is now a status in usbTxLen* instead of a message. We can now conform - to the spec and leave the stall status pending until it is cleared. - - Made usbTxPacketCnt1 and usbTxPacketCnt3 public. This allows the - application code to reset data toggling on interrupt pipes. - -* Release 2006-07-18 - - - Added an #if !defined __ASSEMBLER__ to the warning in usbdrv.h. This fixes - an assembler error. - - usbDeviceDisconnect() takes pull-up resistor to high impedance now. - -* Release 2007-02-01 - - - Merged in some code size improvements from usbtiny (thanks to Dick - Streefland for these optimizations!) - - Special alignment requirement for usbRxBuf not required any more. Thanks - again to Dick Streefland for this hint! - - Reverted to "#warning" instead of unused static variables -- new versions - of IAR CC should handle this directive. - - Changed Open Source license to GNU GPL v2 in order to make linking against - other free libraries easier. We no longer require publication of the - circuit diagrams, but we STRONGLY encourage it. If you improve the driver - itself, PLEASE grant us a royalty free license to your changes for our - commercial license. - -* Release 2007-03-29 - - - New configuration option "USB_PUBLIC" in usbconfig.h. - - Set USB version number to 1.10 instead of 1.01. - - Code used USB_CFG_DESCR_PROPS_STRING_DEVICE and - USB_CFG_DESCR_PROPS_STRING_PRODUCT inconsistently. Changed all occurrences - to USB_CFG_DESCR_PROPS_STRING_PRODUCT. - - New assembler module for 16.5 MHz RC oscillator clock with PLL in receiver - code. - - New assembler module for 16 MHz crystal. - - usbdrvasm.S contains common code only, clock-specific parts have been moved - to usbdrvasm12.S, usbdrvasm16.S and usbdrvasm165.S respectively. - -* Release 2007-06-25 - - - 16 MHz module: Do SE0 check in stuffed bits as well. - -* Release 2007-07-07 - - - Define hi8(x) for IAR compiler to limit result to 8 bits. This is necessary - for negative values. - - Added 15 MHz module contributed by V. Bosch. - - Interrupt vector name can now be configured. This is useful if somebody - wants to use a different hardware interrupt than INT0. - -* Release 2007-08-07 - - - Moved handleIn3 routine in usbdrvasm16.S so that relative jump range is - not exceeded. - - More config options: USB_RX_USER_HOOK(), USB_INITIAL_DATATOKEN, - USB_COUNT_SOF - - USB_INTR_PENDING can now be a memory address, not just I/O - -* Release 2007-09-19 - - - Split out common parts of assembler modules into separate include file - - Made endpoint numbers configurable so that given interface definitions - can be matched. See USB_CFG_EP3_NUMBER in usbconfig-prototype.h. - - Store endpoint number for interrupt/bulk-out so that usbFunctionWriteOut() - can handle any number of endpoints. - - Define usbDeviceConnect() and usbDeviceDisconnect() even if no - USB_CFG_PULLUP_IOPORTNAME is defined. Directly set D+ and D- to 0 in this - case. - -* Release 2007-12-01 - - - Optimize usbDeviceConnect() and usbDeviceDisconnect() for less code size - when USB_CFG_PULLUP_IOPORTNAME is not defined. - -* Release 2007-12-13 - - - Renamed all include-only assembler modules from *.S to *.inc so that - people don't add them to their project sources. - - Distribute leap bits in tx loop more evenly for 16 MHz module. - - Use "macro" and "endm" instead of ".macro" and ".endm" for IAR - - Avoid compiler warnings for constant expr range by casting some values in - USB descriptors. - -* Release 2008-01-21 - - - Fixed bug in 15 and 16 MHz module where the new address set with - SET_ADDRESS was already accepted at the next NAK or ACK we send, not at - the next data packet we send. This caused problems when the host polled - too fast. Thanks to Alexander Neumann for his help and patience debugging - this issue! - -* Release 2008-02-05 - - - Fixed bug in 16.5 MHz module where a register was used in the interrupt - handler before it was pushed. This bug was introduced with version - 2007-09-19 when common parts were moved to a separate file. - - Optimized CRC routine (thanks to Reimar Doeffinger). - -* Release 2008-02-16 - - - Removed outdated IAR compatibility stuff (code sections). - - Added hook macros for USB_RESET_HOOK() and USB_SET_ADDRESS_HOOK(). - - Added optional routine usbMeasureFrameLength() for calibration of the - internal RC oscillator. - -* Release 2008-02-28 - - - USB_INITIAL_DATATOKEN defaults to USBPID_DATA1 now, which means that we - start with sending USBPID_DATA0. - - Changed defaults in usbconfig-prototype.h - - Added free USB VID/PID pair for MIDI class devices - - Restructured AVR-USB as separate package, not part of PowerSwitch any more. - -* Release 2008-04-18 - - - Restructured usbdrv.c so that it is easier to read and understand. - - Better code optimization with gcc 4. - - If a second interrupt in endpoint is enabled, also add it to config - descriptor. - - Added config option for long transfers (above 254 bytes), see - USB_CFG_LONG_TRANSFERS in usbconfig.h. - - Added 20 MHz module contributed by Jeroen Benschop. - -* Release 2008-05-13 - - - Fixed bug in libs-host/hiddata.c function usbhidGetReport(): length - was not incremented, pointer to length was incremented instead. - - Added code to command line tool(s) which claims an interface. This code - is disabled by default, but may be necessary on newer Linux kernels. - - Added usbconfig.h option "USB_CFG_CHECK_DATA_TOGGLING". - - New header "usbportability.h" prepares ports to other development - environments. - - Long transfers (above 254 bytes) did not work when usbFunctionRead() was - used to supply the data. Fixed this bug. [Thanks to Alexander Neumann!] - - In hiddata.c (example code for sending/receiving data over HID), use - USB_RECIP_DEVICE instead of USB_RECIP_INTERFACE for control transfers so - that we need not claim the interface. - - in usbPoll() loop 20 times polling for RESET state instead of 10 times. - This accounts for the higher clock rates we now support. - - Added a module for 12.8 MHz RC oscillator with PLL in receiver loop. - - Added hook to SOF code so that oscillator can be tuned to USB frame clock. - - Added timeout to waitForJ loop. Helps preventing unexpected hangs. - - Added example code for oscillator tuning to libs-device (thanks to - Henrik Haftmann for the idea to this routine). - - Implemented option USB_CFG_SUPPRESS_INTR_CODE. - -* Release 2008-10-22 - - - Fixed libs-device/osctune.h: OSCCAL is memory address on ATMega88 and - similar, not offset of 0x20 needs to be added. - - Allow distribution under GPLv3 for those who have to link against other - code distributed under GPLv3. - -* Release 2008-11-26 - - - Removed libusb-win32 dependency for hid-data example in Makefile.windows. - It was never required and confused many people. - - Added extern uchar usbRxToken to usbdrv.h. - - Integrated a module with CRC checks at 18 MHz by Lukas Schrittwieser. - -* Release 2009-03-23 diff --git a/tools/avrusb/CommercialLicense.txt b/tools/avrusb/CommercialLicense.txt deleted file mode 100644 index 6d8bf39..0000000 --- a/tools/avrusb/CommercialLicense.txt +++ /dev/null @@ -1,156 +0,0 @@ -AVR-USB Driver Software License Agreement -Version 2008-10-07 - -THIS LICENSE AGREEMENT GRANTS YOU CERTAIN RIGHTS IN A SOFTWARE. YOU CAN -ENTER INTO THIS AGREEMENT AND ACQUIRE THE RIGHTS OUTLINED BELOW BY PAYING -THE AMOUNT ACCORDING TO SECTION 4 ("PAYMENT") TO OBJECTIVE DEVELOPMENT. - - -1 DEFINITIONS - -1.1 "OBJECTIVE DEVELOPMENT" shall mean OBJECTIVE DEVELOPMENT Software GmbH, -Grosse Schiffgasse 1A/7, 1020 Wien, AUSTRIA. - -1.2 "You" shall mean the Licensee. - -1.3 "AVR-USB" shall mean all files included in the package distributed under -the name "avrusb" by OBJECTIVE DEVELOPMENT (http://www.obdev.at/avrusb/) -unless otherwise noted. This includes the firmware-only USB device -implementation for Atmel AVR microcontrollers, some simple device examples -and host side software examples and libraries. - - -2 LICENSE GRANTS - -2.1 Source Code. OBJECTIVE DEVELOPMENT shall furnish you with the source -code of AVR-USB. - -2.2 Distribution and Use. OBJECTIVE DEVELOPMENT grants you the -non-exclusive right to use, copy and distribute AVR-USB with your hardware -product(s), restricted by the limitations in section 3 below. - -2.3 Modifications. OBJECTIVE DEVELOPMENT grants you the right to modify -the source code and your copy of AVR-USB according to your needs. - -2.4 USB IDs. OBJECTIVE DEVELOPMENT grants you the exclusive rights to use -USB Product ID(s) sent to you in e-mail after receiving your payment in -conjunction with USB Vendor ID 5824. OBJECTIVE DEVELOPMENT has acquired an -exclusive license for this pair of USB identifiers from Wouter van Ooijen -(www.voti.nl), who has licensed the VID from the USB Implementers Forum, -Inc. (www.usb.org). - - -3 LICENSE RESTRICTIONS - -3.1 Number of Units. Only one of the following three definitions is -applicable. Which one is determined by the amount you pay to OBJECTIVE -DEVELOPMENT, see section 4 ("Payment") below. - -Hobby License: You may use AVR-USB according to section 2 above in no more -than 5 hardware units. These units must not be sold for profit. - -Entry Level License: You may use AVR-USB according to section 2 above in no -more than 150 hardware units. - -Professional License: You may use AVR-USB according to section 2 above in -any number of hardware units, except for large scale production ("unlimited -fair use"). Quantities below 10,000 units are not considered large scale -production. If your reach quantities which are obviously large scale -production, you must pay a license fee of 0.10 EUR per unit for all units -above 10,000. - -3.2 Rental. You may not rent, lease, or lend AVR-USB or otherwise encumber -any copy of AVR-USB, or any of the rights granted herein. - -3.3 Transfer. You may not transfer your rights under this Agreement to -another party without OBJECTIVE DEVELOPMENT's prior written consent. If -such consent is obtained, you may permanently transfer this License to -another party. The recipient of such transfer must agree to all terms and -conditions of this Agreement. - -3.4 Reservation of Rights. OBJECTIVE DEVELOPMENT retains all rights not -expressly granted. - -3.5 Non-Exclusive Rights. Your license rights under this Agreement are -non-exclusive. - -3.6 Third Party Rights. This Agreement cannot grant you rights controlled -by third parties. In particular, you are not allowed to use the USB logo or -other trademarks owned by the USB Implementers Forum, Inc. without their -consent. Since such consent depends on USB certification, it should be -noted that AVR-USB will not pass certification because it does not -implement checksum verification and the microcontroller ports do not meet -the electrical specifications. - - -4 PAYMENT - -The payment amount depends on the variation of this agreement (according to -section 3.1) into which you want to enter. Concrete prices are listed on -OBJECTIVE DEVELOPMENT's web site, usually at -http://www.obdev.at/avrusb/license.html. You agree to pay the amount listed -there to OBJECTIVE DEVELOPMENT or OBJECTIVE DEVELOPMENT's payment processor -or reseller. - - -5 COPYRIGHT AND OWNERSHIP - -AVR-USB is protected by copyright laws and international copyright -treaties, as well as other intellectual property laws and treaties. AVR-USB -is licensed, not sold. - - -6 TERM AND TERMINATION - -6.1 Term. This Agreement shall continue indefinitely. However, OBJECTIVE -DEVELOPMENT may terminate this Agreement and revoke the granted license and -USB-IDs if you fail to comply with any of its terms and conditions. - -6.2 Survival of Terms. All provisions regarding secrecy, confidentiality -and limitation of liability shall survive termination of this agreement. - - -7 DISCLAIMER OF WARRANTY AND LIABILITY - -LIMITED WARRANTY. AVR-USB IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, OBJECTIVE -DEVELOPMENT AND ITS SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES, EITHER -EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND -NON-INFRINGEMENT, WITH REGARD TO AVR-USB, AND THE PROVISION OF OR FAILURE -TO PROVIDE SUPPORT SERVICES. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL -RIGHTS. YOU MAY HAVE OTHERS, WHICH VARY FROM STATE/JURISDICTION TO -STATE/JURISDICTION. - -LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, -IN NO EVENT SHALL OBJECTIVE DEVELOPMENT OR ITS SUPPLIERS BE LIABLE FOR ANY -SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER -(INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, -BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY -LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE AVR-USB OR THE -PROVISION OF OR FAILURE TO PROVIDE SUPPORT SERVICES, EVEN IF OBJECTIVE -DEVELOPMENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY -CASE, OBJECTIVE DEVELOPMENT'S ENTIRE LIABILITY UNDER ANY PROVISION OF THIS -AGREEMENT SHALL BE LIMITED TO THE AMOUNT ACTUALLY PAID BY YOU FOR AVR-USB. - - -8 MISCELLANEOUS TERMS - -8.1 Marketing. OBJECTIVE DEVELOPMENT has the right to mention for marketing -purposes that you entered into this agreement. - -8.2 Entire Agreement. This document represents the entire agreement between -OBJECTIVE DEVELOPMENT and you. It may only be modified in writing signed by -an authorized representative of both, OBJECTIVE DEVELOPMENT and you. - -8.3 Severability. In case a provision of these terms and conditions should -be or become partly or entirely invalid, ineffective, or not executable, -the validity of all other provisions shall not be affected. - -8.4 Applicable Law. This agreement is governed by the laws of the Republic -of Austria. - -8.5 Responsible Courts. The responsible courts in Vienna/Austria will have -exclusive jurisdiction regarding all disputes in connection with this -agreement. - diff --git a/tools/avrusb/License.txt b/tools/avrusb/License.txt deleted file mode 100644 index e9b2752..0000000 --- a/tools/avrusb/License.txt +++ /dev/null @@ -1,361 +0,0 @@ -OBJECTIVE DEVELOPMENT GmbH's AVR-USB driver software is distributed under the -terms and conditions of the GNU GPL version 2 or the GNU GPL version 3. It is -your choice whether you apply the terms of version 2 or version 3. The full -text of GPLv2 is included below. In addition to the requirements in the GPL, -we STRONGLY ENCOURAGE you to do the following: - -(1) Publish your entire project on a web site and drop us a note with the URL. -Use the form at http://www.obdev.at/avrusb/feedback.html for your submission. - -(2) Adhere to minimum publication standards. Please include AT LEAST: - - a circuit diagram in PDF, PNG or GIF format - - full source code for the host software - - a Readme.txt file in ASCII format which describes the purpose of the - project and what can be found in which directories and which files - - a reference to http://www.obdev.at/avrusb/ - -(3) If you improve the driver firmware itself, please give us a free license -to your modifications for our commercial license offerings. - - - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/tools/avrusb/Readme.txt b/tools/avrusb/Readme.txt deleted file mode 100644 index f72a0bc..0000000 --- a/tools/avrusb/Readme.txt +++ /dev/null @@ -1,76 +0,0 @@ -This is the Readme file to Objective Development's firmware-only USB driver -for Atmel AVR microcontrollers and related code. For more information please -visit http://www.obdev.at/avrusb/. - - -WHAT IS INCLUDED IN THIS PACKAGE? -================================= -This package consists of the device side USB driver firmware, library code -for device and host and fully working examples for device and host: - - Readme.txt .............. The file you are currently reading. - usbdrv .................. AVR-USB firmware, to be included in your project. - examples ................ Example code for device and host side. - libs-device ............. Useful code snippets for the device firmware. - libs-host ............... Useful code snippets for device drivers. - circuits ................ Example circuits using this driver. - Changelog.txt ........... Documentation of changes between versions. - License.txt ............. Free Open Source license for this package (GPL). - CommercialLicense.txt ... Alternative commercial license for this package. - USBID-License.txt ....... Terms and conditions for free USB VID/PID pairs. - -Each subdirectory contains a separate Readme file which explains its -contents. - - -PREREQUISITES -============= -The AVR code of AVR-USB is written in C and assembler. You need either -avr-gcc or IAR CC to compile the project. We recommend avr-gcc because it -is free and easily available. Gcc version 3 generates slightly more -efficient code than version 4 for AVR-USB. Not every release is tested with -the IAR compiler. Previous versions have been tested with IAR 4.10B/W32 and -4.12A/W32 on an ATmega8 with the "small" and "tiny" memory model. - -Ready made avr-gcc tool chains are available for most operating systems: - * Windows: WinAVR http://winavr.sourceforge.net/ - * Mac: AVRMacPack http://www.obdev.at/avrmacpack/ - * Linux and other Unixes: Most free Unixes have optional packages for AVR - development. If not, follow the instructions at - http://www.nongnu.org/avr-libc/user-manual/install_tools.html - -Our host side examples are compiled with gcc on all platforms. Gcc is the -default C compiler on Mac, Linux and many other Unixes. On windows, we -recommend MinGW (http://www.mingw.org/). Use the automated MinGW installer -for least troubles. You also need MSYS from the same site to work with -standard Makefiles. - -Most examples also depend on libusb. Libusb is available from -http://libusb.sourceforge.net/ for Unix and -http://libusb-win32.sourceforge.net/ for Windows. - - -TECHNICAL DOCUMENTATION -======================= -The API reference of the driver firmware can be found in usbdrv/usbdrv.h. -Documentation for host and device library files are in the respective header -files. For more information, see our documentation wiki at -http://www.obdev.at/goto.php?t=avrusb-wiki. - - -LICENSE -======= -AVR-USB and related code is distributed under the terms of the GNU General -Public License (GPL) version 2 (see License.txt for details) and the GNU -General Public License (GPL) version 3. It is your choice whether you apply -the terms of version 2 or version 3. In addition to the terms of the GPL, we -strongly encourage you to publish your entire project and mail OBJECTIVE -DEVELOPMENT a link to your publication. - -Alternatively, we offer a commercial license without the restrictions of the -GPL. See CommercialLicense.txt for details. - - ----------------------------------------------------------------------------- -(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH. -http://www.obdev.at/ diff --git a/tools/avrusb/USBID-License.txt b/tools/avrusb/USBID-License.txt deleted file mode 100644 index 984c9ee..0000000 --- a/tools/avrusb/USBID-License.txt +++ /dev/null @@ -1,146 +0,0 @@ -Royalty-Free Non-Exclusive License USB Product-ID -================================================= - -Version 2008-04-07 - -OBJECTIVE DEVELOPMENT Software GmbH hereby grants you the non-exclusive -right to use three USB.org vendor-ID (VID) / product-ID (PID) pairs with -products based on Objective Development's firmware-only USB driver for -Atmel AVR microcontrollers: - - * VID = 5824 (=0x16c0) / PID = 1500 (=0x5dc) for devices implementing no - USB device class (vendor-class devices with USB class = 0xff). Devices - using this pair will be referred to as "VENDOR CLASS" devices. - - * VID = 5824 (=0x16c0) / PID = 1503 (=0x5df) for HID class devices - (excluding mice and keyboards). Devices using this pair will be referred - to as "HID CLASS" devices. - - * VID = 5824 (=0x16c0) / PID = 1505 (=0x5e1) for CDC class modem devices - Devices using this pair will be referred to as "CDC-ACM CLASS" devices. - - * VID = 5824 (=0x16c0) / PID = 1508 (=0x5e4) for MIDI class devices - Devices using this pair will be referred to as "MIDI CLASS" devices. - -Since the granted right is non-exclusive, the same VID/PID pairs may be -used by many companies and individuals for different products. To avoid -conflicts, your device and host driver software MUST adhere to the rules -outlined below. - -OBJECTIVE DEVELOPMENT Software GmbH has licensed these VID/PID pairs from -Wouter van Ooijen (see www.voti.nl), who has licensed the VID from the USB -Implementers Forum, Inc. (see www.usb.org). The VID is registered for the -company name "Van Ooijen Technische Informatica". - - -RULES AND RESTRICTIONS -====================== - -(1) The USB device MUST provide a textual representation of the -manufacturer and product identification. The manufacturer identification -MUST be available at least in USB language 0x0409 (English/US). - -(2) The textual manufacturer identification MUST contain either an Internet -domain name (e.g. "mycompany.com") registered and owned by you, or an -e-mail address under your control (e.g. "myname@gmx.net"). You can embed -the domain name or e-mail address in any string you like, e.g. "Objective -Development http://www.obdev.at/avrusb/". - -(3) You are responsible for retaining ownership of the domain or e-mail -address for as long as any of your products are in use. - -(4) You may choose any string for the textual product identification, as -long as this string is unique within the scope of your textual manufacturer -identification. - -(5) Matching of device-specific drivers MUST be based on the textual -manufacturer and product identification in addition to the usual VID/PID -matching. This means that operating system features which are based on -VID/PID matching only (e.g. Windows kernel level drivers, automatic actions -when the device is plugged in etc) MUST NOT be used. The driver matching -MUST be a comparison of the entire strings, NOT a sub-string match. For -CDC-ACM CLASS and MIDI CLASS devices, a generic class driver should be used -and the matching is based on the USB device class. - -(6) The extent to which VID/PID matching is allowed for non device-specific -drivers or features depends on the operating system and particular VID/PID -pair used: - - * Mac OS X, Linux, FreeBSD and other Unixes: No VID/PID matching is - required and hence no VID/PID-only matching is allowed at all. - - * Windows: The operating system performs VID/PID matching for the kernel - level driver. You are REQUIRED to use libusb-win32 (see - http://libusb-win32.sourceforge.net/) as the kernel level driver for - VENDOR CLASS devices. HID CLASS devices all use the generic HID class - driver shipped with Windows, except mice and keyboards. You therefore - MUST NOT use any of the shared VID/PID pairs for mice or keyboards. - CDC-ACM CLASS devices require a ".inf" file which matches on the VID/PID - pair. This ".inf" file MUST load the "usbser" driver to configure the - device as modem (COM-port). - -(7) OBJECTIVE DEVELOPMENT Software GmbH disclaims all liability for any -problems which are caused by the shared use of these VID/PID pairs. You -have been warned that the sharing of VID/PID pairs may cause problems. If -you want to avoid them, get your own VID/PID pair for exclusive use. - - -HOW TO IMPLEMENT THESE RULES -============================ - -The following rules are for VENDOR CLASS and HID CLASS devices. CDC-ACM -CLASS and MIDI CLASS devices use the operating system's class driver and -don't need a custom driver. - -The host driver MUST iterate over all devices with the given VID/PID -numbers in their device descriptors and query the string representation for -the manufacturer name in USB language 0x0409 (English/US). It MUST compare -the ENTIRE string with your textual manufacturer identification chosen in -(2) above. A substring search for your domain or e-mail address is NOT -acceptable. The driver MUST NOT touch the device (other than querying the -descriptors) unless the strings match. - -For all USB devices with matching VID/PID and textual manufacturer -identification, the host driver must query the textual product -identification and string-compare it with the name of the product it can -control. It may only initialize the device if the product matches exactly. - -Objective Development provides examples for these matching rules with the -"PowerSwitch" project (using libusb) and with the "Automator" project -(using Windows calls on Windows and libusb on Unix). - - -Technical Notes: -================ - -Sharing the same VID/PID pair among devices is possible as long as ALL -drivers which match the VID/PID also perform matching on the textual -identification strings. This is easy on all operating systems except -Windows, since Windows establishes a static connection between the VID/PID -pair and a kernel level driver. All devices with the same VID/PID pair must -therefore use THE SAME kernel level driver. - -We therefore demand that you use libusb-win32 for VENDOR CLASS devices. -This is a generic kernel level driver which allows all types of USB access -for user space applications. This is only a partial solution of the -problem, though, because different device drivers may come with different -versions of libusb-win32 and they may not work with the libusb version of -the respective other driver. You are therefore encouraged to test your -driver against a broad range of libusb-win32 versions. Do not use new -features in new versions, or check for their existence before you use them. -When a new libusb-win32 becomes available, make sure that your driver is -compatible with it. - -For HID CLASS devices it is necessary that all those devices bind to the -same kernel driver: Microsoft's generic USB HID driver. This is true for -all HID devices except those with a specialized driver. Currently, the only -HIDs with specialized drivers are mice and keyboards. You therefore MUST -NOT use a shared VID/PID with mouse and keyboard devices. - -Sharing the same VID/PID among different products is unusual and probably -violates the USB specification. If you do it, you do it at your own risk. - -To avoid possible incompatibilities, we highly recommend that you get your -own VID/PID pair if you intend to sell your product. Objective -Development's commercial licenses for AVR-USB include a PID for -unrestricted exclusive use. diff --git a/tools/avrusb/circuits/Readme.txt b/tools/avrusb/circuits/Readme.txt deleted file mode 100644 index 427241b..0000000 --- a/tools/avrusb/circuits/Readme.txt +++ /dev/null @@ -1,79 +0,0 @@ -This is the Readme file for the AVR-USB example circuits directory. - - -CIRCUITS IN THIS DIRECTORY -========================== -Since USB requires 3.3 V levels on D+ and D- but delivers a power supply of -ca. 5 V, some kind of level conversion must be performed. There are several -ways to implement this level conversion, see the example circuits below. - -with-vreg.png and with-vreg.sch (EAGLE schematics): - This circuit uses a low drop voltage regulator to reduce the USB supply to - 3.3 V. You MUST use a low drop regulator because standard regulators such - as the LM317 require at least ca. 2 V drop. The advantage of this approach - is that it comes closest to the voltage levels required by the USB - specification and that the circuit is powered from a regulated supply. If - no USB cable is used (connector directly soldered on PCB), you can even - omit the 68 Ohm series resistors. The disadvantage is that you may want to - use other chips in your design which require 5 V. Please check that the AVR - used in your design allows the chosen clock rate at 3.3 V. - -with-zener.png and with-zener.sch (EAGLE schematics): - This circuit enforces lower voltage levels on D+ and D- with zener diodes. - The zener diodes MUST be low power / low current types to ensure that the - 1k5 pull-up resistor on D- generates a voltage of well above 2.5 V (but - below 3.6 V). The advantage of this circuit is its simplicity and that the - circuit can be powered at 5 V (usually precise enough if the cable drop is - neglected). The disadvantage is that some zener diodes have a lower voltage - than 3 V when powered through 1k5 and the choice of components becomes - relevant. In addition to that, the power consumption during USB data - transfer is increased because the current is only limited by the 68 Ohm - series resistor. The zeners may even distort the signal waveforms due to - their capacity. - -with-series-diodes.png and with-series-diodes.sch (EAGLE schematics): - This is a simplified low-cost version of the voltage regulator approach. - Instead of using a voltage regulator, we reduce the voltage by the forward - voltage of two silicon diodes (roughly 1.4 V). This gives ca. 3.6 V which - is practically inside the allowed range. The big disadvantage is that the - supply is not regulated -- it even depends strongly on the power - consumption. This cannot be tolerated for analog circuits. - -tiny45-rc.png and tiny45-rc.sch (EAGLE schematics): - This is mostly an example for connecting an 8 pin device using the internal - RC oscillator for system clock. This example uses series diodes to limit - the supply, but you may choose any other method. Please note that you must - choose a clock rate of 12.8 or 16.5 MHz because only the receiver modules - for these frequencies have a PLL to allow higher clock rate tolerances. - - -GENERAL DESIGN NOTES -==================== -All examples have D+ on hardware interrupt INT0 because this is the highest -priority interrupt on AVRs. You may use other hardware interrupts (and -configure the options at the end of usbconfig.h accordingly) if you make sure -that no higher priority interrupt is used. - -If you use USB_SOF_HOOK or USB_COUNT_SOF in usbconfig.h, you must wire D- to -the interrupt instead. This way the interrupt is triggered on USB Start Of -Frame pulses as well. - -Most examples have a 1M pull-down resistor at D+. This pull-up ensures that -in self-powered designs no interrupts occur while USB is not connected. You -may omit this resistor in bus-powered designs. Older examples had a pull-up -resistor instead. This is not compatible with the zener diode approach to -level conversion: 1M pull-up in conjunction with a 3.6 V zener diode give an -invalid logic level. - -All examples with ATMega8/88/168 have D+ at port D bit 2 (because this is -hardware interrupt 0) and D- on port D bit 4 because it is also a clock input -for timer/counter 0. This way the firmware can easily check for activity on -D- (USB frame pulses) by checking the counter value in regular intervals. If -no activity is found, the firmware should (according to the USB -specification) put the system into a low power suspend mode. - - - ----------------------------------------------------------------------------- -(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH. -http://www.obdev.at/ diff --git a/tools/avrusb/circuits/tiny45-rc.png b/tools/avrusb/circuits/tiny45-rc.png deleted file mode 100644 index 39139216c6499786160ec2bcdb945708b3486693..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8316 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 a$0+-}l-1aV1+i%y#)jtC8m``X^nU;#Qo1n! diff --git a/tools/avrusb/circuits/tiny45-rc.sch b/tools/avrusb/circuits/tiny45-rc.sch deleted file mode 100644 index 349f1ad60c47e121ae2c0032259d379e03fbf397..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 193502 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 z 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 diff --git a/tools/avrusb/circuits/with-series-diodes.sch b/tools/avrusb/circuits/with-series-diodes.sch deleted file mode 100644 index d84d99e562a27e3f613511c6c9b340c9a9d59020..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 213956 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 J_OZ*^{|BitSq}gJ diff --git a/tools/avrusb/circuits/with-vreg.png b/tools/avrusb/circuits/with-vreg.png deleted file mode 100644 index 2aba73987823ed355d06413658ed87138d2d158e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14060 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� 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 EKWi0tAOHXW diff --git a/tools/avrusb/circuits/with-vreg.sch b/tools/avrusb/circuits/with-vreg.sch deleted file mode 100644 index 1f1797bddb31bb9d52adee492dc6c75fc775c17f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 215922 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 =c(K5lb_W%CF6am+RL{;5Cs?fcR9t7lziemra4 z%l&F$TzDb+)t?IsJ$u_jW|5{c)S72_0)ol z@z9+QXZf~?hfe)=BMz^6sQk(gdA@6&v;AZB`lHJS`f>7K*6Xj?FmQZ)&zI_)GfB3b z5bkGY^Ht$cyI&dn!n`QugS_F{JSR;rJj{#mQ5y$S;B?4^UtlpkKFs>bMvu{ ze&k-5!!ti}&+dwwZEqs|lO4oEy&uIxy&uIx-+o^1NAcw2alU7m^J9=P9_sRK6AyLg zMgk76dZ_%;jXdAwN800>Ed%{{i}klRoiWglX1Cx+>}vkZ{3smi{h0FM9;EkUnqGM3 z$0z#B_3ans})9 zqj)H1al9UQ^6_{B=KL6BjEA~>+r&dpxHWH&;#CjjtNggmclq&sm)Gmx{DXmh?AlhZ zPn$W=k9MyidF1=`a1X)zQ8?85G3A5&l*97&$UO+!HPrCTkN?!aU;U_-r=lM}h95s1 z{22D66Ygm=`Z4Tn=XmBv>dE?Cf3kyksIzBHJk@SBg#+nsnQwv#=@%dWy@U#Qbl6AyLy27keW|2F-oeH-?F{62ti zzn?=~rF_%~G3Fq6-xfMTtAo!6pO?*nHFuDW9c@Afs_@3ff zd*qzZqa8N(r+>1uc&M{yO+3`uzfC-}^!K?RGv4y?c=(=TPEQRS9_sRK6A$HVhRT`o zX+4BfFRt;&cX0M|&aBv+?va7*v46VV%l>tL!+llrOYP6^vc1WB>k0Hd$7TCAwKGq$ zxsTyc!?Ssg@HCy;Z(AxSJz@S6_j7*Ue@5!Zm4})iR~{7nINW`?m;D&eyS^y=_+k8b zP}|SX`qh*V@`h*YN7A$JpXzBk&snttKfW)t z$KjS!_QGHM$!_AI&i?AI9&`B=Q$_cALA{>L%b2s-~C&g10Kn^zr!T+`(@zM{-SXn&hspsh2VVKIbXN^ ztyiNxKIih08Fr7$aL$eiXP&@4DR^QLy3=m+hxtRwgOkqV@TBv&cPH1E>(v&*ax3Ci=QtR?jPYV_H6L$_4hQ!&$i!>aloF9 zk00Xg(P{BaB2;lgp2AE2kjD==Jn0(nl$SomkFEWaBOZ+Vf!~`Rs&1!aUzyY_e!i8) z&$;u>KIhH~_Mx17it$5z9R8BG&)E9;^{0~$g!nm^eaLe^8tilHIl(;11C_@3IqOfN zeNsHL&x1GA>nEK!Fn++zGP$Er{I(ieE}c(nH~0gJM)a? z>%%%Fiy!e&#wo>>c+z=Xy!0u4ruHStwy)ST9A_uV^>2*%5y{j{ERJ)@k2Zux7Ffjk)1)l-r~im{4O5)^k3)kAf9v{7cYH^ z2lA!gVSY#d#E1A~eg)2cg~zX2V||I;1KIcTBx$vK4}6H9ADMk#-|{EXK96Ic9|!w9 zd~KBZ$c#q&aPERDDgKhT&;9nCPFKqpgMHSlGW)DKy%0a)j!2XE33z57p4Y(k#qkTg z`sU{G!yYhk0rl}C-1d;O{scLA;>6?Pq0&Q~5I>LqO^ly|7e-$ze!z(zj}t%lzdP2U z%kFRRA%5;P`@B*1p?_Wz`{z7<8ts$E&;JhloLt{(^XGTO`1v*V`F}(F{5(X4y{BkW zWB>e`hhqCm@gPNi!ZRSuS9nIm&u_&;{XAAY={zo8`qZEBjL5nt>h*_yV7@;v`j>c^ zW|@OCclY?+HuNwbe&<2?e0aF?eBx(reVf_Gg4ay5mggqc)`EQ=;B8y>nKt>u%(k=k zRed1ZC&gdl_L-E-s$X3HV)E{2pX;#C)?lBWZ$&$dJ2I@lf*s6AE%#M}+3Xpkd|ifL z?EY`Khxy1sJ4_&7e}Uije{5_!s06O()5H3UIWFrSsQMrAx+Yva^qxoaeo1^tXLDo8 zi)Wt9pK$Skruo{`xn_k6AJ%dFrSfeyM+?v8G8f~1=+2h-yKLaxM|*s#?Hhf+{;HiV z;XG#>dYOxR{TAW@_jQnd)i><**h)?~yy>m09>T?|9>T>#tz21su@&PqRO^V>CwnJ< zSN~4^$Mts0j}xUe>y6_)lXgp85B^TfJJnwk&$G6)P2u99bDzrd6;C?vFY)BV{8xI! zL%FZzad?#roPL9I9puM4n)2`g$9LeI2NBM5g0=dEwhsEk80QZY=l6#=$6lm;`sihc z7|G%sU-3zC3;non#yJn>X~j4PAHRKIoHN&Aen$W1=V{_~P4yKIrO)&@Jn8)WO+1*# z#Y2^^k8|ex{H6NaY&{$Le%7tlw`XwZy7N z7mq&vgo}p~6X5uL%5C-fl3&GV$3M9r-imn7Nl5~Z&xAAH(H3Z9Q0_yahjwvS{Tua% z>c2OjU2xWh*t+=(vEFHUYT|hY7yZJ;Lzh39mA@vQbSgjP5l=pLKT!3piHCAtSo+07 z)n83YO7?q{XV-s`{8@KR_wgo}q#2am&(4xPfqgLzy$6kW)_!S&~?XZcI@v>`|T?B$7D z@hY$6#jCu+#Y55Oar$3ySFbkls)yvolRtmL#Y0_x-ez$g+9~nu+bKBh6kP3;cEMbo z_~)#O;vbx|DB#T5g%gMD74UpGlvt%aw2P0_KU4o|eV)~`alD}aq_5=}Sypms`D@}| z`?2_b2;t)UcG$TI(=A*)*LjbGaPjQpGNuR@PyUPr!o{mx;FGKdqwD9?cP1Z+?Sk{z z=g0Hd*oAg+^RbQX0{b{TYZvVM(Ki+QfAH^pYGAwIc^S@Luy+GhImPRmaPd&TZzG;` z=#;#8FprCek`{Rj(`=qIVXK{&u)kDK8*;?4m#1BbS9v8bUgZ@o9_rf#JaG(l^=cEZ zdPt9W^5;*uc&Kj|7Uv;9;@R@e#xHP_%g#+PPb2$=JUOpc%7?~ym+p= z`UZLURUfu}L7QVsUOf4SGML{fzj&zT1H$2h?BZC?NtWUV{fp{{wcH-t%iqynz7Xb1 z>|4?aQBx3-;$d0@(k?3mW~h>3z{JJl`q5_;~KS z#om=*f3m|PcHeHw4m+D;eG^o;cwG}N9_srO@uWki&5nC)MkV*6L03hn5E*H}Bc zVE@pLC}(1y^ju{-->uQK@ctG){=6mYYsQym?FjtXk2ba=-!3>W#@}A1)8oGj?Inz} z&Dzn90quH7?FD`EBkh9ql-h^KY5!^;!o{n72p13a>$R8LOI&~PoGtr%yo1E=@A2*t z@bH{(x*y1VV|eXrvb{gE%if=Pe{5eD(7w(N?P%xev3*VLW5*<4*N?u(+U?)J0Sjri-*zH$6}nV6hhzp{Q;@|AGj_<}o@EUC`!?Bn+r!mm$QdwKML znOQsH_ZL<@5ZhOZXYGjJ7w4V1;dkxbbL;%p{U<+`;b9-x#GC72y0xpWno?aGj6zfb;tf!pRqVl4sTKc|cW8 z@lanc@e^#X)8pcyzq&5hBc5~~7Z3IM{$&67o_*>k+{)iZJ$MKI5630R6YqeF_Q#Is z<+tR$etx@{-{XLev$YlV;`b(qx650ujs5n2(Qp5IIF~rh?gR3>#UXy&eFX6MUaTpW zW4w>h7@uF6WEa{gPh)%rJjAE<8=?Hj9B%zBf3ow(KM~{kA?xe8F8qss7Jt(N`uHm{ zJj4TX{KkfpuZf4^(^OBu;rTrfkBf)W)+8?;JsuaYd?c?}A{JC0;*BzsAHM;jwmd1> zFS)S(?)o!{9WpV~udDW!JId8CZZgLv{U`Seqjk7T#=Mj{xx;Nm7uS^=tlamEO_G}| zAE?R$f5Ly)>s*I|Q=T(_Y0r3BY*N2>yfUZ^_-psEKFRR!numll?&+GO7$Lg@}f7$br zu7CTb`4Rjp7B9lhFE#WWZN5hjG}Uw1t9RDxXWRbxzl}`A}bEFQr5t)AbuJ=w#j%vZE=r`n2WAMDJ%5k4s%?1|lG{it653yZhE zw>^$8TYT~X=l4y(H!@4|~SZaH#A#SbUyUzuN5i zwrI~Qd&@oL&di>STgCQ;J@342pgo`XRE($b^Bdz6p7`Usk3;cFM?7O6*=^Ota36Vq z-BLWW+tPom*FXEydi|qT@3UTu)uP>gX7vZJm{Q@`jo)Ux&ti~q4C?LHW3d~?H=`+j zr0S!3sJ#yspAG%z2YM@IvnTa>x&I8~LgNOR;uN$ z5TA@)w@n=wpWuwi#rA&gpT_vSWqD(K!V{NV_wgxS>D1pUz0xUexi?4bop30-KzV!T z-W;D4&*Jv_FVySzS|9Np+p9e$?GtG4?KTBBj0~k>TBxXPi~Iw{XVm2r5xkmI{|adAH?aRJ4afes4$Op}ljT*S^|4J>HO>_qUu~;gjNNdw;U_`CBdDFWG*b<#YZCLB#sWCu{HR zv2qyx@weJuK!zuW5u3DkV$=7Zf8YP=dS}bOMSD&)dsgFo3A_E!juADp=M}xp?YaLu zqdlRieU7A_zq&Nq6Dk}#3U~6gOTK0@S4Vq7Wl!wfy4`$YXIY@$p2}DH8|}#(4V&3B z;93947(4b#ySHum+;ffWX$Qv4p5WNi;fJxl;E(l$))dU={rq$NoZf0VjZfy8&(-{s zb&j9E*?1b}b&U6#hsw_4U(EAT#`nSIpMJiy{;b|wwes?OX(;n0+WV!C$M*g%R&4em zKK*=Y{iSBlw7tJPU)ueA341dC^!98Rk8bSk=&a@A5x=$Dtp9xJjYr8K<5BECn~g_| zMf9JHMZW)R7?1wS?AaCfmtG!^VtfuZ9ub>%AE-`jj89kZ@P=Fzwp71kGx`^-T_7$3vA_s_Ze9d3W`J%+QFobF@m+ z_Hc;_*1NV}y4A+7Odg!Qb={|64TqeQ5BEWqE{XRLpy*5YW807?eXb|W+XIdsCx03F zN?!Ub-^;<-qh)>$We@tPy`moWufU-WuW8R2oKISwn(T}o;ggbsgI_+I`enm-^UH?4 zhV2*Gjl3zp+dprECvW@!m3?NN74P3b7h1dsXa2+d1nP0=RXURoc9T5%(|m&;m2a*; z+EaS-@`U?PHEhX;eJVaGk9hX=JuV(f+Vpo@+B}Y5gtPyS927kshX*gpgR`#&P0JJZ z+2D~CPP<_5u-SbaaDD^Ww~Ofa%j%y^{vgb^H!Q~QZyK@R$rpP=WjA>4L1Aa8aQuOv zpgtb(3pmu{(yMf)C-Xb<=uh*_{7!zk{@m}1!&sh|j^E>YbBcvSe!m01KWS$z2l{=j z`Tc{@?>FK1>qhK%^2I+;`4^rs62F8sZ)@zY@CSVyls-}N_!}JRap_e$?|0(Bj;-n=|79lvuvpqbyNUeL_%SJv-M zJ{Q{i#&PENjiW~FckbWgAAcVop78}cL*-xmK{=tEBM^?i!J!_PUZwMXM;`rYzM0?2 zFV~;@9ld#ZUOIl~JV(**#5lHWZ0{42$ND*6bZzuIl4tSG!cnyCHZ5}=@_*e4z{J9*?3(@yCnTOYiAM`^c<`pNM z8Rz{yt2O_R;}$?y?P2wuV+ep?C#QqDg zUTFJWSr^cbXfwrr1H8B{!2a959M@$~zy5mfXX3nF*DXFndjY5K$mL@{Okd6XTq0H_{ToPv$rR4i@m_TJ;AYC zE}zFg@=7OvNuId#ew3e}v;)b*6Zg4a^7Ygsw#NoO#rE7%`I`DA#jo@XH~uA09r&Op z#{U@>|DOo+icOss|CX)TC!%{9kGD|D_oJ+ll{;&w2b)R^lD1dcikaXA%D|zsC-M_%dVM|kA91{F>mlP@%FU*Y}& zJY|LY^1wHV|L1J})2v;vZ#>bSBltzSuH5tu;{S6Y{wW*nu6Q4ZIypSMk3&D+Z2buS zyS#p6uH9_i=htP}L-%oXKL$!aCfwiO@$$N_Q@HQb#$20^t}Cvzu2(+bcFrNJm$|oq zf8=X${0NR8g!5i~@AnJG;`iT#eE`;>&DIy-#J6u>tow!&C(OqvH|u4UU-l6XW!+!I znY&>R*#WztNA{7tc&OJSoVlLYGkH^7Z$kZgg!*FZUtQO@uHozwa!^07Lk^#j4ytkr zck-d1kzVQ3{XvyO`D_0{<#hVDMn9fm?KjTfE}Un6yzsbTx8E0=U)YbDaIw92y2(5T zyxBYl`_Ruq{k#HuF)mL70bJcmsaCGPFnP+w6W2c=3MFOQk*1e(`jPSUuINYJ`*GptUlQ$+`oCuLz0~ zxIlk`|7b5z-|o=En1LUlYG2r0?Wox97}H1xl|1R;NteoJenhYIc|W3G`FlT--syLK zjO&8UjE@)o<|X6DX7gwEPOwiiKVoP6=>3Jgm=E9wKkvovvVYNE%#le4^?rmWT`HgX z5xvsq{fK_$@BK)6r$6=MdTWnA4()L>ibS1%9G*KcNg+#JV8;`WA~mI3QQ`Xv|V z!44xCA1V8TZ7soW?9Zvb;PB+{@S1q`0v+Bae#;!*k&)>M>pOV%F&y3|9=my5Jd|>& zJk<4LM;UMR4zxAKA@gb0mQeE6JXt)H`%y*wnlEMh$swMZKcffg^@xXhJ;GT_Ag^-D zp01o>zgp#Y^&)=4`i1sDo9F%jf2?ch8#r@CpM`z+AWt8_2kPbNl> ze{IVj#Qx!*h^zZUKhGQ!J>Nf&f8#lS;z#$tQaoG#USZEJG@GY^7w2j84{!f`Z0lV2 z^OGBA#PtKz&wr4k44!)k1CHVXYiM7D0|Dl z_z8othYb}D&vV?u)$fUi@+^aJ^dql)JdR#)$wxnKH9!7Y@Z&{?m>)0Ne?)%del2mH zj)M))%hM)`<0JNDK97C;Is&^9_fUUd06EqLr1R?({DBfsj$Uxd=YEXy=Znt9kBdg+ zN9x&ZzRI2eb}RZ(`+(OU-#E{_r6bN`q4YJf4|2qMzE2qY+jIXu_DN7bkClFh2R|yk z(#em?Px;7?DvvAYi_(v`_g`FJr1tnx{P=<3N7@5^PusOc2JahbO^9PYDW3JKj~+O% zJ<@+Zb8WiMVw7~mmCcI|p>J%~PVpUa2$ei~)SnBNf5k%;pU6*5#|837kK{Ana4%2! z=@&{*H10Dz-O>`~dQjh=BS(Ca&i4;v`};%x5B1}P^h%$VC&ZQX#|17ps{P9Bhk+BZDLgjbti+`csU&zrvU{9#z zu`_Z|KVC?$^m#v$KG&c7QE?LW=YB*l`KIM`e*C*IK5l6@KW-_F*pI)uu5oL!H|z=ZenbvG`go9D>GOUheXc+EBYJZExgXIBo|e=6 zI5D9;9@Lup@e=&FdPIJF_*HQ|nEEA~=g=3?#)j&z!TQN&{j=gE^qa1qr2qfrJ6eF% z|JV4AJnIF%XZ>qy#Fa1Wg>XH^Tc3^mvNuP4@|W!Rs{d^CJN$6`tMpHdiSZ);N)LG2 z9xtc-#K%zmi@fyadSZQVyt5_5>zex-^985;;67jBtPy?O!V^!@C;Lcmu7~p>-=W@gVr6IFKFH<9_q(g z&R;SvK#2g!i-#8Fk)yrxksYL;c=7nL%VR$erM!|qr!U(5BYzwHEd1+#8vA*u@8^-D zU6aoD8{(CZ=?UYw^ym4;ena~6d}F_%{FIOB3H^WcW9&CBW6K6J z$IaFrzaPf&i%&K`UVQwB+9P`J|4`#NEf0l7_|f|dxyNpZeuPRMJ@DvH7bGqkH1p+%#Y{= zkNM_)ghyY@H}@myl~3-+1?EQ^DsUmsVO<=b!x~Ay%3e=#K1RR#yW&Us6YSY_ZtgGa zf7YUCPpJHY|B!={PB``@o=FE4E*|})<+pqSC{mcIUmGv8O|9os~7!Q7K6o0B-$kA_* z&i7-l`R`|g-=Tio8UH{1VV@bw{6zh*cqr>;aPAX5c0e4jKQ}qt56b5G^aGS5#k2cF z%N~yUpl^)|dgb+veo;MTKm3CJr>~FYQ2w%;>N|F8KF?>q z`hTC@Y<~Rj=*QFXW8aAVNPDLqzMr8!^yg6TFXZSqD1Yov;=F=-AqVy24&~>5f$Fh4 zKcbhoeLnq2Jyk!mb7)_xS6<)TkBZy0{|wJ_sh*TKwc7~&xWxR}7Vh_5@)7*_e@5&_ z-kVK5po$;r!`>g1Jw4&bEjcav5h|Q|AqOR$@R9hDGo#O^AE~G6XXVWNNPY79=6oNRu4Q}E-Z zN0}cleeH<-IQM(ek5Jj4`fv{b%Ge|vKi>U@STCq>{D&NrbizmC$D{x4`Sm09RQ;@+ zS$m{Dd3|#~QZM`!>zn(LdV;5R8<8KEK6_IAztjJ>H2Q|8m5BB%Y{;Z;#Z6c!T=(h#YZA`F(q&UdTcBq&=ed`D~A>r|ReZNPY79 z=6g`?f5rOdex#n@soh54$NiK4-1+PN{YG6F{dhfo+#39tT-SVj zOfGLeKCXHw%Cr7v0G0jWS@#Loy6@I%#G%N09R9=YF(2uX98~LZ*83msw)M$D1O2sh zS%3W}e>l)zDhE`07~lK8+nR6>3QEi<-#d?awhj(0;_yXz=}|iLOiHlxSIy2JjduPf zcK*`ul$~#@+Bi4oxv?|nSFzJ2-)OWmICd-I@I`re$wPBHf7tANf3Wjb-Uqlfz7Ozs zC7!W!Y5j9!XZ8rO6MK$6p24wm5r;3z!%H3-?L0oYVdowFmyEhQ+IbmvJ~_nmeXo!G zz&9t-it~AO&ktjJPVsDBeZtRo*2A9l#8F`nROP(6eN^x-)W^d;CdXbT>7bHd^U%%^ zH&Dd`?RvQV|4BdI8Gc9X`I=W#e(J0GS@}c%uX^S6js3ssmDe}+|Ej0#XL>^a|M+{O z{Ri7WJov)s2kgfF;SD=CnIGdgzLkBat#RLJBz|NZq8@%6r#_5RP(O|%$9P8h{Wwm& zkb~~YIF8=I#_{K3A6WHN{k$KkPhQ{LkJKx#Z|+Cx3GT=7;rel6eXTwB@xibUy!B`J z@tc^^5mqz_~Y5yuZeI`WM^tt(+I+9F0F`NZC0j%)NYnKAH10 z$U*%%L*%yD`C-yQX)p9A!kv6*zu@SVKAme-Ih4Q7wStqM(;v<)+_3XI)*e3)`qgc3 zFh6daFyeld=OTzx|9k{-$(a~v`ImYBi5z_faR^m?X@|%`{qq+i=~wBOpU-}kda8cD zJyM^%zIl73UU_}<_DDU!Q@f3*U;SA>=kw$FlWqLY?6$LlA9bE~IL}!STgCRsx$b87 zN!b(Pz6gZlP}9C6F~&bLR_ zx5z>Fq&=ed`D~A>r|PHnsCwn~&DXiqE3a>CkE$oQZ;!*@ce=y;80V|o`2EmrkB!)m z%-^U7RPBQLU{9!@uOi1hmGb-fD)mARx+n8h^zwVR&sV>yda8cjkJKlxZ|+CxmDe}- zBlQGN?KXn_im}N>^&9H?~tB+jQ#Gfgfk@_3Qd?drtNhcF8{A_m8#bS`FvdAB9g!#wM%n_bb1U{=U`aSB2lN z4E1`*o)IJMH3v^pNy5~_l z$7XA_V!goMW6ysT>jl32$@m-8I}V6tpkDm?D>%QNE}VKT4Zjn8ZS>az;ddlMy`Hpp zijaEM#PECTS-r*`8Fi+3R<9rai#_{gzMOn`l0fAzczn-wsOp7&Y*efl_q*yO- zev1*m>9=dC7k&b#T*9f>@6|7^e=T`;sMi&f!tW1;dae0dtXJRbLQS%I-F$4USBhu# z+F)}}e$nzKn+rl!FZes{Icly$Rj=(|wlnod53E^BHw*{Ii1^;PwMNJ{)%FWL+FzUR2+9PZ z%lX}MERV_wPC13sPO;0++oRo}-fpjXDB2AQPQ6Cgm(+JApN#eTV)(tYP_M`TCi-j2 zVYBD@dL6tlmLbKndcF2zR?fbG^#Z^D-Hr94ocnyj-VKP_ocf|C z*v{G>b>;)U<%A>w|Ji9qQ=EGJOaH6tZ)o{tsMnSIhu7~roI&+3Kl zPu?)FUf@el9#}8RJbqiO6IAu0j!#?{>jYK3(34yn{maiD^O1kSL!DBbdVQ_7UqJK5oyUuZU%!UQeECzsF!p6q3R7RJd%7jN3MZfhlB=pB_}Ml!tHq>wxD zl-be0{oz}Z{v;}*`W(q{V9h)Gv|7sGbVDZCANit-kMez;<$7KHy87!{_6?V!_9U4a z#lpG0M`G>)G5egwy#N^QRq)~2d9(9!)>v`BsAOmy-{aOMQt_jFv4hPy5}PI@zi3U8 zm7BL-v}MJ*V27g(Q#plWhbc+R+uv;0I8S@kLA{GkUox|=%W%nZ$v$&?J7z3CE*XDd zWE=lQ-m>!_v`yZXJbrN>;{9=Dr`*1F^(>yh%%&er zEkt{Trwp4J)Py?#eR%_ z4_Q9SCtc5;CH)K2dAe}kt;oJ5lzr3mcc9J^&pQ`AE*?rc$%~gh;gpB{Rw(+)=|orvj3#ykYrN*)cQ}-_X=KhBi-%v z#YdZ`ct5QrE9{@Qgm=R@JY-<@Y-10NGO_mt)qQPn_SM0m9>2!sdf-s)C%|8ILfn&s zf?K^NayF;gdji2Z|6kmn*Y9@mZW!LfB>m!{{{6$^^?P2D7cYIn+51N?l#j>Z!M%R= zEs=+MdGSy$FTFfl)l6Rdh00fUmLHznyL2Ufkw0?#m#&b%WanuATwZ>O_Agy=gbnXJ zTS42n^{?|b1CITfLvUSl2=K3z;&WnLR~^7fk346pygWR0I{ruT{WjE@`21;qwg0K) zJK?^-Rewr+o_LzgHCl*I_FEp95VQv?fzPtJtHVQlf}@Xpmpj53D! z8J+bThfr6CXU|Q5J+*f%Ka~4R*pqs3UV`=uP5n|6Py2Ovn|SQzap}Px>A9@1&rH7X zPCo1-z2-k-S)lY~dcTwS$85m$xOgaeNM5}33IFurQ4Y#Eap5PiFJbAS9+w=?!us>` z!lAxAO3$;lUS2rV$=C2Z=h&b(e8HYQuzHyNYxuptHNHcHXOL68Ez~jfmp|twd&-~k z7jd!f#5huMt_?j$r14CC#OEcm;`K?%>+JV>7We;8@|hT)pJ6z?-S$^w|H=L}@nN43 zpWu|!;UPYW!`qLJZKzos#^08iVw3(j4=3I@<4qeQ9n{C+=k3@p@92W6e_%|2Cw@Fm zyuo9qG!C-ykP_4gm-x<9>ilWkBf(rPV(YO=W*f#9!l9HPaJ?lJuW%o4P5mV z4)x_xdg9H?3x_)S5O3c+B>q+texuxqH*ong#Y4Q|4`!+inrW!=sFX#5EO$s^-+;+8(@i2vxX@B4J@J4mN^#<$osk7s^= z>eCj_x5apVfO!6T7SEKuSv)(uA)a~vzs2*R7Pr~+X!NV;djP;2`c>ZjfZd=zo}aoV z#vxSx4KZLm@<*H>@GNfOsaqt+ZXtrwriK-{TAbX8$(I3C^<=(9|z&iYLXR;zvAk&cAKqp*{}9OP}-*Pa}y> z#$F$9yNgfSx0in|tVfe`1iFSxUFO}zYry=WK0q2!b5Z@~TYFT^3^ zgl`x47oNTe>e^9_F`RNJUX-twN1xgka$KXFc{@7P)@vu*dhM>b5`UI<^j}#!BKDf~ z&khg$Gv(ynvAq9*cXdIvE(7m7-Ntvrp&n=b2@aM0;aQ)O4qC*Wd{}o#FEq_J;L2C! z()vYup)udmm0Ay?qu38%Gu{DH><3uC@t#T6c~F&8Je2oLdK{i~9v3ftl4re!Uai|a zj{U*C9@cxvYyBsA@lY=>y;@5Z<^6h)et7By@w^K$cldfr5c_S;^3z7SPTLlKMQ@A; zuH$#%JY$I6xsHE@vu+|!uCvAwPJZa;SyHbb9)I(UqSp_Pe&(}YKRjzBp1F~Je#h#N z`po*jCSMBie>KnVU%l^$;-7Ug<)p1c73biT8yxC!<}Kh*?5{Ya-8PFu#>ZkD(l1jV zDD{&c#nUf%Ts)L?k{2(1!tZ}gl!NjS-u16BU#Q0=7gohiUO3d3N9mc{c|F3RUS9T; zz16N|UuXYpUjq9gpT18i+sA-+_7C##;7&fwPZ(!8$HlXWKK|(+@Hf|ed=k&(%XRee zp&fnG=J>=p*VXpG(Mz5@%Sag{4^O^~6+T~h@@0JS`NESgaqjblC*O{r`TdYua#?>z z{hck}jPZXM`yr<;JjV7nXrGi}+L}AxU?kfQp?&d5@hab~+i6?hQx9uIJBOL9Sdi?~ zpNxAOIO7g$4=DR}il1Ly7t8lY--z#jmOSGV^3b9@<>#Cyv_H)kJ=7N*DjXjBavdss z(LcuDNMxPMnm;X1jr`a{^Oo^Sb1UGg=P`<3avE|njh>ZzIC1D@Jnc<`gi zbDkEvPLlkFRrUQ1-)0nl9-w@Ur`$o_$}9OcaLR`sv%lh@#-0lHg?f8h`~>|*z5W_; zWBS7y*ZTz=9_saohmybS36DRZ=quuRJcM&rAzziVm@oMi%HKx3(cbU_)W;iZBlJU+ zFL45o-_tk`>rKiB@8snNnSkZJWg78 zD1CtB#Y6ck;`HUn%RcDPpVtG%M|nt(aE;;Uq5otLkN%TqG1Y%gvYzS5XK(Kx*Lvz+ z+zGwAKUlJsQ-KKkCbwNi)U_5{=&txXW((( zFZsC%dnF&cy}u4sz0mV`eYD5JK7-`Z$90pxjP)STMsTLExK8BR2aju=$TLacJbMIX zyeF>EgPp^4N;<6{#Y>-X)`Q4F zIZH2`bssp??qFsd(SL|yj zzS4cC8gT`#_)76M{L0x+=id-l@R$95#EGA@UNtYzb=8;nfmb|w9Q}$f>46t6J+z}m zXY_|T3v0w#OZFl(l1a(o>3+*k!+y)vZ>Am13+;$G2(eOJCo(5-c$g<>etY+hf%`4Y zZCRfb=eP8e*o}D&RCW_j9v&A@|LO5tZ4FJ^ARqr+m2mWp-_p462k+#!zPvxvxPQ*R z4E`U={tR-XZJ$u_qV__ZfGb{7JnSFRkIT=BXL#nm&R?NDg0WTvhf2SA#@S{#*U3li zLh?{_DqrGicl$GG{DkrhcYlU`b@E{U)9=qrtRHL7qum?l=WA$p%d>Vz+iceE93I*o z;}rFw&x6ueY8^_R@KCOU(@x)etj*D`9ys4XZr#ZP+bQh?AJU$n(hrW$!J)#%t6a8@ zyPR?=y(?$74^KIjkLd~Hqspy(OwTs-ukK)P4?>mWyZkdz&9eMH{3@0D1 zOF!ix{a`rPeZDGZ5ocUv-2!DC);K7h`1ZJXDCs0GUiySHE+PlzBb@OM9O`k&aUO(^ z>MI=T%cJz1Ve#_9p^`ts#vSId^w+dg+8H0loj89>Muqv?)x`g$FZlfJ@weNvM>cf{AEWZ3){l8NLF9&rE#4Pc<4(F=U$v}&G*34_C6nZaK5~r{>By`59kl`K%PS*PKxtA$@}Njh&OnslMm|=(Qkvi673eu=h_t#{7y8_~-xJo_)4{jO*&p!Jl|{d@nlJ@q^?^&lpJm$5<;I z9{t>F^!nk^&og^oKRj{8Tuk~W+3~C^`)AazZL!TULisPkvE0z^*srmDuHwE~8{-iB zM9{d87yDKAIkn&A_Q%3Lr}nA5{9yZ#gY6el9>ztkL*+;92Wj6(?V7gRWIt-q{VVNT zX&+AUjGp4Y6a5=F`)JVOz8UhmE)d; zh#SMh{+{2T1c!(EeMRw5)053t;juFmeX_ISK-Udto*eQ;zsjp}B1e9O@&~)IZ%({H zeY~+hPCjm*Jj6NiO*}?C&bK8;J~94FmmlNqBlN7~?&QGx2q~VeQ?$>heM;3=y!I)D zi`PD-$JvXMKH=<1f@`1By(;fbmftMI0aUK@a02?Wfr}WN`Xl zKR(ibvd>BX#y;oa>w_wrCzq0w!}Fo%#Qm8&!(#-Ye`8POsuSY9WT?u++2M~&i|0%E z?G?krI*a{Tc+L)U-S9Av6|Z#CgIA@W_9vYES$Jrwzo9&o%gd85{9w4sg?{F}^o`WM zxc;S0J3Pb{^J?aCl;yrd?0op~Q3kx{XYoEJ=iP)`mD-r!P**5E)4G-4n*@iFSBlpZ z3(8-(;!WiR$M4+lq`twwZr_zyaCkNkC%E|A#mj_4Q=d1W3zI>dB_i;kIU`>r*w#>=T+fK5lQ)n0W zCfCMs|K9Mp%&_AJf6+H`PrEpe1%K#+jqTKmT-)b2_D)dq3G+5+THhKxbsY>R9oHo< zJw=?p9KBF{A$j_KaA*;S$3}d-JUsF~U+JaYdwJnd$-lwsiwqz9#$T$xP1v~C+CH28 zJ<}TR3qSeOdf?ORtsdtZA8YfkdZsnr_e}Ya#;zX>&i$R(?|m@#dk=-jn?gTB`=VdM zXHb=g_Q^dN_A%1;VugN>eF}KmsXyl_Ug@MqdZ9i((F;Eq?(%IYr}_iwr#$Ex3|Dz2 zul&6H@cYSRkbW{5w4eO0d6+(xSRl64Pl|^Q)_)QwlAroZTMwEZV%O;z(66TTtrh!K zaM~&BF6>t9S6L%CJnL79Z_Y+QS^LPIlmUJ)oa>~My!14~c`q>^sF&AS3aD`8gtPZp z#L-`rmwx7UULG8I<*R-YyVFl{?v>A^oc$~G@cV>L ze@#61$UQC|JswA%`4!ipDku7H|EpL|f!Tc-3tyCj$Z6ZeWB8WUhGaez5T_b$K&GBnn_i-#IG^13d0 z$w6It!t+G%l&6TRoX+o|Jd|7Y^W{{1o&7_3uqXL?zf(TspdObT)ay|@FW4=VA31Qz zv%aH`qCQ*ZeEewZO2T|wIC3doqn`n1-w*lQrUv;iTNjReigzGSf6m?&W z&-!!LdyMx`<}`{E@vIX)E*|RV3F4(sdYI=U2lewD@ldZ{II{f7kBndFfqFgSpA<@PyM+1uamFF`Rz0F=U2;%7h_M(3^GS}U;;bhW=i{j69*2@`~}Y3B$dzn zg&v0ozpy@H-pkyGF%_zMfio8e_xHKrnL}|M>g5@WxDJ(_S^JV6>T%9(V;3lMQ0b98 z@7MJC!Y{u!>H$yXYbpnNTzP8Zm5=0U`?OD}(_drn9UR&WS330%DmT>GE#wO?yDDGR zM|SmkkXQY@9k3U;w;TM9*eMaj3Iiv{(KVKm3Li@Je2FQn|P%Yj$X>C@=8BAdQ@K3OZJi7Qu#LIu%mG4Ctv&lb#|^%4tS{d zm*k7M+NbhCKm9XtK$>Fz4Bo7NrcU&!%=4kDmw2f6qj=JJT)gy24?KM?`*l#^;?dU( z=eqh;`Zx5@=Ym7M9(eRL!;#m#Zc;Km`HG#dKECCfp?}`~iuvf~!z^hP--YY)XU`Xj{i~gt8m#_{?>JH`cKZ;@G176$SGf_%8wp+U01#;pUPjvk@w|?$8M7MTl*&~F4=7VCgD9=dl`+Z{~YH% zTBDNWx_P~J(e9IOpUgiK?7cm_Ev&ur>Av>6NpGL!%!f#Bs^*9Xq3^+jhnpKkbf1qko^zVRo%pp4Zt9#P@zP;hA@hK9Axi)mr&zT>vh;mj{I-XAZY#hG5=Q-1wSdfz7P*t8>cY-jk1t_}FWAhBI`B1q0dQ$3Dn|a~3D!pKZYL)nU9R?F5@(IC;+E z9F{EY?JeL>Uopz`%+%}FGX2!e@I`ap6x3w+J3rkDZi;f8^56XVSpJSF^XDyIa8y>W z2M^t8^}@IJhXkrGb%^*Q4LI-c#txM!3wkRvb3ND$ygX%I@50nRJ-rAIzvwLfKdGI566}+0`*a*A=?#jQW zcXYtZ;Gz6q4siv382)7@T@} zoC<@3IlQX+YK@har>gpD%_Lm)rA}Ut>Wd#euKMD4kE_1KiN{r6;>zQyFLCH`>dUzQ z*n#nPuKjZ>%$N8*9>zr|dl!t$CV$9J{wU(b^Nq+c9xI*6hx1NK&+qm~kMy%wqI4Sf z;lYuI3K#G7v~5okTJpa3cdGrZTf1TP3LBbVZ8(_5LE((c``EUB9G6>fI)7nz&(S6q z-*0(!>j%%i!?^G{gMW`p4r=;B!}xy7t6P6??~_s5jwwg^1IHgE#8Ko&C0Dn;<-iP_ zo5~+FK7;ZvX?aFX{QCz5_C@)@%QM>gweB-dko;^4#QO}Jm8V@&Mwvg%Bxvn3VSAFi z(rD3cuQRLN|7?4I7r!HHpYEPz%b<)GdhY4KWa&IGK2wtu0%bf}>fURLJYzeb4(UP(9Qpx@ zVjplm>=&ds-9y0XPxz!b-9u=n>?bqtFYXWUt_AXFoS&E5j=sJA8`c-SKeqMp%H)7} zU%1@%g-OX?#wQQIIjld%2{-w$u1oQBonEdz^_Ove|6M!Rk#3gF+#lBy%6a!BTgR_V!hLPtGw|{Lw>`VGAkb5@e; z;moAD5P8W#-~Rc$zY@>BzQ@Hw8Ed3pJn1|x9_sT|IiX&^cw*P%;-Ox@c+z=XJXHBI zUT|LR%v0@|%gIxC?^$@ykIjj&dZ_1Sn^W^gy-Xr}Cmy7*X8^%zHyvx^Gn?S-frGOr?s4{Y!9V^9+dFXb ztPkPYnHd>iPNJVV zcJ=lp3u-n&QGY@kDE2ebS?p)f&o$rA$d6pZ{`@IEk3Yxmxm{vy{!&}N-;nR){qo&8 z&bHk4;Ja*`O zI;$amc-HEn_uII(J)WO@+PVPZN_@ZR!90`5ShA zU_vR2f8vcbki$c~nRCNn$NSbVTRUN^RWF0RW(hyg* zhu?4aN4o6n)MxBmq4mkaH_WxM)bOLvxATEH-ZuF^?7epH;ytuE{(9TR_+b70$=c+b z$uC9`p|$PkG5gf+|6}{TfDc(+jox&Zy)Qi4E#UCC{k6SA{~I|j{)|O-w#MP&yH?rR z9j8Y;lzgOLyz&<=UgeQr#4CT{;+4N}@ycJgc;)YL*#Qdvn&pYT@AR?y;|Fcqmw7gy z%k8gc2k%9<|5}n|VZaGj?DtxB#I`kV{a)s23jy;1pB@{hm~S1{k}N{LtH+FIpR%D- z-nw@(_rX*?pw?g5JmkiYk4YZdXG}Uji5EJPmgNiQ?VUXM%0}GlCvb}Tv+_9oYrZ%p zIr_(=2k56fQ-0Ej_iWG0Pasz==nR_5+wC{WKQJcLA=EdWAa!hSIh%5B{>{RR7&zeYuW*@Ui|%}ntZ&ouGp^<&S`CU38Yd^6>#bj_c;%_#obvEP9S z`w0#8HGh5oKgK0HFJa%HWQR3O*gp7c`6mxdzIsq29{n{cIne5hzpCAvf;{@iefPky z|5nsL`|k0{n9YrP(Erqr#wQQ#--vtt_^YU&{gY<;Hy@w+-If2*e;c1%@`X_i_3AO( z;PsM?Q>g4f;nVdqw}w zBYyB3(kUahG`!v)Gdv0pqFX;DvjPV)UZz%tKN^j+V zG{*mcc(C|<>asD(!}~P)h4?JLWlVD4O^tS@eT`B1Eg<^l)M~x95~Y3Nt7UI|WkY<@ zzLwwLnoRn^D`NR$aT40s-G_`$_W4C4?%NkF*S9bFo@VXqiJf~T&Dz(i{>|!CXkYf? z(4>BK{pw`9{b!$34kxOUq+~uXjXi&_8^&H}9bEo-qkRqWlSAR#cHtT?aiqAm4qkb3u>vr`=a})yBuSJpI!H zLjO!$W2@kRv8Y z2aV+!6>#?Lb-h?l@Vxx3K_1@cd!*G@Jm*gJ0atxJF1wA9U`k~-*+KS^9(b>ZIQfSI z?@b;#u)V=G=znDsJAm(Nc!RKE*pvQ&Jp-uhUpnDndjr72)?3EBdY`n2fxNNAZ^bmx zv!nbL%E;Ij%4++;!7nC{^nf@qdGcc4*vlWeBMExIeSIgV`X!&eN9B&nTkt77dNTaR zmJG*d!m-1+X64_WyhUY=zgz~l$S;f<|9{~ZVI6JpBi5B*ZGR{jtErF`u3`*Px6 z@xH!CT6t72kE2KBq>Mh_{hO83Z+wdW7B~O1NJp;=hw%e0f z{;NiBIq=&9%1=3)m7o5nh+}{9rQe_)P}wuXT|c1mo5>qKDnIEdzw{is{Z$S2*A2Fk zZ5y1w*TUAv4?5Qdw)}&B+IzEd(w>PoDEE;lC*>DE<*NrZ;Nqb^{;_|c?Lm8h#dA7F(93EXBhi7c_IQ3-xJp!(xY|+@9PULy&hLQq|>S_57`qx$v=uK@m|lN_l#|bliBG;b?Jn? zt>6CGUSAq>OT!RDzO1K;^`bw=nnir_j>)0?)OnNj(@@GI`wx)c9_ve;`I9{Tn0R0Q zn$7oKyRjwN_lb1Ams(;#y=()3PpsD%tJnPvp{Vi~{Z2WVFAXT?9n~=I5EGOOO1)Gb z_%M$RxmtZo_CCR2p%h5TWYa@>#v`xi$Q`l1=<)SE)LKyEe2-O<)ytx}H1=CI-|KGb zuVS1}wz#5AU|;C=T0TzEP7h4WCqh3XIp&9wKlGk`3guzdW92#F6&63`F{iZ_`k7K3 z_XpT>M=gwBvDwTsCq4$s`eg_9)!@ z<)HB&n)r@I_T1MgU6t;t{chGd$IqIx=)~iupL2Za)Wx$(D>rV~uzKZ|jhmZEBy&oA zr8%YE(vs4m(t^?{rFr&!adOV zOQGGPm? zR^=44ZyDB|Vclk=*>lNBDrPQAdKWI}YoBu}ez9*e7tK3k&g@d}%!M<1=MCzj-X&N* zG16J>G1678RgHAlI%>(Rj?PL?WoAlerL;Gtvy&xDsInvIQcA1Wu3p?98IwLha@ZBlZ^`3Gvr!uXly~9Xnd*{q$ z^JeyiuU+}q8R^&RG?Q4G%n3A-u1LBg>EL3uy;4?!YP-}JEHyP#V^y3}g-Eiq;c`zh zr&i9d^1Yf$@?A=6rXj=adxvD~yO-%n@eYUc-Qm?rE>o3Glc~xiCSIP_nat^I?+K*r zE|uGBsz|3#(&_N_8B5a~x~abzE>Np!#Z=)1BWBt7C6Zc%&Bx`Q&fdlCl|}ku%{n48 zGic^%Nu@TUx390=+JnAjSS`b9hIN#C`{uTnd&~{#_lmV6_q`*jbehZ=sZ9JHWwP(c z)O!1twwF7~o!R$J_r1$~?P7`gfnQZp;v}Dfo?rN7g(`2)+ z)>BNkF4v;k%$j{YEi~IsYbw>Lo$Xz7=rnfIRal?gUaod5D|d8QZ_D@2Wo2uY;d`x| zfA4VLJKguL_`TN>oNWoCGHcH{ZwkBV!qe-u0^d>KJ5ye|C|LOJaHRpKkm%<-1at3?mKbK?;=XtCz03A3tA^K>Rcf{Py|W|#-j#hnyV7ZLU6!UN zM5vX+uJu?N%7mQ0cO#SHJr18yF}#}CI2rU*yL#gH?v7>I_nz+Td!^iyf3MWycj_>s zwyb82xN6@khG*Yv9ohG4xifsP(b3hqm({vElJMQipMCF1zoTbHby-KHC#l)@YPlA^ z2V19p1h1ISkO_9|GJBcrLK(~sSsA)xd3vo~R!>gi56v5~$%JuCCIYFHAw3mD%p_b3 zKfxS`aW=)trzhtef83_y_gT4S?WX4npIW+f#U-mt7j0a(YW3!|8_s*N=-tzDy_|l} z{QBFlACtaPd0M4hI;~mQrI)LnyS!Yf?)vf`Dc`fa2TQ$W>!#Hu)&o;Z=WSlQs?=Fp zzrL9PigGqn8KR_3V35@6qDdbj-Q8&!%n4b7>aGftC8*{JI){{?QyJL0W(Xznb+GB~ z5K`>UIx2c!}34c2vU3aTmo=^j3DKTY@np(BZiU!pSZE+nI(Sz!?>#Av*B3*6|n!>IRwKTbC*R)ztuf_Xd+PSXsq-NAQe-}wQ zm85%Gch9a&ANLAW{OG3n^G=y}Hr;%C+&-{;dgt`orp(%Ht4oV)9#pA>t(`@y&t13i z($Zp0QkVo?wDIE2D_56ht=@Xk$~Eg&oR>5z3nNNXWv4OU8M3Odg;6M1t-I1WqH={@ zkinD@qiNrA0XN;5B8yJ8*H4JFU_hw?e{K3i67*s@~X#i2iN%fjbNLOV@X);WE1dY3F( z(0BThdA)w~DrSAo##LKw)W0l@{8LMtZOd}ShV#~~&Ra(ZO)2V|Mg4}LuX|e8pc*@; zl|$o<8heMRu~MDZZ7NZ`e*M5=+D1%;E7?xk(8_6Asd^y0RJ&VstJbbqzk18+%_Xc= zu-$JdF~K_GoTFL86wquETt4(-?@{9JJt_7cB@Xk<)MARtp;x-X5=_|Hg?v4zhV7VIe=)h>yO_iaSrh8B| zL#TaTnyx|B*e#u*m!_wgn%yQ3Lx7H)pA)q7j9kkwTD(>-t|rxB|2ea46TNfx z5DU>vjm?&Z9ze|$>{;^RxU)&_ar-?S6gt}ux>z{Qv^~kS8!ld7TD{J;{x)x1w{^?f zm8F#{Hmz8>)($UT6gF`;$4&3-&ODpmi|5ZSP3g7U|3{S;+m_*~6`NO;OmV4qF;~}Y z*|O=_>C-R0^wMePtX#Qq{icl@R&UsH(KP!yJswm#yAt+!hm?Qg{p05*cRMEa!dBl- zXAQLg&uRU25bQatf8WLp=au@_p1Znas!MjlIVsX}>$W{AQhqFU2#!+&%bQ#&?_id$-fTnkigo6qnz?A{5L^^9 z=N#?}mN^H1U$D%3?4uW3W~z^=e^JTEfZ0ljqEzv!pb$ zG`%!u-po>Zguj%Yv5CtKg=Q38+#p)@hy90@ML0<^lnk=x2EtTv@H)&=!Qul4yQ;$y zFKW*>WLbo%;Lx)ev<}4#vZow&Q-|KPVCmx#yQ;&fUeq3%%Cgu^9g10;w!&tQ&HPZz zAbTcbH+7hu7A!o>Q4MFdXf82&mNr~0Pfg=*nTI=SjrI0VgX}WIo{OBFIr8UCc2nay zDt&xVrLpw1o?O#zoKw`~N)z;C&${fUM2n`=n$t&Qnv^HgvzziX>M53H;mlKJE?#iT zyxy~CGRiDmv0=qU8#mbIMI33@+MdQ7zo(IRJxdq2FSaKPR+kp8Sb4#U^H!H;hU(=C z!#SrtQ8=rhFdTE*6NSA6g<%V8PZZ8BD75F5_RNNJ3JTw}rwZRxPiZ!d?07q#_!b9 z#*4S`O4?G@ZlPXQ>IgSd?NKWC_}(y7=-_3lAbsX<$O>xdDa$l@`k3I5lT(4P9UY6G zK3O>AKdqsI;H1>b5-fn zcEeJ|{rM)U(uXI9rHaE!O;n}NY7R@4-Glb3!lRw>`O`tw#9pw`)LGOA1-mhHQNe%` z?9L{Q3JTVs1nE<#L#zUgCUY^#(+5|Fn0!F-cjt%3;y3X?`cUi;^QY(y708~dZKh!E z#?5QDZRF^=4!bpUVg+UPIH?}XZKf>rgVA((KUkYqwer}#rf@sC*FVlXWE~w%bfk{~ z4_SvD0E^`aV{ET~e0WeDR_b`KQsLcUwXn+6(#ixS>2t?JSHj_%qLTE1<)JI-8la@% zN$1@uvOcncMf`}>6)n`04q4#=>GWag!POO`H&m@h_M!Qt&sYytMOv{273rhdLsikO zio}o$6-l4y9;ynAU_NRnMfxE4P*u#BR*5RYVGw&lD1Ux@P!;KuTY2k=KB;zvgOfaG zZA#Jy&xfw0J5;7oN&3Y4(3SLr2P_(t=u!8fE3pREV@7Gzl0GCq3@w$=40A2?OX=hF zgKH^vOf!O#S|vO(Vy5L;`SiK`p)0AxqBLqrpXeWkmRj&ogBHCDVCY(^9Qe7clxgvA z5g1fUEgo3NBhETEo}{S}G^V!*VU014h5mIAgX*Xjl~_sWBeQS|TGAIu3`0wILo+0y-4|YO+cbrZ&bULz zqv!*7jM%}Ozk17NQf*vik4*AVroGrW+)~=LKHJM2s=h9Jr_654XRpi{qCWP&cB_wf zZwygic&*g#%2%n{iP)z5=L77=o56NpK6@L;5cPF*+KaAsTRwZO$dL7Qh5NU=^e^ux z8KS<1&@GzMPuTzWFJzG*Wwg50a-YG*YQWxk^t?5v!#*bZHWQN81QL*BU(FGH+6rP>3ct zc{GKsh)wbECWK;5PqhjZqzkO-H4qNfYzjBYDjH#cbhJqUes0*3Jz2cql$qhxZ|SqX zgIjv$lKFE^oY`~qLaZ@=Uhkp>y$ep^Io!TE*%nt%>Ev^^ZdrX%=}mnz7l#8fmC^+f zS-fcGe7Ze*nO`X)bLK2uv>;%oE}pq)2^TxsSFTxMuNkzn0Ois-Yqyl_r})6D8Qvq< ze)+I_$}$Vd>hvWG7V`st3uko&pb`N4Wxs{9YE$MfSZu#q8826-EM9EiE3@pzKZHw*A=R!rrba)6GhAmK>GLp4Z3Q=y(s-?2GNV z!n_T3NNmGuUTkP@TB()RZdkb{S-A0{wOiKOQ}AY_r3?C&%sg?9S^30M`($ORvp76o zf9!GRY|aiAu3WKl&FX0zR%}_jal?vr;aK6Si>CL@xBt6)`pTWtHmy3>%X1L%+!bp# zuUxZs-KvXLuU}h85>q67<-7XIclT93)mOQzuX1-^_0FVxSNYTByDOin+*P@IxU5xb z$%6J7RrLzSSbrtXdSo+8uf5$dy$_)ai|5bm>nkldbxGg6Q|6SGEShO3gOlaDbzn+i@@ebu?Lf_u&Gr15i nYHcP|Zol#1OcQTCZ6@^k11`*k_8vs&QwMx~pAXr`E+_v#gIBV+ diff --git a/tools/avrusb/circuits/with-zener.png b/tools/avrusb/circuits/with-zener.png deleted file mode 100644 index 0ec88933bf8f4fe48c4d3868d27fc69d3ef90e09..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13421 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 diff --git a/tools/avrusb/circuits/with-zener.sch b/tools/avrusb/circuits/with-zener.sch deleted file mode 100644 index e7da8e5f44d57b43c14edfeeb390af334c364464..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 225561 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 bCL*&{32m&unhLGu2z^@rcKZW<*v -#include "opendevice.h" - -/* ------------------------------------------------------------------------- */ - -#define MATCH_SUCCESS 1 -#define MATCH_FAILED 0 -#define MATCH_ABORT -1 - -/* private interface: match text and p, return MATCH_SUCCESS, MATCH_FAILED, or MATCH_ABORT. */ -static int _shellStyleMatch(char *text, char *p) -{ -int last, matched, reverse; - - for(; *p; text++, p++){ - if(*text == 0 && *p != '*') - return MATCH_ABORT; - switch(*p){ - case '\\': - /* Literal match with following character. */ - p++; - /* FALLTHROUGH */ - default: - if(*text != *p) - return MATCH_FAILED; - continue; - case '?': - /* Match anything. */ - continue; - case '*': - while(*++p == '*') - /* Consecutive stars act just like one. */ - continue; - if(*p == 0) - /* Trailing star matches everything. */ - return MATCH_SUCCESS; - while(*text) - if((matched = _shellStyleMatch(text++, p)) != MATCH_FAILED) - return matched; - return MATCH_ABORT; - case '[': - reverse = p[1] == '^'; - if(reverse) /* Inverted character class. */ - p++; - matched = MATCH_FAILED; - if(p[1] == ']' || p[1] == '-') - if(*++p == *text) - matched = MATCH_SUCCESS; - for(last = *p; *++p && *p != ']'; last = *p) - if (*p == '-' && p[1] != ']' ? *text <= *++p && *text >= last : *text == *p) - matched = MATCH_SUCCESS; - if(matched == reverse) - return MATCH_FAILED; - continue; - } - } - return *text == 0; -} - -/* public interface for shell style matching: returns 0 if fails, 1 if matches */ -static int shellStyleMatch(char *text, char *pattern) -{ - if(pattern == NULL) /* NULL pattern is synonymous to "*" */ - return 1; - return _shellStyleMatch(text, pattern) == MATCH_SUCCESS; -} - -/* ------------------------------------------------------------------------- */ - -int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen) -{ -char buffer[256]; -int rval, i; - - if((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use libusb version if it works */ - return rval; - if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, 0x0409, buffer, sizeof(buffer), 5000)) < 0) - return rval; - if(buffer[1] != USB_DT_STRING){ - *buf = 0; - return 0; - } - if((unsigned char)buffer[0] < rval) - rval = (unsigned char)buffer[0]; - rval /= 2; - /* lossy conversion to ISO Latin1: */ - for(i=1;i buflen) /* destination buffer overflow */ - break; - buf[i-1] = buffer[2 * i]; - if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */ - buf[i-1] = '?'; - } - buf[i-1] = 0; - return i-1; -} - -/* ------------------------------------------------------------------------- */ - -int usbOpenDevice(usb_dev_handle **device, int vendorID, char *vendorNamePattern, int productID, char *productNamePattern, char *serialNamePattern, FILE *printMatchingDevicesFp, FILE *warningsFp) -{ -struct usb_bus *bus; -struct usb_device *dev; -usb_dev_handle *handle = NULL; -int errorCode = USBOPEN_ERR_NOTFOUND; - - usb_find_busses(); - usb_find_devices(); - for(bus = usb_get_busses(); bus; bus = bus->next){ - for(dev = bus->devices; dev; dev = dev->next){ /* iterate over all devices on all busses */ - if((vendorID == 0 || dev->descriptor.idVendor == vendorID) - && (productID == 0 || dev->descriptor.idProduct == productID)){ - char vendor[256], product[256], serial[256]; - int len; - handle = usb_open(dev); /* we need to open the device in order to query strings */ - if(!handle){ - errorCode = USBOPEN_ERR_ACCESS; - if(warningsFp != NULL) - fprintf(warningsFp, "Warning: cannot open VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); - continue; - } - /* now check whether the names match: */ - len = vendor[0] = 0; - if(dev->descriptor.iManufacturer > 0){ - len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, vendor, sizeof(vendor)); - } - if(len < 0){ - errorCode = USBOPEN_ERR_ACCESS; - if(warningsFp != NULL) - fprintf(warningsFp, "Warning: cannot query manufacturer for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); - }else{ - errorCode = USBOPEN_ERR_NOTFOUND; - /* printf("seen device from vendor ->%s<-\n", vendor); */ - if(shellStyleMatch(vendor, vendorNamePattern)){ - len = product[0] = 0; - if(dev->descriptor.iProduct > 0){ - len = usbGetStringAscii(handle, dev->descriptor.iProduct, product, sizeof(product)); - } - if(len < 0){ - errorCode = USBOPEN_ERR_ACCESS; - if(warningsFp != NULL) - fprintf(warningsFp, "Warning: cannot query product for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); - }else{ - errorCode = USBOPEN_ERR_NOTFOUND; - /* printf("seen product ->%s<-\n", product); */ - if(shellStyleMatch(product, productNamePattern)){ - len = serial[0] = 0; - if(dev->descriptor.iSerialNumber > 0){ - len = usbGetStringAscii(handle, dev->descriptor.iSerialNumber, serial, sizeof(serial)); - } - if(len < 0){ - errorCode = USBOPEN_ERR_ACCESS; - if(warningsFp != NULL) - fprintf(warningsFp, "Warning: cannot query serial for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); - } - if(shellStyleMatch(serial, serialNamePattern)){ - if(printMatchingDevicesFp != NULL){ - if(serial[0] == 0){ - fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product); - }else{ - fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\" serial=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product, serial); - } - }else{ - break; - } - } - } - } - } - } - usb_close(handle); - handle = NULL; - } - } - if(handle) /* we have found a deice */ - break; - } - if(handle != NULL){ - errorCode = 0; - *device = handle; - } - if(printMatchingDevicesFp != NULL) /* never return an error for listing only */ - errorCode = 0; - return errorCode; -} - -/* ------------------------------------------------------------------------- */ diff --git a/tools/avrusb/examples/custom-class/commandline/opendevice.h b/tools/avrusb/examples/custom-class/commandline/opendevice.h deleted file mode 100644 index 5e9b68b..0000000 --- a/tools/avrusb/examples/custom-class/commandline/opendevice.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Name: opendevice.h - * Project: AVR-USB host-side library - * Author: Christian Starkjohann - * Creation Date: 2008-04-10 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: opendevice.h 692 2008-11-07 15:07:40Z cs $ - */ - -/* -General Description: -This module offers additional functionality for host side drivers based on -libusb or libusb-win32. It includes a function to find and open a device -based on numeric IDs and textual description. It also includes a function to -obtain textual descriptions from a device. - -To use this functionality, simply copy opendevice.c and opendevice.h into your -project and add them to your Makefile. You may modify and redistribute these -files according to the GNU General Public License (GPL) version 2 or 3. -*/ - -#ifndef __OPENDEVICE_H_INCLUDED__ -#define __OPENDEVICE_H_INCLUDED__ - -#include /* this is libusb, see http://libusb.sourceforge.net/ */ -#include - -int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen); -/* This function gets a string descriptor from the device. 'index' is the - * string descriptor index. The string is returned in ISO Latin 1 encoding in - * 'buf' and it is terminated with a 0-character. The buffer size must be - * passed in 'buflen' to prevent buffer overflows. A libusb device handle - * must be given in 'dev'. - * Returns: The length of the string (excluding the terminating 0) or - * a negative number in case of an error. If there was an error, use - * usb_strerror() to obtain the error message. - */ - -int usbOpenDevice(usb_dev_handle **device, int vendorID, char *vendorNamePattern, int productID, char *productNamePattern, char *serialNamePattern, FILE *printMatchingDevicesFp, FILE *warningsFp); -/* This function iterates over all devices on all USB busses and searches for - * a device. Matching is done first by means of Vendor- and Product-ID (passed - * in 'vendorID' and 'productID'. An ID of 0 matches any numeric ID (wildcard). - * When a device matches by its IDs, matching by names is performed. Name - * matching can be done on textual vendor name ('vendorNamePattern'), product - * name ('productNamePattern') and serial number ('serialNamePattern'). A - * device matches only if all non-null pattern match. If you don't care about - * a string, pass NULL for the pattern. Patterns are Unix shell style pattern: - * '*' stands for 0 or more characters, '?' for one single character, a list - * of characters in square brackets for a single character from the list - * (dashes are allowed to specify a range) and if the lis of characters begins - * with a caret ('^'), it matches one character which is NOT in the list. - * Other parameters to the function: If 'warningsFp' is not NULL, warning - * messages are printed to this file descriptor with fprintf(). If - * 'printMatchingDevicesFp' is not NULL, no device is opened but matching - * devices are printed to the given file descriptor with fprintf(). - * If a device is opened, the resulting USB handle is stored in '*device'. A - * pointer to a "usb_dev_handle *" type variable must be passed here. - * Returns: 0 on success, an error code (see defines below) on failure. - */ - -/* usbOpenDevice() error codes: */ -#define USBOPEN_SUCCESS 0 /* no error */ -#define USBOPEN_ERR_ACCESS 1 /* not enough permissions to open device */ -#define USBOPEN_ERR_IO 2 /* I/O error */ -#define USBOPEN_ERR_NOTFOUND 3 /* device not found */ - - -/* Obdev's free USB IDs, see USBID-License.txt for details */ - -#define USB_VID_OBDEV_SHARED 5824 /* obdev's shared vendor ID */ -#define USB_PID_OBDEV_SHARED_CUSTOM 1500 /* shared PID for custom class devices */ -#define USB_PID_OBDEV_SHARED_HID 1503 /* shared PID for HIDs except mice & keyboards */ -#define USB_PID_OBDEV_SHARED_CDCACM 1505 /* shared PID for CDC Modem devices */ -#define USB_PID_OBDEV_SHARED_MIDI 1508 /* shared PID for MIDI class devices */ - -#endif /* __OPENDEVICE_H_INCLUDED__ */ diff --git a/tools/avrusb/examples/custom-class/commandline/set-led b/tools/avrusb/examples/custom-class/commandline/set-led deleted file mode 100644 index c69614625601155d056a5cb068308c4a503fcaaa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23225 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Ⓢ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 diff --git a/tools/avrusb/examples/custom-class/commandline/set-led.c b/tools/avrusb/examples/custom-class/commandline/set-led.c deleted file mode 100644 index 3f167dc..0000000 --- a/tools/avrusb/examples/custom-class/commandline/set-led.c +++ /dev/null @@ -1,135 +0,0 @@ -/* Name: set-led.c - * Project: custom-class, a basic USB example - * Author: Christian Starkjohann - * Creation Date: 2008-04-10 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: set-led.c 692 2008-11-07 15:07:40Z cs $ - */ - -/* -General Description: -This is the host-side driver for the custom-class example device. It searches -the USB for the LEDControl device and sends the requests understood by this -device. -This program must be linked with libusb on Unix and libusb-win32 on Windows. -See http://libusb.sourceforge.net/ or http://libusb-win32.sourceforge.net/ -respectively. -*/ - -#include -#include -#include -#include /* this is libusb */ -#include "opendevice.h" /* common code moved to separate module */ - -#include "../firmware/requests.h" /* custom request numbers */ -#include "../firmware/usbconfig.h" /* device's VID/PID and names */ - -static void usage(char *name) -{ - fprintf(stderr, "usage:\n"); - fprintf(stderr, " %s on ....... turn on LED\n", name); - fprintf(stderr, " %s off ...... turn off LED\n", name); - fprintf(stderr, " %s status ... ask current status of LED\n", name); -#if ENABLE_TEST - fprintf(stderr, " %s test ..... run driver reliability test\n", name); -#endif /* ENABLE_TEST */ -} - -int main(int argc, char **argv) -{ -usb_dev_handle *handle = NULL; -const unsigned char rawVid[2] = {USB_CFG_VENDOR_ID}, rawPid[2] = {USB_CFG_DEVICE_ID}; -char vendor[] = {USB_CFG_VENDOR_NAME, 0}, product[] = {USB_CFG_DEVICE_NAME, 0}; -char buffer[4]; -int cnt, vid, pid, isOn; - - usb_init(); - if(argc < 2){ /* we need at least one argument */ - usage(argv[0]); - exit(1); - } - /* compute VID/PID from usbconfig.h so that there is a central source of information */ - vid = rawVid[1] * 256 + rawVid[0]; - pid = rawPid[1] * 256 + rawPid[0]; - /* The following function is in opendevice.c: */ - if(usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) != 0){ - fprintf(stderr, "Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid, pid); - exit(1); - } - /* Since we use only control endpoint 0, we don't need to choose a - * configuration and interface. Reading device descriptor and setting a - * configuration and interface is done through endpoint 0 after all. - * However, newer versions of Linux require that we claim an interface - * even for endpoint 0. Enable the following code if your operating system - * needs it: */ -#if 0 - int retries = 1, usbConfiguration = 1, usbInterface = 0; - if(usb_set_configuration(handle, usbConfiguration) && showWarnings){ - fprintf(stderr, "Warning: could not set configuration: %s\n", usb_strerror()); - } - /* now try to claim the interface and detach the kernel HID driver on - * Linux and other operating systems which support the call. */ - while((len = usb_claim_interface(handle, usbInterface)) != 0 && retries-- > 0){ -#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP - if(usb_detach_kernel_driver_np(handle, 0) < 0 && showWarnings){ - fprintf(stderr, "Warning: could not detach kernel driver: %s\n", usb_strerror()); - } -#endif - } -#endif - - if(strcasecmp(argv[1], "status") == 0){ - cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_GET_STATUS, 0, 0, buffer, sizeof(buffer), 5000); - if(cnt < 1){ - if(cnt < 0){ - fprintf(stderr, "USB error: %s\n", usb_strerror()); - }else{ - fprintf(stderr, "only %d bytes received.\n", cnt); - } - }else{ - printf("LED is %s\n", buffer[0] ? "on" : "off"); - } - }else if((isOn = (strcasecmp(argv[1], "on") == 0)) || strcasecmp(argv[1], "off") == 0){ - cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, CUSTOM_RQ_SET_STATUS, isOn, 0, buffer, 0, 5000); - if(cnt < 0){ - fprintf(stderr, "USB error: %s\n", usb_strerror()); - } -#if ENABLE_TEST - }else if(strcasecmp(argv[1], "test") == 0){ - int i; - srandomdev(); - for(i = 0; i < 50000; i++){ - int value = random() & 0xffff, index = random() & 0xffff; - int rxValue, rxIndex; - if((i+1) % 100 == 0){ - fprintf(stderr, "\r%05d", i+1); - fflush(stderr); - } - cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_ECHO, value, index, buffer, sizeof(buffer), 5000); - if(cnt < 0){ - fprintf(stderr, "\nUSB error in iteration %d: %s\n", i, usb_strerror()); - break; - }else if(cnt != 4){ - fprintf(stderr, "\nerror in iteration %d: %d bytes received instead of 4\n", i, cnt); - break; - } - rxValue = ((int)buffer[0] & 0xff) | (((int)buffer[1] & 0xff) << 8); - rxIndex = ((int)buffer[2] & 0xff) | (((int)buffer[3] & 0xff) << 8); - if(rxValue != value || rxIndex != index){ - fprintf(stderr, "\ndata error in iteration %d:\n", i); - fprintf(stderr, "rxValue = 0x%04x value = 0x%04x\n", rxValue, value); - fprintf(stderr, "rxIndex = 0x%04x index = 0x%04x\n", rxIndex, index); - } - } - fprintf(stderr, "\nTest completed.\n"); -#endif /* ENABLE_TEST */ - }else{ - usage(argv[0]); - exit(1); - } - usb_close(handle); - return 0; -} diff --git a/tools/avrusb/examples/custom-class/firmware/Makefile b/tools/avrusb/examples/custom-class/firmware/Makefile deleted file mode 100644 index e909fc6..0000000 --- a/tools/avrusb/examples/custom-class/firmware/Makefile +++ /dev/null @@ -1,164 +0,0 @@ -# Name: Makefile -# Project: custom-class example -# Author: Christian Starkjohann -# Creation Date: 2008-04-07 -# Tabsize: 4 -# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH -# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) -# This Revision: $Id: Makefile 692 2008-11-07 15:07:40Z cs $ - -DEVICE = atmega168 -F_CPU = 16000000 # in Hz -FUSE_L = # see below for fuse values for particular devices -FUSE_H = -AVRDUDE = avrdude -c usbasp -p $(DEVICE) # edit this line for your programmer - -CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0 -OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o - -COMPILE = avr-gcc -Wall -Os -DF_CPU=$(F_CPU) $(CFLAGS) -mmcu=$(DEVICE) - -############################################################################## -# Fuse values for particular devices -############################################################################## -# If your device is not listed here, go to -# http://palmavr.sourceforge.net/cgi-bin/fc.cgi -# and choose options for external crystal clock and no clock divider -# -################################## ATMega8 ################################## -# ATMega8 FUSE_L (Fuse low byte): -# 0x9f = 1 0 0 1 1 1 1 1 -# ^ ^ \ / \--+--/ -# | | | +------- CKSEL 3..0 (external >8M crystal) -# | | +--------------- SUT 1..0 (crystal osc, BOD enabled) -# | +------------------ BODEN (BrownOut Detector enabled) -# +-------------------- BODLEVEL (2.7V) -# ATMega8 FUSE_H (Fuse high byte): -# 0xc9 = 1 1 0 0 1 0 0 1 <-- BOOTRST (boot reset vector at 0x0000) -# ^ ^ ^ ^ ^ ^ ^------ BOOTSZ0 -# | | | | | +-------- BOOTSZ1 -# | | | | + --------- EESAVE (don't preserve EEPROM over chip erase) -# | | | +-------------- CKOPT (full output swing) -# | | +---------------- SPIEN (allow serial programming) -# | +------------------ WDTON (WDT not always on) -# +-------------------- RSTDISBL (reset pin is enabled) -# -############################## ATMega48/88/168 ############################## -# ATMega*8 FUSE_L (Fuse low byte): -# 0xdf = 1 1 0 1 1 1 1 1 -# ^ ^ \ / \--+--/ -# | | | +------- CKSEL 3..0 (external >8M crystal) -# | | +--------------- SUT 1..0 (crystal osc, BOD enabled) -# | +------------------ CKOUT (if 0: Clock output enabled) -# +-------------------- CKDIV8 (if 0: divide by 8) -# ATMega*8 FUSE_H (Fuse high byte): -# 0xde = 1 1 0 1 1 1 1 0 -# ^ ^ ^ ^ ^ \-+-/ -# | | | | | +------ BODLEVEL 0..2 (110 = 1.8 V) -# | | | | + --------- EESAVE (preserve EEPROM over chip erase) -# | | | +-------------- WDTON (if 0: watchdog always on) -# | | +---------------- SPIEN (allow serial programming) -# | +------------------ DWEN (debug wire enable) -# +-------------------- RSTDISBL (reset pin is enabled) -# -############################## ATTiny25/45/85 ############################### -# ATMega*5 FUSE_L (Fuse low byte): -# 0xef = 1 1 1 0 1 1 1 1 -# ^ ^ \+/ \--+--/ -# | | | +------- CKSEL 3..0 (clock selection -> crystal @ 12 MHz) -# | | +--------------- SUT 1..0 (BOD enabled, fast rising power) -# | +------------------ CKOUT (clock output on CKOUT pin -> disabled) -# +-------------------- CKDIV8 (divide clock by 8 -> don't divide) -# ATMega*5 FUSE_H (Fuse high byte): -# 0xdd = 1 1 0 1 1 1 0 1 -# ^ ^ ^ ^ ^ \-+-/ -# | | | | | +------ BODLEVEL 2..0 (brownout trigger level -> 2.7V) -# | | | | +---------- EESAVE (preserve EEPROM on Chip Erase -> not preserved) -# | | | +-------------- WDTON (watchdog timer always on -> disable) -# | | +---------------- SPIEN (enable serial programming -> enabled) -# | +------------------ DWEN (debug wire enable) -# +-------------------- RSTDISBL (disable external reset -> enabled) -# -################################ ATTiny2313 ################################# -# ATTiny2313 FUSE_L (Fuse low byte): -# 0xef = 1 1 1 0 1 1 1 1 -# ^ ^ \+/ \--+--/ -# | | | +------- CKSEL 3..0 (clock selection -> crystal @ 12 MHz) -# | | +--------------- SUT 1..0 (BOD enabled, fast rising power) -# | +------------------ CKOUT (clock output on CKOUT pin -> disabled) -# +-------------------- CKDIV8 (divide clock by 8 -> don't divide) -# ATTiny2313 FUSE_H (Fuse high byte): -# 0xdb = 1 1 0 1 1 0 1 1 -# ^ ^ ^ ^ \-+-/ ^ -# | | | | | +---- RSTDISBL (disable external reset -> enabled) -# | | | | +-------- BODLEVEL 2..0 (brownout trigger level -> 2.7V) -# | | | +-------------- WDTON (watchdog timer always on -> disable) -# | | +---------------- SPIEN (enable serial programming -> enabled) -# | +------------------ EESAVE (preserve EEPROM on Chip Erase -> not preserved) -# +-------------------- DWEN (debug wire enable) - - -# symbolic targets: -help: - @echo "This Makefile has no default rule. Use one of the following:" - @echo "make hex ....... to build main.hex" - @echo "make program ... to flash fuses and firmware" - @echo "make fuse ...... to flash the fuses" - @echo "make flash ..... to flash the firmware (use this on metaboard)" - @echo "make clean ..... to delete objects and hex file" - -hex: main.hex - -program: flash fuse - -# rule for programming fuse bits: -fuse: - @[ "$(FUSE_H)" != "" -a "$(FUSE_L)" != "" ] || \ - { echo "*** Edit Makefile and choose values for FUSE_L and FUSE_H!"; exit 1; } - $(AVRDUDE) -U hfuse:w:$(FUSE_H):m -U lfuse:w:$(FUSE_L):m - -# rule for uploading firmware: -flash: main.hex - $(AVRDUDE) -U flash:w:main.hex:i - -# rule for deleting dependent files (those which can be built by Make): -clean: - rm -f main.hex main.lst main.obj main.cof main.list main.map main.eep.hex main.elf *.o usbdrv/*.o main.s usbdrv/oddebug.s usbdrv/usbdrv.s - -# Generic rule for compiling C files: -.c.o: - $(COMPILE) -c $< -o $@ - -# Generic rule for assembling Assembler source files: -.S.o: - $(COMPILE) -x assembler-with-cpp -c $< -o $@ -# "-x assembler-with-cpp" should not be necessary since this is the default -# file type for the .S (with capital S) extension. However, upper case -# characters are not always preserved on Windows. To ensure WinAVR -# compatibility define the file type manually. - -# Generic rule for compiling C to assembler, used for debugging only. -.c.s: - $(COMPILE) -S $< -o $@ - -# file targets: - -# Since we don't want to ship the driver multipe times, we copy it into this project: -usbdrv: - cp -r ../../../usbdrv . - -main.elf: usbdrv $(OBJECTS) # usbdrv dependency only needed because we copy it - $(COMPILE) -o main.elf $(OBJECTS) - -main.hex: main.elf - rm -f main.hex main.eep.hex - avr-objcopy -j .text -j .data -O ihex main.elf main.hex - avr-size main.hex - -# debugging targets: - -disasm: main.elf - avr-objdump -d main.elf - -cpp: - $(COMPILE) -E main.c diff --git a/tools/avrusb/examples/custom-class/firmware/main.c b/tools/avrusb/examples/custom-class/firmware/main.c deleted file mode 100644 index 90eeb3c..0000000 --- a/tools/avrusb/examples/custom-class/firmware/main.c +++ /dev/null @@ -1,98 +0,0 @@ -/* Name: main.c - * Project: custom-class, a basic USB example - * Author: Christian Starkjohann - * Creation Date: 2008-04-09 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: main.c 692 2008-11-07 15:07:40Z cs $ - */ - -/* -This example should run on most AVRs with only little changes. No special -hardware resources except INT0 are used. You may have to change usbconfig.h for -different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or -at least be connected to INT0 as well. -We assume that an LED is connected to port B bit 0. If you connect it to a -different port or bit, change the macros below: -*/ -#define LED_PORT_DDR DDRB -#define LED_PORT_OUTPUT PORTB -#define LED_BIT 0 - -#include -#include -#include /* for sei() */ -#include /* for _delay_ms() */ - -#include /* required by usbdrv.h */ -#include "usbdrv.h" -#include "oddebug.h" /* This is also an example for using debug macros */ -#include "requests.h" /* The custom request numbers we use */ - -/* ------------------------------------------------------------------------- */ -/* ----------------------------- USB interface ----------------------------- */ -/* ------------------------------------------------------------------------- */ - -usbMsgLen_t usbFunctionSetup(uchar data[8]) -{ -usbRequest_t *rq = (void *)data; -static uchar dataBuffer[4]; /* buffer must stay valid when usbFunctionSetup returns */ - - if(rq->bRequest == CUSTOM_RQ_ECHO){ /* echo -- used for reliability tests */ - dataBuffer[0] = rq->wValue.bytes[0]; - dataBuffer[1] = rq->wValue.bytes[1]; - dataBuffer[2] = rq->wIndex.bytes[0]; - dataBuffer[3] = rq->wIndex.bytes[1]; - usbMsgPtr = dataBuffer; /* tell the driver which data to return */ - return 4; - }else if(rq->bRequest == CUSTOM_RQ_SET_STATUS){ - if(rq->wValue.bytes[0] & 1){ /* set LED */ - LED_PORT_OUTPUT |= _BV(LED_BIT); - }else{ /* clear LED */ - LED_PORT_OUTPUT &= ~_BV(LED_BIT); - } - }else if(rq->bRequest == CUSTOM_RQ_GET_STATUS){ - dataBuffer[0] = ((LED_PORT_OUTPUT & _BV(LED_BIT)) != 0); - usbMsgPtr = dataBuffer; /* tell the driver which data to return */ - return 1; /* tell the driver to send 1 byte */ - } - return 0; /* default for not implemented requests: return no data back to host */ -} - -/* ------------------------------------------------------------------------- */ - -int main(void) -{ -uchar i; - - wdt_enable(WDTO_1S); - /* Even if you don't use the watchdog, turn it off here. On newer devices, - * the status of the watchdog (on/off, period) is PRESERVED OVER RESET! - */ - DBG1(0x00, 0, 0); /* debug output: main starts */ - /* RESET status: all port bits are inputs without pull-up. - * That's the way we need D+ and D-. Therefore we don't need any - * additional hardware initialization. - */ - odDebugInit(); - usbInit(); - usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */ - i = 0; - while(--i){ /* fake USB disconnect for > 250 ms */ - wdt_reset(); - _delay_ms(1); - } - usbDeviceConnect(); - LED_PORT_DDR |= _BV(LED_BIT); /* make the LED bit an output */ - sei(); - DBG1(0x01, 0, 0); /* debug output: main loop starts */ - for(;;){ /* main event loop */ - DBG1(0x02, 0, 0); /* debug output: main loop iterates */ - wdt_reset(); - usbPoll(); - } - return 0; -} - -/* ------------------------------------------------------------------------- */ diff --git a/tools/avrusb/examples/custom-class/firmware/requests.h b/tools/avrusb/examples/custom-class/firmware/requests.h deleted file mode 100644 index b4ecb14..0000000 --- a/tools/avrusb/examples/custom-class/firmware/requests.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Name: requests.h - * Project: custom-class, a basic USB example - * Author: Christian Starkjohann - * Creation Date: 2008-04-09 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: requests.h 692 2008-11-07 15:07:40Z cs $ - */ - -/* This header is shared between the firmware and the host software. It - * defines the USB request numbers (and optionally data types) used to - * communicate between the host and the device. - */ - -#ifndef __REQUESTS_H_INCLUDED__ -#define __REQUESTS_H_INCLUDED__ - -#define CUSTOM_RQ_ECHO 0 -/* Request that the device sends back wValue and wIndex. This is used with - * random data to test the reliability of the communication. - */ -#define CUSTOM_RQ_SET_STATUS 1 -/* Set the LED status. Control-OUT. - * The requested status is passed in the "wValue" field of the control - * transfer. No OUT data is sent. Bit 0 of the low byte of wValue controls - * the LED. - */ - -#define CUSTOM_RQ_GET_STATUS 2 -/* Get the current LED status. Control-IN. - * This control transfer involves a 1 byte data phase where the device sends - * the current status to the host. The status is in bit 0 of the byte. - */ - -#endif /* __REQUESTS_H_INCLUDED__ */ diff --git a/tools/avrusb/examples/custom-class/firmware/usbconfig.h b/tools/avrusb/examples/custom-class/firmware/usbconfig.h deleted file mode 100644 index 42cf2e8..0000000 --- a/tools/avrusb/examples/custom-class/firmware/usbconfig.h +++ /dev/null @@ -1,350 +0,0 @@ -/* Name: usbconfig.h - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2005-04-01 - * Tabsize: 4 - * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: usbconfig-prototype.h 734 2009-03-23 11:10:07Z cs $ - */ - -#ifndef __usbconfig_h_included__ -#define __usbconfig_h_included__ - -/* -General Description: -This file is an example configuration (with inline documentation) for the USB -driver. It configures AVR-USB for USB D+ connected to Port D bit 2 (which is -also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may -wire the lines to any other port, as long as D+ is also wired to INT0 (or any -other hardware interrupt, as long as it is the highest level interrupt, see -section at the end of this file). -*/ - -/* ---------------------------- Hardware Config ---------------------------- */ - -#define USB_CFG_IOPORTNAME D -/* This is the port where the USB bus is connected. When you configure it to - * "B", the registers PORTB, PINB and DDRB will be used. - */ -#define USB_CFG_DMINUS_BIT 4 -/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected. - * This may be any bit in the port. - */ -#define USB_CFG_DPLUS_BIT 2 -/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected. - * This may be any bit in the port. Please note that D+ must also be connected - * to interrupt pin INT0! [You can also use other interrupts, see section - * "Optional MCU Description" below, or you can connect D- to the interrupt, as - * it is required if you use the USB_COUNT_SOF feature. If you use D- for the - * interrupt, the USB interrupt will also be triggered at Start-Of-Frame - * markers every millisecond.] - */ -#define USB_CFG_CLOCK_KHZ (F_CPU/1000) -/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000, - * 16500 and 20000. The 12.8 MHz and 16.5 MHz versions of the code require no - * crystal, they tolerate +/- 1% deviation from the nominal frequency. All - * other rates require a precision of 2000 ppm and thus a crystal! - * Default if not specified: 12 MHz - */ -#define USB_CFG_CHECK_CRC 0 -/* Define this to 1 if you want that the driver checks integrity of incoming - * data packets (CRC checks). CRC checks cost quite a bit of code size and are - * currently only available for 18 MHz crystal clock. You must choose - * USB_CFG_CLOCK_KHZ = 18000 if you enable this option. - */ - -/* ----------------------- Optional Hardware Config ------------------------ */ - -/* #define USB_CFG_PULLUP_IOPORTNAME D */ -/* If you connect the 1.5k pullup resistor from D- to a port pin instead of - * V+, you can connect and disconnect the device from firmware by calling - * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h). - * This constant defines the port on which the pullup resistor is connected. - */ -/* #define USB_CFG_PULLUP_BIT 4 */ -/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined - * above) where the 1.5k pullup resistor is connected. See description - * above for details. - */ - -/* --------------------------- Functional Range ---------------------------- */ - -#define USB_CFG_HAVE_INTRIN_ENDPOINT 0 -/* Define this to 1 if you want to compile a version with two endpoints: The - * default control endpoint 0 and an interrupt-in endpoint (any other endpoint - * number). - */ -#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0 -/* Define this to 1 if you want to compile a version with three endpoints: The - * default control endpoint 0, an interrupt-in endpoint 3 (or the number - * configured below) and a catch-all default interrupt-in endpoint as above. - * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature. - */ -#define USB_CFG_EP3_NUMBER 3 -/* If the so-called endpoint 3 is used, it can now be configured to any other - * endpoint number (except 0) with this macro. Default if undefined is 3. - */ -/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */ -/* The above macro defines the startup condition for data toggling on the - * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1. - * Since the token is toggled BEFORE sending any data, the first packet is - * sent with the oposite value of this configuration! - */ -#define USB_CFG_IMPLEMENT_HALT 0 -/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature - * for endpoint 1 (interrupt endpoint). Although you may not need this feature, - * it is required by the standard. We have made it a config option because it - * bloats the code considerably. - */ -#define USB_CFG_SUPPRESS_INTR_CODE 0 -/* Define this to 1 if you want to declare interrupt-in endpoints, but don't - * want to send any data over them. If this macro is defined to 1, functions - * usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if - * you need the interrupt-in endpoints in order to comply to an interface - * (e.g. HID), but never want to send any data. This option saves a couple - * of bytes in flash memory and the transmit buffers in RAM. - */ -#define USB_CFG_INTR_POLL_INTERVAL 10 -/* If you compile a version with endpoint 1 (interrupt-in), this is the poll - * interval. The value is in milliseconds and must not be less than 10 ms for - * low speed devices. - */ -#define USB_CFG_IS_SELF_POWERED 0 -/* Define this to 1 if the device has its own power supply. Set it to 0 if the - * device is powered from the USB bus. - */ -#define USB_CFG_MAX_BUS_POWER 40 -/* Set this variable to the maximum USB bus power consumption of your device. - * The value is in milliamperes. [It will be divided by two since USB - * communicates power requirements in units of 2 mA.] - */ -#define USB_CFG_IMPLEMENT_FN_WRITE 0 -/* Set this to 1 if you want usbFunctionWrite() to be called for control-out - * transfers. Set it to 0 if you don't need it and want to save a couple of - * bytes. - */ -#define USB_CFG_IMPLEMENT_FN_READ 0 -/* Set this to 1 if you need to send control replies which are generated - * "on the fly" when usbFunctionRead() is called. If you only want to send - * data from a static buffer, set it to 0 and return the data from - * usbFunctionSetup(). This saves a couple of bytes. - */ -#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0 -/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints. - * You must implement the function usbFunctionWriteOut() which receives all - * interrupt/bulk data sent to any endpoint other than 0. The endpoint number - * can be found in 'usbRxToken'. - */ -#define USB_CFG_HAVE_FLOWCONTROL 0 -/* Define this to 1 if you want flowcontrol over USB data. See the definition - * of the macros usbDisableAllRequests() and usbEnableAllRequests() in - * usbdrv.h. - */ -#define USB_CFG_LONG_TRANSFERS 0 -/* Define this to 1 if you want to send/receive blocks of more than 254 bytes - * in a single control-in or control-out transfer. Note that the capability - * for long transfers increases the driver size. - */ -/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */ -/* This macro is a hook if you want to do unconventional things. If it is - * defined, it's inserted at the beginning of received message processing. - * If you eat the received message and don't want default processing to - * proceed, do a return after doing your things. One possible application - * (besides debugging) is to flash a status LED on each packet. - */ -/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */ -/* This macro is a hook if you need to know when an USB RESET occurs. It has - * one parameter which distinguishes between the start of RESET state and its - * end. - */ -/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */ -/* This macro (if defined) is executed when a USB SET_ADDRESS request was - * received. - */ -#define USB_COUNT_SOF 0 -/* define this macro to 1 if you need the global variable "usbSofCount" which - * counts SOF packets. This feature requires that the hardware interrupt is - * connected to D- instead of D+. - */ -/* #ifdef __ASSEMBLER__ - * macro myAssemblerMacro - * in YL, TCNT0 - * sts timer0Snapshot, YL - * endm - * #endif - * #define USB_SOF_HOOK myAssemblerMacro - * This macro (if defined) is executed in the assembler module when a - * Start Of Frame condition is detected. It is recommended to define it to - * the name of an assembler macro which is defined here as well so that more - * than one assembler instruction can be used. The macro may use the register - * YL and modify SREG. If it lasts longer than a couple of cycles, USB messages - * immediately after an SOF pulse may be lost and must be retried by the host. - * What can you do with this hook? Since the SOF signal occurs exactly every - * 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in - * designs running on the internal RC oscillator. - * Please note that Start Of Frame detection works only if D- is wired to the - * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES! - */ -#define USB_CFG_CHECK_DATA_TOGGLING 0 -/* define this macro to 1 if you want to filter out duplicate data packets - * sent by the host. Duplicates occur only as a consequence of communication - * errors, when the host does not receive an ACK. Please note that you need to - * implement the filtering yourself in usbFunctionWriteOut() and - * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable - * for each control- and out-endpoint to check for duplicate packets. - */ -#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0 -/* define this macro to 1 if you want the function usbMeasureFrameLength() - * compiled in. This function can be used to calibrate the AVR's RC oscillator. - */ - -/* -------------------------- Device Description --------------------------- */ - -#define USB_CFG_VENDOR_ID 0xc0, 0x16 -/* USB vendor ID for the device, low byte first. If you have registered your - * own Vendor ID, define it here. Otherwise you use one of obdev's free shared - * VID/PID pairs. Be sure to read USBID-License.txt for rules! - */ -#define USB_CFG_DEVICE_ID 0xdc, 0x05 -/* This is the ID of the product, low byte first. It is interpreted in the - * scope of the vendor ID. If you have registered your own VID with usb.org - * or if you have licensed a PID from somebody else, define it here. Otherwise - * you use obdev's free shared VID/PID pair. Be sure to read the rules in - * USBID-License.txt! - */ -#define USB_CFG_DEVICE_VERSION 0x00, 0x01 -/* Version number of the device: Minor number first, then major number. - */ -#define USB_CFG_VENDOR_NAME 'o', 'b', 'd', 'e', 'v', '.', 'a', 't' -#define USB_CFG_VENDOR_NAME_LEN 8 -/* These two values define the vendor name returned by the USB device. The name - * must be given as a list of characters under single quotes. The characters - * are interpreted as Unicode (UTF-16) entities. - * If you don't want a vendor name string, undefine these macros. - * ALWAYS define a vendor name containing your Internet domain name if you use - * obdev's free shared VID/PID pair. See the file USBID-License.txt for - * details. - */ -#define USB_CFG_DEVICE_NAME 'L', 'E', 'D', 'C', 'o', 'n', 't', 'r', 'o', 'l' -#define USB_CFG_DEVICE_NAME_LEN 10 -/* Same as above for the device name. If you don't want a device name, undefine - * the macros. See the file USBID-License.txt before you assign a name if you - * use a shared VID/PID. - */ -/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */ -/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */ -/* Same as above for the serial number. If you don't want a serial number, - * undefine the macros. - * It may be useful to provide the serial number through other means than at - * compile time. See the section about descriptor properties below for how - * to fine tune control over USB descriptors such as the string descriptor - * for the serial number. - */ -#define USB_CFG_DEVICE_CLASS 0xff /* set to 0 if deferred to interface */ -#define USB_CFG_DEVICE_SUBCLASS 0 -/* See USB specification if you want to conform to an existing device class. - * Class 0xff is "vendor specific". - */ -#define USB_CFG_INTERFACE_CLASS 0 /* define class here if not at device level */ -#define USB_CFG_INTERFACE_SUBCLASS 0 -#define USB_CFG_INTERFACE_PROTOCOL 0 -/* See USB specification if you want to conform to an existing device class or - * protocol. The following classes must be set at interface level: - * HID class is 3, no subclass and protocol required (but may be useful!) - * CDC class is 2, use subclass 2 and protocol 1 for ACM - */ -/* #define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 42 */ -/* Define this to the length of the HID report descriptor, if you implement - * an HID device. Otherwise don't define it or define it to 0. - * If you use this define, you must add a PROGMEM character array named - * "usbHidReportDescriptor" to your code which contains the report descriptor. - * Don't forget to keep the array and this define in sync! - */ - -/* #define USB_PUBLIC static */ -/* Use the define above if you #include usbdrv.c instead of linking against it. - * This technique saves a couple of bytes in flash memory. - */ - -/* ------------------- Fine Control over USB Descriptors ------------------- */ -/* If you don't want to use the driver's default USB descriptors, you can - * provide our own. These can be provided as (1) fixed length static data in - * flash memory, (2) fixed length static data in RAM or (3) dynamically at - * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more - * information about this function. - * Descriptor handling is configured through the descriptor's properties. If - * no properties are defined or if they are 0, the default descriptor is used. - * Possible properties are: - * + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched - * at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is - * used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if - * you want RAM pointers. - * + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found - * in static memory is in RAM, not in flash memory. - * + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash), - * the driver must know the descriptor's length. The descriptor itself is - * found at the address of a well known identifier (see below). - * List of static descriptor names (must be declared PROGMEM if in flash): - * char usbDescriptorDevice[]; - * char usbDescriptorConfiguration[]; - * char usbDescriptorHidReport[]; - * char usbDescriptorString0[]; - * int usbDescriptorStringVendor[]; - * int usbDescriptorStringDevice[]; - * int usbDescriptorStringSerialNumber[]; - * Other descriptors can't be provided statically, they must be provided - * dynamically at runtime. - * - * Descriptor properties are or-ed or added together, e.g.: - * #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18)) - * - * The following descriptors are defined: - * USB_CFG_DESCR_PROPS_DEVICE - * USB_CFG_DESCR_PROPS_CONFIGURATION - * USB_CFG_DESCR_PROPS_STRINGS - * USB_CFG_DESCR_PROPS_STRING_0 - * USB_CFG_DESCR_PROPS_STRING_VENDOR - * USB_CFG_DESCR_PROPS_STRING_PRODUCT - * USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER - * USB_CFG_DESCR_PROPS_HID - * USB_CFG_DESCR_PROPS_HID_REPORT - * USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver) - * - * Note about string descriptors: String descriptors are not just strings, they - * are Unicode strings prefixed with a 2 byte header. Example: - * int serialNumberDescriptor[] = { - * USB_STRING_DESCRIPTOR_HEADER(6), - * 'S', 'e', 'r', 'i', 'a', 'l' - * }; - */ - -#define USB_CFG_DESCR_PROPS_DEVICE 0 -#define USB_CFG_DESCR_PROPS_CONFIGURATION 0 -#define USB_CFG_DESCR_PROPS_STRINGS 0 -#define USB_CFG_DESCR_PROPS_STRING_0 0 -#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0 -#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0 -#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0 -#define USB_CFG_DESCR_PROPS_HID 0 -#define USB_CFG_DESCR_PROPS_HID_REPORT 0 -#define USB_CFG_DESCR_PROPS_UNKNOWN 0 - -/* ----------------------- Optional MCU Description ------------------------ */ - -/* The following configurations have working defaults in usbdrv.h. You - * usually don't need to set them explicitly. Only if you want to run - * the driver on a device which is not yet supported or with a compiler - * which is not fully supported (such as IAR C) or if you use a differnt - * interrupt than INT0, you may have to define some of these. - */ -/* #define USB_INTR_CFG MCUCR */ -/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */ -/* #define USB_INTR_CFG_CLR 0 */ -/* #define USB_INTR_ENABLE GIMSK */ -/* #define USB_INTR_ENABLE_BIT INT0 */ -/* #define USB_INTR_PENDING GIFR */ -/* #define USB_INTR_PENDING_BIT INTF0 */ -/* #define USB_INTR_VECTOR SIG_INTERRUPT0 */ - -#endif /* __usbconfig_h_included__ */ diff --git a/tools/avrusb/examples/custom-class/firmware/usbdrv/Changelog.txt b/tools/avrusb/examples/custom-class/firmware/usbdrv/Changelog.txt deleted file mode 100644 index c07bca9..0000000 --- a/tools/avrusb/examples/custom-class/firmware/usbdrv/Changelog.txt +++ /dev/null @@ -1,270 +0,0 @@ -This file documents changes in the firmware-only USB driver for atmel's AVR -microcontrollers. New entries are always appended to the end of the file. -Scroll down to the bottom to see the most recent changes. - -2005-04-01: - - Implemented endpoint 1 as interrupt-in endpoint. - - Moved all configuration options to usbconfig.h which is not part of the - driver. - - Changed interface for usbVendorSetup(). - - Fixed compatibility with ATMega8 device. - - Various minor optimizations. - -2005-04-11: - - Changed interface to application: Use usbFunctionSetup(), usbFunctionRead() - and usbFunctionWrite() now. Added configuration options to choose which - of these functions to compile in. - - Assembler module delivers receive data non-inverted now. - - Made register and bit names compatible with more AVR devices. - -2005-05-03: - - Allow address of usbRxBuf on any memory page as long as the buffer does - not cross 256 byte page boundaries. - - Better device compatibility: works with Mega88 now. - - Code optimization in debugging module. - - Documentation updates. - -2006-01-02: - - Added (free) default Vendor- and Product-IDs bought from voti.nl. - - Added USBID-License.txt file which defines the rules for using the free - shared VID/PID pair. - - Added Readme.txt to the usbdrv directory which clarifies administrative - issues. - -2006-01-25: - - Added "configured state" to become more standards compliant. - - Added "HALT" state for interrupt endpoint. - - Driver passes the "USB Command Verifier" test from usb.org now. - - Made "serial number" a configuration option. - - Minor optimizations, we now recommend compiler option "-Os" for best - results. - - Added a version number to usbdrv.h - -2006-02-03: - - New configuration variable USB_BUFFER_SECTION for the memory section where - the USB rx buffer will go. This defaults to ".bss" if not defined. Since - this buffer MUST NOT cross 256 byte pages (not even touch a page at the - end), the user may want to pass a linker option similar to - "-Wl,--section-start=.mybuffer=0x800060". - - Provide structure for usbRequest_t. - - New defines for USB constants. - - Prepared for HID implementations. - - Increased data size limit for interrupt transfers to 8 bytes. - - New macro usbInterruptIsReady() to query interrupt buffer state. - -2006-02-18: - - Ensure that the data token which is sent as an ack to an OUT transfer is - always zero sized. This fixes a bug where the host reports an error after - sending an out transfer to the device, although all data arrived at the - device. - - Updated docs in usbdrv.h to reflect changed API in usbFunctionWrite(). - -* Release 2006-02-20 - - - Give a compiler warning when compiling with debugging turned on. - - Added Oleg Semyonov's changes for IAR-cc compatibility. - - Added new (optional) functions usbDeviceConnect() and usbDeviceDisconnect() - (also thanks to Oleg!). - - Rearranged tests in usbPoll() to save a couple of instructions in the most - likely case that no actions are pending. - - We need a delay between the SET ADDRESS request until the new address - becomes active. This delay was handled in usbPoll() until now. Since the - spec says that the delay must not exceed 2ms, previous versions required - aggressive polling during the enumeration phase. We have now moved the - handling of the delay into the interrupt routine. - - We must not reply with NAK to a SETUP transaction. We can only achieve this - by making sure that the rx buffer is empty when SETUP tokens are expected. - We therefore don't pass zero sized data packets from the status phase of - a transfer to usbPoll(). This change MAY cause troubles if you rely on - receiving a less than 8 bytes long packet in usbFunctionWrite() to - identify the end of a transfer. usbFunctionWrite() will NEVER be called - with a zero length. - -* Release 2006-03-14 - - - Improved IAR C support: tiny memory model, more devices - - Added template usbconfig.h file under the name usbconfig-prototype.h - -* Release 2006-03-26 - - - Added provision for one more interrupt-in endpoint (endpoint 3). - - Added provision for one interrupt-out endpoint (endpoint 1). - - Added flowcontrol macros for USB. - - Added provision for custom configuration descriptor. - - Allow ANY two port bits for D+ and D-. - - Merged (optional) receive endpoint number into global usbRxToken variable. - - Use USB_CFG_IOPORTNAME instead of USB_CFG_IOPORT. We now construct the - variable name from the single port letter instead of computing the address - of related ports from the output-port address. - -* Release 2006-06-26 - - - Updated documentation in usbdrv.h and usbconfig-prototype.h to reflect the - new features. - - Removed "#warning" directives because IAR does not understand them. Use - unused static variables instead to generate a warning. - - Do not include when compiling with IAR. - - Introduced USB_CFG_DESCR_PROPS_* in usbconfig.h to configure how each - USB descriptor should be handled. It is now possible to provide descriptor - data in Flash, RAM or dynamically at runtime. - - STALL is now a status in usbTxLen* instead of a message. We can now conform - to the spec and leave the stall status pending until it is cleared. - - Made usbTxPacketCnt1 and usbTxPacketCnt3 public. This allows the - application code to reset data toggling on interrupt pipes. - -* Release 2006-07-18 - - - Added an #if !defined __ASSEMBLER__ to the warning in usbdrv.h. This fixes - an assembler error. - - usbDeviceDisconnect() takes pull-up resistor to high impedance now. - -* Release 2007-02-01 - - - Merged in some code size improvements from usbtiny (thanks to Dick - Streefland for these optimizations!) - - Special alignment requirement for usbRxBuf not required any more. Thanks - again to Dick Streefland for this hint! - - Reverted to "#warning" instead of unused static variables -- new versions - of IAR CC should handle this directive. - - Changed Open Source license to GNU GPL v2 in order to make linking against - other free libraries easier. We no longer require publication of the - circuit diagrams, but we STRONGLY encourage it. If you improve the driver - itself, PLEASE grant us a royalty free license to your changes for our - commercial license. - -* Release 2007-03-29 - - - New configuration option "USB_PUBLIC" in usbconfig.h. - - Set USB version number to 1.10 instead of 1.01. - - Code used USB_CFG_DESCR_PROPS_STRING_DEVICE and - USB_CFG_DESCR_PROPS_STRING_PRODUCT inconsistently. Changed all occurrences - to USB_CFG_DESCR_PROPS_STRING_PRODUCT. - - New assembler module for 16.5 MHz RC oscillator clock with PLL in receiver - code. - - New assembler module for 16 MHz crystal. - - usbdrvasm.S contains common code only, clock-specific parts have been moved - to usbdrvasm12.S, usbdrvasm16.S and usbdrvasm165.S respectively. - -* Release 2007-06-25 - - - 16 MHz module: Do SE0 check in stuffed bits as well. - -* Release 2007-07-07 - - - Define hi8(x) for IAR compiler to limit result to 8 bits. This is necessary - for negative values. - - Added 15 MHz module contributed by V. Bosch. - - Interrupt vector name can now be configured. This is useful if somebody - wants to use a different hardware interrupt than INT0. - -* Release 2007-08-07 - - - Moved handleIn3 routine in usbdrvasm16.S so that relative jump range is - not exceeded. - - More config options: USB_RX_USER_HOOK(), USB_INITIAL_DATATOKEN, - USB_COUNT_SOF - - USB_INTR_PENDING can now be a memory address, not just I/O - -* Release 2007-09-19 - - - Split out common parts of assembler modules into separate include file - - Made endpoint numbers configurable so that given interface definitions - can be matched. See USB_CFG_EP3_NUMBER in usbconfig-prototype.h. - - Store endpoint number for interrupt/bulk-out so that usbFunctionWriteOut() - can handle any number of endpoints. - - Define usbDeviceConnect() and usbDeviceDisconnect() even if no - USB_CFG_PULLUP_IOPORTNAME is defined. Directly set D+ and D- to 0 in this - case. - -* Release 2007-12-01 - - - Optimize usbDeviceConnect() and usbDeviceDisconnect() for less code size - when USB_CFG_PULLUP_IOPORTNAME is not defined. - -* Release 2007-12-13 - - - Renamed all include-only assembler modules from *.S to *.inc so that - people don't add them to their project sources. - - Distribute leap bits in tx loop more evenly for 16 MHz module. - - Use "macro" and "endm" instead of ".macro" and ".endm" for IAR - - Avoid compiler warnings for constant expr range by casting some values in - USB descriptors. - -* Release 2008-01-21 - - - Fixed bug in 15 and 16 MHz module where the new address set with - SET_ADDRESS was already accepted at the next NAK or ACK we send, not at - the next data packet we send. This caused problems when the host polled - too fast. Thanks to Alexander Neumann for his help and patience debugging - this issue! - -* Release 2008-02-05 - - - Fixed bug in 16.5 MHz module where a register was used in the interrupt - handler before it was pushed. This bug was introduced with version - 2007-09-19 when common parts were moved to a separate file. - - Optimized CRC routine (thanks to Reimar Doeffinger). - -* Release 2008-02-16 - - - Removed outdated IAR compatibility stuff (code sections). - - Added hook macros for USB_RESET_HOOK() and USB_SET_ADDRESS_HOOK(). - - Added optional routine usbMeasureFrameLength() for calibration of the - internal RC oscillator. - -* Release 2008-02-28 - - - USB_INITIAL_DATATOKEN defaults to USBPID_DATA1 now, which means that we - start with sending USBPID_DATA0. - - Changed defaults in usbconfig-prototype.h - - Added free USB VID/PID pair for MIDI class devices - - Restructured AVR-USB as separate package, not part of PowerSwitch any more. - -* Release 2008-04-18 - - - Restructured usbdrv.c so that it is easier to read and understand. - - Better code optimization with gcc 4. - - If a second interrupt in endpoint is enabled, also add it to config - descriptor. - - Added config option for long transfers (above 254 bytes), see - USB_CFG_LONG_TRANSFERS in usbconfig.h. - - Added 20 MHz module contributed by Jeroen Benschop. - -* Release 2008-05-13 - - - Fixed bug in libs-host/hiddata.c function usbhidGetReport(): length - was not incremented, pointer to length was incremented instead. - - Added code to command line tool(s) which claims an interface. This code - is disabled by default, but may be necessary on newer Linux kernels. - - Added usbconfig.h option "USB_CFG_CHECK_DATA_TOGGLING". - - New header "usbportability.h" prepares ports to other development - environments. - - Long transfers (above 254 bytes) did not work when usbFunctionRead() was - used to supply the data. Fixed this bug. [Thanks to Alexander Neumann!] - - In hiddata.c (example code for sending/receiving data over HID), use - USB_RECIP_DEVICE instead of USB_RECIP_INTERFACE for control transfers so - that we need not claim the interface. - - in usbPoll() loop 20 times polling for RESET state instead of 10 times. - This accounts for the higher clock rates we now support. - - Added a module for 12.8 MHz RC oscillator with PLL in receiver loop. - - Added hook to SOF code so that oscillator can be tuned to USB frame clock. - - Added timeout to waitForJ loop. Helps preventing unexpected hangs. - - Added example code for oscillator tuning to libs-device (thanks to - Henrik Haftmann for the idea to this routine). - - Implemented option USB_CFG_SUPPRESS_INTR_CODE. - -* Release 2008-10-22 - - - Fixed libs-device/osctune.h: OSCCAL is memory address on ATMega88 and - similar, not offset of 0x20 needs to be added. - - Allow distribution under GPLv3 for those who have to link against other - code distributed under GPLv3. - -* Release 2008-11-26 - - - Removed libusb-win32 dependency for hid-data example in Makefile.windows. - It was never required and confused many people. - - Added extern uchar usbRxToken to usbdrv.h. - - Integrated a module with CRC checks at 18 MHz by Lukas Schrittwieser. - -* Release 2009-03-23 diff --git a/tools/avrusb/examples/custom-class/firmware/usbdrv/CommercialLicense.txt b/tools/avrusb/examples/custom-class/firmware/usbdrv/CommercialLicense.txt deleted file mode 100644 index 6d8bf39..0000000 --- a/tools/avrusb/examples/custom-class/firmware/usbdrv/CommercialLicense.txt +++ /dev/null @@ -1,156 +0,0 @@ -AVR-USB Driver Software License Agreement -Version 2008-10-07 - -THIS LICENSE AGREEMENT GRANTS YOU CERTAIN RIGHTS IN A SOFTWARE. YOU CAN -ENTER INTO THIS AGREEMENT AND ACQUIRE THE RIGHTS OUTLINED BELOW BY PAYING -THE AMOUNT ACCORDING TO SECTION 4 ("PAYMENT") TO OBJECTIVE DEVELOPMENT. - - -1 DEFINITIONS - -1.1 "OBJECTIVE DEVELOPMENT" shall mean OBJECTIVE DEVELOPMENT Software GmbH, -Grosse Schiffgasse 1A/7, 1020 Wien, AUSTRIA. - -1.2 "You" shall mean the Licensee. - -1.3 "AVR-USB" shall mean all files included in the package distributed under -the name "avrusb" by OBJECTIVE DEVELOPMENT (http://www.obdev.at/avrusb/) -unless otherwise noted. This includes the firmware-only USB device -implementation for Atmel AVR microcontrollers, some simple device examples -and host side software examples and libraries. - - -2 LICENSE GRANTS - -2.1 Source Code. OBJECTIVE DEVELOPMENT shall furnish you with the source -code of AVR-USB. - -2.2 Distribution and Use. OBJECTIVE DEVELOPMENT grants you the -non-exclusive right to use, copy and distribute AVR-USB with your hardware -product(s), restricted by the limitations in section 3 below. - -2.3 Modifications. OBJECTIVE DEVELOPMENT grants you the right to modify -the source code and your copy of AVR-USB according to your needs. - -2.4 USB IDs. OBJECTIVE DEVELOPMENT grants you the exclusive rights to use -USB Product ID(s) sent to you in e-mail after receiving your payment in -conjunction with USB Vendor ID 5824. OBJECTIVE DEVELOPMENT has acquired an -exclusive license for this pair of USB identifiers from Wouter van Ooijen -(www.voti.nl), who has licensed the VID from the USB Implementers Forum, -Inc. (www.usb.org). - - -3 LICENSE RESTRICTIONS - -3.1 Number of Units. Only one of the following three definitions is -applicable. Which one is determined by the amount you pay to OBJECTIVE -DEVELOPMENT, see section 4 ("Payment") below. - -Hobby License: You may use AVR-USB according to section 2 above in no more -than 5 hardware units. These units must not be sold for profit. - -Entry Level License: You may use AVR-USB according to section 2 above in no -more than 150 hardware units. - -Professional License: You may use AVR-USB according to section 2 above in -any number of hardware units, except for large scale production ("unlimited -fair use"). Quantities below 10,000 units are not considered large scale -production. If your reach quantities which are obviously large scale -production, you must pay a license fee of 0.10 EUR per unit for all units -above 10,000. - -3.2 Rental. You may not rent, lease, or lend AVR-USB or otherwise encumber -any copy of AVR-USB, or any of the rights granted herein. - -3.3 Transfer. You may not transfer your rights under this Agreement to -another party without OBJECTIVE DEVELOPMENT's prior written consent. If -such consent is obtained, you may permanently transfer this License to -another party. The recipient of such transfer must agree to all terms and -conditions of this Agreement. - -3.4 Reservation of Rights. OBJECTIVE DEVELOPMENT retains all rights not -expressly granted. - -3.5 Non-Exclusive Rights. Your license rights under this Agreement are -non-exclusive. - -3.6 Third Party Rights. This Agreement cannot grant you rights controlled -by third parties. In particular, you are not allowed to use the USB logo or -other trademarks owned by the USB Implementers Forum, Inc. without their -consent. Since such consent depends on USB certification, it should be -noted that AVR-USB will not pass certification because it does not -implement checksum verification and the microcontroller ports do not meet -the electrical specifications. - - -4 PAYMENT - -The payment amount depends on the variation of this agreement (according to -section 3.1) into which you want to enter. Concrete prices are listed on -OBJECTIVE DEVELOPMENT's web site, usually at -http://www.obdev.at/avrusb/license.html. You agree to pay the amount listed -there to OBJECTIVE DEVELOPMENT or OBJECTIVE DEVELOPMENT's payment processor -or reseller. - - -5 COPYRIGHT AND OWNERSHIP - -AVR-USB is protected by copyright laws and international copyright -treaties, as well as other intellectual property laws and treaties. AVR-USB -is licensed, not sold. - - -6 TERM AND TERMINATION - -6.1 Term. This Agreement shall continue indefinitely. However, OBJECTIVE -DEVELOPMENT may terminate this Agreement and revoke the granted license and -USB-IDs if you fail to comply with any of its terms and conditions. - -6.2 Survival of Terms. All provisions regarding secrecy, confidentiality -and limitation of liability shall survive termination of this agreement. - - -7 DISCLAIMER OF WARRANTY AND LIABILITY - -LIMITED WARRANTY. AVR-USB IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, OBJECTIVE -DEVELOPMENT AND ITS SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES, EITHER -EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND -NON-INFRINGEMENT, WITH REGARD TO AVR-USB, AND THE PROVISION OF OR FAILURE -TO PROVIDE SUPPORT SERVICES. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL -RIGHTS. YOU MAY HAVE OTHERS, WHICH VARY FROM STATE/JURISDICTION TO -STATE/JURISDICTION. - -LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, -IN NO EVENT SHALL OBJECTIVE DEVELOPMENT OR ITS SUPPLIERS BE LIABLE FOR ANY -SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER -(INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, -BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY -LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE AVR-USB OR THE -PROVISION OF OR FAILURE TO PROVIDE SUPPORT SERVICES, EVEN IF OBJECTIVE -DEVELOPMENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY -CASE, OBJECTIVE DEVELOPMENT'S ENTIRE LIABILITY UNDER ANY PROVISION OF THIS -AGREEMENT SHALL BE LIMITED TO THE AMOUNT ACTUALLY PAID BY YOU FOR AVR-USB. - - -8 MISCELLANEOUS TERMS - -8.1 Marketing. OBJECTIVE DEVELOPMENT has the right to mention for marketing -purposes that you entered into this agreement. - -8.2 Entire Agreement. This document represents the entire agreement between -OBJECTIVE DEVELOPMENT and you. It may only be modified in writing signed by -an authorized representative of both, OBJECTIVE DEVELOPMENT and you. - -8.3 Severability. In case a provision of these terms and conditions should -be or become partly or entirely invalid, ineffective, or not executable, -the validity of all other provisions shall not be affected. - -8.4 Applicable Law. This agreement is governed by the laws of the Republic -of Austria. - -8.5 Responsible Courts. The responsible courts in Vienna/Austria will have -exclusive jurisdiction regarding all disputes in connection with this -agreement. - diff --git a/tools/avrusb/examples/custom-class/firmware/usbdrv/License.txt b/tools/avrusb/examples/custom-class/firmware/usbdrv/License.txt deleted file mode 100644 index e9b2752..0000000 --- a/tools/avrusb/examples/custom-class/firmware/usbdrv/License.txt +++ /dev/null @@ -1,361 +0,0 @@ -OBJECTIVE DEVELOPMENT GmbH's AVR-USB driver software is distributed under the -terms and conditions of the GNU GPL version 2 or the GNU GPL version 3. It is -your choice whether you apply the terms of version 2 or version 3. The full -text of GPLv2 is included below. In addition to the requirements in the GPL, -we STRONGLY ENCOURAGE you to do the following: - -(1) Publish your entire project on a web site and drop us a note with the URL. -Use the form at http://www.obdev.at/avrusb/feedback.html for your submission. - -(2) Adhere to minimum publication standards. Please include AT LEAST: - - a circuit diagram in PDF, PNG or GIF format - - full source code for the host software - - a Readme.txt file in ASCII format which describes the purpose of the - project and what can be found in which directories and which files - - a reference to http://www.obdev.at/avrusb/ - -(3) If you improve the driver firmware itself, please give us a free license -to your modifications for our commercial license offerings. - - - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/tools/avrusb/examples/custom-class/firmware/usbdrv/Readme.txt b/tools/avrusb/examples/custom-class/firmware/usbdrv/Readme.txt deleted file mode 100644 index a7aad3e..0000000 --- a/tools/avrusb/examples/custom-class/firmware/usbdrv/Readme.txt +++ /dev/null @@ -1,158 +0,0 @@ -This is the Readme file to Objective Development's firmware-only USB driver -for Atmel AVR microcontrollers. For more information please visit -http://www.obdev.at/avrusb/ - -This directory contains the USB firmware only. Copy it as-is to your own -project and add all .c and .S files to your project (these files are marked -with an asterisk in the list below). Then copy usbconfig-prototype.h as -usbconfig.h to your project and edit it according to your configuration. - - -TECHNICAL DOCUMENTATION -======================= -The technical documentation (API) for the firmware driver is contained in the -file "usbdrv.h". Please read all of it carefully! Configuration options are -documented in "usbconfig-prototype.h". - -The driver consists of the following files: - Readme.txt ............. The file you are currently reading. - Changelog.txt .......... Release notes for all versions of the driver. - usbdrv.h ............... Driver interface definitions and technical docs. -* usbdrv.c ............... High level language part of the driver. Link this - module to your code! -* usbdrvasm.S ............ Assembler part of the driver. This module is mostly - a stub and includes one of the usbdrvasm*.S files - depending on processor clock. Link this module to - your code! - usbdrvasm*.inc ......... Assembler routines for particular clock frequencies. - Included by usbdrvasm.S, don't link it directly! - asmcommon.inc .......... Common assembler routines. Included by - usbdrvasm*.inc, don't link it directly! - usbconfig-prototype.h .. Prototype for your own usbdrv.h file. -* oddebug.c .............. Debug functions. Only used when DEBUG_LEVEL is - defined to a value greater than 0. Link this module - to your code! - oddebug.h .............. Interface definitions of the debug module. - usbportability.h ....... Header with compiler-dependent stuff. - usbdrvasm.asm .......... Compatibility stub for IAR-C-compiler. Use this - module instead of usbdrvasm.S when you assembler - with IAR's tools. - License.txt ............ Open Source license for this driver. - CommercialLicense.txt .. Optional commercial license for this driver. - USBID-License.txt ...... Terms and conditions for using particular USB ID - values for particular purposes. - -(*) ... These files should be linked to your project. - - -CPU CORE CLOCK FREQUENCY -======================== -We supply assembler modules for clock frequencies of 12 MHz, 12.8 MHz, 15 MHz, -16 MHz, 16.5 MHz 18 MHz and 20 MHz. Other clock rates are not supported. The -actual clock rate must be configured in usbdrv.h unless you use the default -12 MHz. - -12 MHz Clock -This is the traditional clock rate of AVR-USB because it's the lowest clock -rate where the timing constraints of the USB spec can be met. - -15 MHz Clock -Similar to 12 MHz, but some NOPs inserted. On the other hand, the higher clock -rate allows for some loops which make the resulting code size somewhat smaller -than the 12 MHz version. - -16 MHz Clock -This clock rate has been added for users of the Arduino board and other -ready-made boards which come with a fixed 16 MHz crystal. It's also an option -if you need the slightly higher clock rate for performance reasons. Since -16 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code -is somewhat tricky and has to insert a leap cycle every third byte. - -12.8 MHz and 16.5 MHz Clock -The assembler modules for these clock rates differ from the other modules -because they have been built for an RC oscillator with only 1% precision. The -receiver code inserts leap cycles to compensate for clock deviations. 1% is -also the precision which can be achieved by calibrating the internal RC -oscillator of the AVR. Please note that only AVRs with internal 64 MHz PLL -oscillator can reach 16.5 MHz with the RC oscillator. This includes the very -popular ATTiny25, ATTiny45, ATTiny85 series as well as the ATTiny26. Almost -all AVRs can reach 12.8 MHz, although this is outside the specified range. - -See the EasyLogger example at http://www.obdev.at/avrusb/easylogger.html for -code which calibrates the RC oscillator based on the USB frame clock. - -18 MHz Clock -This module is closer to the USB specification because it performs an on the -fly CRC check for incoming packets. Packets with invalid checksum are -discarded as required by the spec. If you also implement checks for data -PID toggling on application level (see option USB_CFG_CHECK_DATA_TOGGLING -in usbconfig.h for more info), this ensures data integrity. Due to the CRC -tables and alignment requirements, this code is bigger than modules for other -clock rates. To activate this module, you must define USB_CFG_CHECK_CRC to 1 -and USB_CFG_CLOCK_KHZ to 18000 in usbconfig.h. - -20 MHz Clock -This module is for people who won't do it with less than the maximum. Since -20 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code -uses similar tricks as the 16 MHz module to insert leap cycles. - - -USB IDENTIFIERS -=============== -Every USB device needs a vendor- and a product-identifier (VID and PID). VIDs -are obtained from usb.org for a price of 1,500 USD. Once you have a VID, you -can assign PIDs at will. - -Since an entry level cost of 1,500 USD is too high for most small companies -and hobbyists, we provide some VID/PID pairs for free. See the file -USBID-License.txt for details. - -Objective Development also has some license offerings which include product -IDs. See http://www.obdev.at/avrusb/ for details. - - -DEVELOPMENT SYSTEM -================== -This driver has been developed and optimized for the GNU compiler version 3 -(gcc 3). It does work well with gcc 4, but with bigger code size. We recommend -that you use the GNU compiler suite because it is freely available. AVR-USB -has also been ported to the IAR compiler and assembler. It has been tested -with IAR 4.10B/W32 and 4.12A/W32 on an ATmega8 with the "small" and "tiny" -memory model. Not every release is tested with IAR CC and the driver may -therefore fail to compile with IAR. Please note that gcc is more efficient for -usbdrv.c because this module has been deliberately optimized for gcc. - - -USING AVR-USB FOR FREE -====================== -The AVR firmware driver is published under the GNU General Public License -Version 2 (GPL2) and the GNU General Public License Version 3 (GPL3). It is -your choice whether you apply the terms of version 2 or version 3. - -If you decide for the free GPL2 or GPL3, we STRONGLY ENCOURAGE you to do the -following things IN ADDITION to the obligations from the GPL: - -(1) Publish your entire project on a web site and drop us a note with the URL. -Use the form at http://www.obdev.at/avrusb/feedback.html for your submission. -If you don't have a web site, you can publish the project in obdev's -documentation wiki at -http://www.obdev.at/goto.php?t=avrusb-wiki&p=hosted-projects. - -(2) Adhere to minimum publication standards. Please include AT LEAST: - - a circuit diagram in PDF, PNG or GIF format - - full source code for the host software - - a Readme.txt file in ASCII format which describes the purpose of the - project and what can be found in which directories and which files - - a reference to http://www.obdev.at/avrusb/ - -(3) If you improve the driver firmware itself, please give us a free license -to your modifications for our commercial license offerings. - - -COMMERCIAL LICENSES FOR AVR-USB -=============================== -If you don't want to publish your source code under the terms of the GPL, -you can simply pay money for AVR-USB. As an additional benefit you get -USB PIDs for free, licensed exclusively to you. See the file -"CommercialLicense.txt" for details. - diff --git a/tools/avrusb/examples/custom-class/firmware/usbdrv/USBID-License.txt b/tools/avrusb/examples/custom-class/firmware/usbdrv/USBID-License.txt deleted file mode 100644 index 984c9ee..0000000 --- a/tools/avrusb/examples/custom-class/firmware/usbdrv/USBID-License.txt +++ /dev/null @@ -1,146 +0,0 @@ -Royalty-Free Non-Exclusive License USB Product-ID -================================================= - -Version 2008-04-07 - -OBJECTIVE DEVELOPMENT Software GmbH hereby grants you the non-exclusive -right to use three USB.org vendor-ID (VID) / product-ID (PID) pairs with -products based on Objective Development's firmware-only USB driver for -Atmel AVR microcontrollers: - - * VID = 5824 (=0x16c0) / PID = 1500 (=0x5dc) for devices implementing no - USB device class (vendor-class devices with USB class = 0xff). Devices - using this pair will be referred to as "VENDOR CLASS" devices. - - * VID = 5824 (=0x16c0) / PID = 1503 (=0x5df) for HID class devices - (excluding mice and keyboards). Devices using this pair will be referred - to as "HID CLASS" devices. - - * VID = 5824 (=0x16c0) / PID = 1505 (=0x5e1) for CDC class modem devices - Devices using this pair will be referred to as "CDC-ACM CLASS" devices. - - * VID = 5824 (=0x16c0) / PID = 1508 (=0x5e4) for MIDI class devices - Devices using this pair will be referred to as "MIDI CLASS" devices. - -Since the granted right is non-exclusive, the same VID/PID pairs may be -used by many companies and individuals for different products. To avoid -conflicts, your device and host driver software MUST adhere to the rules -outlined below. - -OBJECTIVE DEVELOPMENT Software GmbH has licensed these VID/PID pairs from -Wouter van Ooijen (see www.voti.nl), who has licensed the VID from the USB -Implementers Forum, Inc. (see www.usb.org). The VID is registered for the -company name "Van Ooijen Technische Informatica". - - -RULES AND RESTRICTIONS -====================== - -(1) The USB device MUST provide a textual representation of the -manufacturer and product identification. The manufacturer identification -MUST be available at least in USB language 0x0409 (English/US). - -(2) The textual manufacturer identification MUST contain either an Internet -domain name (e.g. "mycompany.com") registered and owned by you, or an -e-mail address under your control (e.g. "myname@gmx.net"). You can embed -the domain name or e-mail address in any string you like, e.g. "Objective -Development http://www.obdev.at/avrusb/". - -(3) You are responsible for retaining ownership of the domain or e-mail -address for as long as any of your products are in use. - -(4) You may choose any string for the textual product identification, as -long as this string is unique within the scope of your textual manufacturer -identification. - -(5) Matching of device-specific drivers MUST be based on the textual -manufacturer and product identification in addition to the usual VID/PID -matching. This means that operating system features which are based on -VID/PID matching only (e.g. Windows kernel level drivers, automatic actions -when the device is plugged in etc) MUST NOT be used. The driver matching -MUST be a comparison of the entire strings, NOT a sub-string match. For -CDC-ACM CLASS and MIDI CLASS devices, a generic class driver should be used -and the matching is based on the USB device class. - -(6) The extent to which VID/PID matching is allowed for non device-specific -drivers or features depends on the operating system and particular VID/PID -pair used: - - * Mac OS X, Linux, FreeBSD and other Unixes: No VID/PID matching is - required and hence no VID/PID-only matching is allowed at all. - - * Windows: The operating system performs VID/PID matching for the kernel - level driver. You are REQUIRED to use libusb-win32 (see - http://libusb-win32.sourceforge.net/) as the kernel level driver for - VENDOR CLASS devices. HID CLASS devices all use the generic HID class - driver shipped with Windows, except mice and keyboards. You therefore - MUST NOT use any of the shared VID/PID pairs for mice or keyboards. - CDC-ACM CLASS devices require a ".inf" file which matches on the VID/PID - pair. This ".inf" file MUST load the "usbser" driver to configure the - device as modem (COM-port). - -(7) OBJECTIVE DEVELOPMENT Software GmbH disclaims all liability for any -problems which are caused by the shared use of these VID/PID pairs. You -have been warned that the sharing of VID/PID pairs may cause problems. If -you want to avoid them, get your own VID/PID pair for exclusive use. - - -HOW TO IMPLEMENT THESE RULES -============================ - -The following rules are for VENDOR CLASS and HID CLASS devices. CDC-ACM -CLASS and MIDI CLASS devices use the operating system's class driver and -don't need a custom driver. - -The host driver MUST iterate over all devices with the given VID/PID -numbers in their device descriptors and query the string representation for -the manufacturer name in USB language 0x0409 (English/US). It MUST compare -the ENTIRE string with your textual manufacturer identification chosen in -(2) above. A substring search for your domain or e-mail address is NOT -acceptable. The driver MUST NOT touch the device (other than querying the -descriptors) unless the strings match. - -For all USB devices with matching VID/PID and textual manufacturer -identification, the host driver must query the textual product -identification and string-compare it with the name of the product it can -control. It may only initialize the device if the product matches exactly. - -Objective Development provides examples for these matching rules with the -"PowerSwitch" project (using libusb) and with the "Automator" project -(using Windows calls on Windows and libusb on Unix). - - -Technical Notes: -================ - -Sharing the same VID/PID pair among devices is possible as long as ALL -drivers which match the VID/PID also perform matching on the textual -identification strings. This is easy on all operating systems except -Windows, since Windows establishes a static connection between the VID/PID -pair and a kernel level driver. All devices with the same VID/PID pair must -therefore use THE SAME kernel level driver. - -We therefore demand that you use libusb-win32 for VENDOR CLASS devices. -This is a generic kernel level driver which allows all types of USB access -for user space applications. This is only a partial solution of the -problem, though, because different device drivers may come with different -versions of libusb-win32 and they may not work with the libusb version of -the respective other driver. You are therefore encouraged to test your -driver against a broad range of libusb-win32 versions. Do not use new -features in new versions, or check for their existence before you use them. -When a new libusb-win32 becomes available, make sure that your driver is -compatible with it. - -For HID CLASS devices it is necessary that all those devices bind to the -same kernel driver: Microsoft's generic USB HID driver. This is true for -all HID devices except those with a specialized driver. Currently, the only -HIDs with specialized drivers are mice and keyboards. You therefore MUST -NOT use a shared VID/PID with mouse and keyboard devices. - -Sharing the same VID/PID among different products is unusual and probably -violates the USB specification. If you do it, you do it at your own risk. - -To avoid possible incompatibilities, we highly recommend that you get your -own VID/PID pair if you intend to sell your product. Objective -Development's commercial licenses for AVR-USB include a PID for -unrestricted exclusive use. diff --git a/tools/avrusb/examples/custom-class/firmware/usbdrv/asmcommon.inc b/tools/avrusb/examples/custom-class/firmware/usbdrv/asmcommon.inc deleted file mode 100644 index 457de3b..0000000 --- a/tools/avrusb/examples/custom-class/firmware/usbdrv/asmcommon.inc +++ /dev/null @@ -1,188 +0,0 @@ -/* Name: asmcommon.inc - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2007-11-05 - * Tabsize: 4 - * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * Revision: $Id$ - */ - -/* Do not link this file! Link usbdrvasm.S instead, which includes the - * appropriate implementation! - */ - -/* -General Description: -This file contains assembler code which is shared among the USB driver -implementations for different CPU cocks. Since the code must be inserted -in the middle of the module, it's split out into this file and #included. - -Jump destinations called from outside: - sofError: Called when no start sequence was found. - se0: Called when a package has been successfully received. - overflow: Called when receive buffer overflows. - doReturn: Called after sending data. - -Outside jump destinations used by this module: - waitForJ: Called to receive an already arriving packet. - sendAckAndReti: - sendNakAndReti: - sendCntAndReti: - usbSendAndReti: - -The following macros must be defined before this file is included: - .macro POP_STANDARD - .endm - .macro POP_RETI - .endm -*/ - -#define token x1 - -overflow: - ldi x2, 1< 0 - -#warning "Never compile production devices with debugging enabled" - -static void uartPutc(char c) -{ - while(!(ODDBG_USR & (1 << ODDBG_UDRE))); /* wait for data register empty */ - ODDBG_UDR = c; -} - -static uchar hexAscii(uchar h) -{ - h &= 0xf; - if(h >= 10) - h += 'a' - (uchar)10 - '0'; - h += '0'; - return h; -} - -static void printHex(uchar c) -{ - uartPutc(hexAscii(c >> 4)); - uartPutc(hexAscii(c)); -} - -void odDebug(uchar prefix, uchar *data, uchar len) -{ - printHex(prefix); - uartPutc(':'); - while(len--){ - uartPutc(' '); - printHex(*data++); - } - uartPutc('\r'); - uartPutc('\n'); -} - -#endif diff --git a/tools/avrusb/examples/custom-class/firmware/usbdrv/oddebug.h b/tools/avrusb/examples/custom-class/firmware/usbdrv/oddebug.h deleted file mode 100644 index d61309d..0000000 --- a/tools/avrusb/examples/custom-class/firmware/usbdrv/oddebug.h +++ /dev/null @@ -1,123 +0,0 @@ -/* Name: oddebug.h - * Project: AVR library - * Author: Christian Starkjohann - * Creation Date: 2005-01-16 - * Tabsize: 4 - * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: oddebug.h 692 2008-11-07 15:07:40Z cs $ - */ - -#ifndef __oddebug_h_included__ -#define __oddebug_h_included__ - -/* -General Description: -This module implements a function for debug logs on the serial line of the -AVR microcontroller. Debugging can be configured with the define -'DEBUG_LEVEL'. If this macro is not defined or defined to 0, all debugging -calls are no-ops. If it is 1, DBG1 logs will appear, but not DBG2. If it is -2, DBG1 and DBG2 logs will be printed. - -A debug log consists of a label ('prefix') to indicate which debug log created -the output and a memory block to dump in hex ('data' and 'len'). -*/ - - -#ifndef F_CPU -# define F_CPU 12000000 /* 12 MHz */ -#endif - -/* make sure we have the UART defines: */ -#include "usbportability.h" - -#ifndef uchar -# define uchar unsigned char -#endif - -#if DEBUG_LEVEL > 0 && !(defined TXEN || defined TXEN0) /* no UART in device */ -# warning "Debugging disabled because device has no UART" -# undef DEBUG_LEVEL -#endif - -#ifndef DEBUG_LEVEL -# define DEBUG_LEVEL 0 -#endif - -/* ------------------------------------------------------------------------- */ - -#if DEBUG_LEVEL > 0 -# define DBG1(prefix, data, len) odDebug(prefix, data, len) -#else -# define DBG1(prefix, data, len) -#endif - -#if DEBUG_LEVEL > 1 -# define DBG2(prefix, data, len) odDebug(prefix, data, len) -#else -# define DBG2(prefix, data, len) -#endif - -/* ------------------------------------------------------------------------- */ - -#if DEBUG_LEVEL > 0 -extern void odDebug(uchar prefix, uchar *data, uchar len); - -/* Try to find our control registers; ATMEL likes to rename these */ - -#if defined UBRR -# define ODDBG_UBRR UBRR -#elif defined UBRRL -# define ODDBG_UBRR UBRRL -#elif defined UBRR0 -# define ODDBG_UBRR UBRR0 -#elif defined UBRR0L -# define ODDBG_UBRR UBRR0L -#endif - -#if defined UCR -# define ODDBG_UCR UCR -#elif defined UCSRB -# define ODDBG_UCR UCSRB -#elif defined UCSR0B -# define ODDBG_UCR UCSR0B -#endif - -#if defined TXEN -# define ODDBG_TXEN TXEN -#else -# define ODDBG_TXEN TXEN0 -#endif - -#if defined USR -# define ODDBG_USR USR -#elif defined UCSRA -# define ODDBG_USR UCSRA -#elif defined UCSR0A -# define ODDBG_USR UCSR0A -#endif - -#if defined UDRE -# define ODDBG_UDRE UDRE -#else -# define ODDBG_UDRE UDRE0 -#endif - -#if defined UDR -# define ODDBG_UDR UDR -#elif defined UDR0 -# define ODDBG_UDR UDR0 -#endif - -static inline void odDebugInit(void) -{ - ODDBG_UCR |= (1<len & 0x10){ /* packet buffer was empty */ - txStatus->buffer[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* toggle token */ - }else{ - txStatus->len = USBPID_NAK; /* avoid sending outdated (overwritten) interrupt data */ - } - p = txStatus->buffer + 1; - i = len; - do{ /* if len == 0, we still copy 1 byte, but that's no problem */ - *p++ = *data++; - }while(--i > 0); /* loop control at the end is 2 bytes shorter than at beginning */ - usbCrc16Append(&txStatus->buffer[1], len); - txStatus->len = len + 4; /* len must be given including sync byte */ - DBG2(0x21 + (((int)txStatus >> 3) & 3), txStatus->buffer, len + 3); -} - -USB_PUBLIC void usbSetInterrupt(uchar *data, uchar len) -{ - usbGenericSetInterrupt(data, len, &usbTxStatus1); -} -#endif - -#if USB_CFG_HAVE_INTRIN_ENDPOINT3 -USB_PUBLIC void usbSetInterrupt3(uchar *data, uchar len) -{ - usbGenericSetInterrupt(data, len, &usbTxStatus3); -} -#endif -#endif /* USB_CFG_SUPPRESS_INTR_CODE */ - -/* ------------------ utilities for code following below ------------------- */ - -/* Use defines for the switch statement so that we can choose between an - * if()else if() and a switch/case based implementation. switch() is more - * efficient for a LARGE set of sequential choices, if() is better in all other - * cases. - */ -#if USB_CFG_USE_SWITCH_STATEMENT -# define SWITCH_START(cmd) switch(cmd){{ -# define SWITCH_CASE(value) }break; case (value):{ -# define SWITCH_CASE2(v1,v2) }break; case (v1): case(v2):{ -# define SWITCH_CASE3(v1,v2,v3) }break; case (v1): case(v2): case(v3):{ -# define SWITCH_DEFAULT }break; default:{ -# define SWITCH_END }} -#else -# define SWITCH_START(cmd) {uchar _cmd = cmd; if(0){ -# define SWITCH_CASE(value) }else if(_cmd == (value)){ -# define SWITCH_CASE2(v1,v2) }else if(_cmd == (v1) || _cmd == (v2)){ -# define SWITCH_CASE3(v1,v2,v3) }else if(_cmd == (v1) || _cmd == (v2) || (_cmd == v3)){ -# define SWITCH_DEFAULT }else{ -# define SWITCH_END }} -#endif - -#ifndef USB_RX_USER_HOOK -#define USB_RX_USER_HOOK(data, len) -#endif -#ifndef USB_SET_ADDRESS_HOOK -#define USB_SET_ADDRESS_HOOK() -#endif - -/* ------------------------------------------------------------------------- */ - -/* We use if() instead of #if in the macro below because #if can't be used - * in macros and the compiler optimizes constant conditions anyway. - * This may cause problems with undefined symbols if compiled without - * optimizing! - */ -#define GET_DESCRIPTOR(cfgProp, staticName) \ - if(cfgProp){ \ - if((cfgProp) & USB_PROP_IS_RAM) \ - flags = 0; \ - if((cfgProp) & USB_PROP_IS_DYNAMIC){ \ - len = usbFunctionDescriptor(rq); \ - }else{ \ - len = USB_PROP_LENGTH(cfgProp); \ - usbMsgPtr = (uchar *)(staticName); \ - } \ - } - -/* usbDriverDescriptor() is similar to usbFunctionDescriptor(), but used - * internally for all types of descriptors. - */ -static inline usbMsgLen_t usbDriverDescriptor(usbRequest_t *rq) -{ -usbMsgLen_t len = 0; -uchar flags = USB_FLG_MSGPTR_IS_ROM; - - SWITCH_START(rq->wValue.bytes[1]) - SWITCH_CASE(USBDESCR_DEVICE) /* 1 */ - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_DEVICE, usbDescriptorDevice) - SWITCH_CASE(USBDESCR_CONFIG) /* 2 */ - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_CONFIGURATION, usbDescriptorConfiguration) - SWITCH_CASE(USBDESCR_STRING) /* 3 */ -#if USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC - if(USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_RAM) - flags = 0; - len = usbFunctionDescriptor(rq); -#else /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */ - SWITCH_START(rq->wValue.bytes[0]) - SWITCH_CASE(0) - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_0, usbDescriptorString0) - SWITCH_CASE(1) - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_VENDOR, usbDescriptorStringVendor) - SWITCH_CASE(2) - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_PRODUCT, usbDescriptorStringDevice) - SWITCH_CASE(3) - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER, usbDescriptorStringSerialNumber) - SWITCH_DEFAULT - if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){ - len = usbFunctionDescriptor(rq); - } - SWITCH_END -#endif /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */ -#if USB_CFG_DESCR_PROPS_HID_REPORT /* only support HID descriptors if enabled */ - SWITCH_CASE(USBDESCR_HID) /* 0x21 */ - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID, usbDescriptorConfiguration + 18) - SWITCH_CASE(USBDESCR_HID_REPORT)/* 0x22 */ - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID_REPORT, usbDescriptorHidReport) -#endif - SWITCH_DEFAULT - if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){ - len = usbFunctionDescriptor(rq); - } - SWITCH_END - usbMsgFlags = flags; - return len; -} - -/* ------------------------------------------------------------------------- */ - -/* usbDriverSetup() is similar to usbFunctionSetup(), but it's used for - * standard requests instead of class and custom requests. - */ -static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq) -{ -uchar len = 0, *dataPtr = usbTxBuf + 9; /* there are 2 bytes free space at the end of the buffer */ -uchar value = rq->wValue.bytes[0]; -#if USB_CFG_IMPLEMENT_HALT -uchar index = rq->wIndex.bytes[0]; -#endif - - dataPtr[0] = 0; /* default reply common to USBRQ_GET_STATUS and USBRQ_GET_INTERFACE */ - SWITCH_START(rq->bRequest) - SWITCH_CASE(USBRQ_GET_STATUS) /* 0 */ - uchar recipient = rq->bmRequestType & USBRQ_RCPT_MASK; /* assign arith ops to variables to enforce byte size */ - if(USB_CFG_IS_SELF_POWERED && recipient == USBRQ_RCPT_DEVICE) - dataPtr[0] = USB_CFG_IS_SELF_POWERED; -#if USB_CFG_IMPLEMENT_HALT - if(recipient == USBRQ_RCPT_ENDPOINT && index == 0x81) /* request status for endpoint 1 */ - dataPtr[0] = usbTxLen1 == USBPID_STALL; -#endif - dataPtr[1] = 0; - len = 2; -#if USB_CFG_IMPLEMENT_HALT - SWITCH_CASE2(USBRQ_CLEAR_FEATURE, USBRQ_SET_FEATURE) /* 1, 3 */ - if(value == 0 && index == 0x81){ /* feature 0 == HALT for endpoint == 1 */ - usbTxLen1 = rq->bRequest == USBRQ_CLEAR_FEATURE ? USBPID_NAK : USBPID_STALL; - usbResetDataToggling(); - } -#endif - SWITCH_CASE(USBRQ_SET_ADDRESS) /* 5 */ - usbNewDeviceAddr = value; - USB_SET_ADDRESS_HOOK(); - SWITCH_CASE(USBRQ_GET_DESCRIPTOR) /* 6 */ - len = usbDriverDescriptor(rq); - goto skipMsgPtrAssignment; - SWITCH_CASE(USBRQ_GET_CONFIGURATION) /* 8 */ - dataPtr = &usbConfiguration; /* send current configuration value */ - len = 1; - SWITCH_CASE(USBRQ_SET_CONFIGURATION) /* 9 */ - usbConfiguration = value; - usbResetStall(); - SWITCH_CASE(USBRQ_GET_INTERFACE) /* 10 */ - len = 1; -#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE - SWITCH_CASE(USBRQ_SET_INTERFACE) /* 11 */ - usbResetDataToggling(); - usbResetStall(); -#endif - SWITCH_DEFAULT /* 7=SET_DESCRIPTOR, 12=SYNC_FRAME */ - /* Should we add an optional hook here? */ - SWITCH_END - usbMsgPtr = dataPtr; -skipMsgPtrAssignment: - return len; -} - -/* ------------------------------------------------------------------------- */ - -/* usbProcessRx() is called for every message received by the interrupt - * routine. It distinguishes between SETUP and DATA packets and processes - * them accordingly. - */ -static inline void usbProcessRx(uchar *data, uchar len) -{ -usbRequest_t *rq = (void *)data; - -/* usbRxToken can be: - * 0x2d 00101101 (USBPID_SETUP for setup data) - * 0xe1 11100001 (USBPID_OUT: data phase of setup transfer) - * 0...0x0f for OUT on endpoint X - */ - DBG2(0x10 + (usbRxToken & 0xf), data, len + 2); /* SETUP=1d, SETUP-DATA=11, OUTx=1x */ - USB_RX_USER_HOOK(data, len) -#if USB_CFG_IMPLEMENT_FN_WRITEOUT - if(usbRxToken < 0x10){ /* OUT to endpoint != 0: endpoint number in usbRxToken */ - usbFunctionWriteOut(data, len); - return; - } -#endif - if(usbRxToken == (uchar)USBPID_SETUP){ - if(len != 8) /* Setup size must be always 8 bytes. Ignore otherwise. */ - return; - usbMsgLen_t replyLen; - usbTxBuf[0] = USBPID_DATA0; /* initialize data toggling */ - usbTxLen = USBPID_NAK; /* abort pending transmit */ - usbMsgFlags = 0; - uchar type = rq->bmRequestType & USBRQ_TYPE_MASK; - if(type != USBRQ_TYPE_STANDARD){ /* standard requests are handled by driver */ - replyLen = usbFunctionSetup(data); - }else{ - replyLen = usbDriverSetup(rq); - } -#if USB_CFG_IMPLEMENT_FN_READ || USB_CFG_IMPLEMENT_FN_WRITE - if(replyLen == USB_NO_MSG){ /* use user-supplied read/write function */ - /* do some conditioning on replyLen, but on IN transfers only */ - if((rq->bmRequestType & USBRQ_DIR_MASK) != USBRQ_DIR_HOST_TO_DEVICE){ - if(sizeof(replyLen) < sizeof(rq->wLength.word)){ /* help compiler with optimizing */ - replyLen = rq->wLength.bytes[0]; - }else{ - replyLen = rq->wLength.word; - } - } - usbMsgFlags = USB_FLG_USE_USER_RW; - }else /* The 'else' prevents that we limit a replyLen of USB_NO_MSG to the maximum transfer len. */ -#endif - if(sizeof(replyLen) < sizeof(rq->wLength.word)){ /* help compiler with optimizing */ - if(!rq->wLength.bytes[1] && replyLen > rq->wLength.bytes[0]) /* limit length to max */ - replyLen = rq->wLength.bytes[0]; - }else{ - if(replyLen > rq->wLength.word) /* limit length to max */ - replyLen = rq->wLength.word; - } - usbMsgLen = replyLen; - }else{ /* usbRxToken must be USBPID_OUT, which means data phase of setup (control-out) */ -#if USB_CFG_IMPLEMENT_FN_WRITE - if(usbMsgFlags & USB_FLG_USE_USER_RW){ - uchar rval = usbFunctionWrite(data, len); - if(rval == 0xff){ /* an error occurred */ - usbTxLen = USBPID_STALL; - }else if(rval != 0){ /* This was the final package */ - usbMsgLen = 0; /* answer with a zero-sized data packet */ - } - } -#endif - } -} - -/* ------------------------------------------------------------------------- */ - -/* This function is similar to usbFunctionRead(), but it's also called for - * data handled automatically by the driver (e.g. descriptor reads). - */ -static uchar usbDeviceRead(uchar *data, uchar len) -{ - if(len > 0){ /* don't bother app with 0 sized reads */ -#if USB_CFG_IMPLEMENT_FN_READ - if(usbMsgFlags & USB_FLG_USE_USER_RW){ - len = usbFunctionRead(data, len); - }else -#endif - { - uchar i = len, *r = usbMsgPtr; - if(usbMsgFlags & USB_FLG_MSGPTR_IS_ROM){ /* ROM data */ - do{ - uchar c = USB_READ_FLASH(r); /* assign to char size variable to enforce byte ops */ - *data++ = c; - r++; - }while(--i); - }else{ /* RAM data */ - do{ - *data++ = *r++; - }while(--i); - } - usbMsgPtr = r; - } - } - return len; -} - -/* ------------------------------------------------------------------------- */ - -/* usbBuildTxBlock() is called when we have data to transmit and the - * interrupt routine's transmit buffer is empty. - */ -static inline void usbBuildTxBlock(void) -{ -usbMsgLen_t wantLen; -uchar len; - - wantLen = usbMsgLen; - if(wantLen > 8) - wantLen = 8; - usbMsgLen -= wantLen; - usbTxBuf[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* DATA toggling */ - len = usbDeviceRead(usbTxBuf + 1, wantLen); - if(len <= 8){ /* valid data packet */ - usbCrc16Append(&usbTxBuf[1], len); - len += 4; /* length including sync byte */ - if(len < 12) /* a partial package identifies end of message */ - usbMsgLen = USB_NO_MSG; - }else{ - len = USBPID_STALL; /* stall the endpoint */ - usbMsgLen = USB_NO_MSG; - } - usbTxLen = len; - DBG2(0x20, usbTxBuf, len-1); -} - -/* ------------------------------------------------------------------------- */ - -static inline void usbHandleResetHook(uchar notResetState) -{ -#ifdef USB_RESET_HOOK -static uchar wasReset; -uchar isReset = !notResetState; - - if(wasReset != isReset){ - USB_RESET_HOOK(isReset); - wasReset = isReset; - } -#endif -} - -/* ------------------------------------------------------------------------- */ - -USB_PUBLIC void usbPoll(void) -{ -schar len; -uchar i; - - len = usbRxLen - 3; - if(len >= 0){ -/* We could check CRC16 here -- but ACK has already been sent anyway. If you - * need data integrity checks with this driver, check the CRC in your app - * code and report errors back to the host. Since the ACK was already sent, - * retries must be handled on application level. - * unsigned crc = usbCrc16(buffer + 1, usbRxLen - 3); - */ - usbProcessRx(usbRxBuf + USB_BUFSIZE + 1 - usbInputBufOffset, len); -#if USB_CFG_HAVE_FLOWCONTROL - if(usbRxLen > 0) /* only mark as available if not inactivated */ - usbRxLen = 0; -#else - usbRxLen = 0; /* mark rx buffer as available */ -#endif - } - if(usbTxLen & 0x10){ /* transmit system idle */ - if(usbMsgLen != USB_NO_MSG){ /* transmit data pending? */ - usbBuildTxBlock(); - } - } - for(i = 20; i > 0; i--){ - uchar usbLineStatus = USBIN & USBMASK; - if(usbLineStatus != 0) /* SE0 has ended */ - goto isNotReset; - } - /* RESET condition, called multiple times during reset */ - usbNewDeviceAddr = 0; - usbDeviceAddr = 0; - usbResetStall(); - DBG1(0xff, 0, 0); -isNotReset: - usbHandleResetHook(i); -} - -/* ------------------------------------------------------------------------- */ - -USB_PUBLIC void usbInit(void) -{ -#if USB_INTR_CFG_SET != 0 - USB_INTR_CFG |= USB_INTR_CFG_SET; -#endif -#if USB_INTR_CFG_CLR != 0 - USB_INTR_CFG &= ~(USB_INTR_CFG_CLR); -#endif - USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT); - usbResetDataToggling(); -#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE - usbTxLen1 = USBPID_NAK; -#if USB_CFG_HAVE_INTRIN_ENDPOINT3 - usbTxLen3 = USBPID_NAK; -#endif -#endif -} - -/* ------------------------------------------------------------------------- */ diff --git a/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrv.h b/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrv.h deleted file mode 100644 index c5cefe9..0000000 --- a/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrv.h +++ /dev/null @@ -1,733 +0,0 @@ -/* Name: usbdrv.h - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2004-12-29 - * Tabsize: 4 - * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: usbdrv.h 738 2009-03-23 11:13:24Z cs $ - */ - -#ifndef __usbdrv_h_included__ -#define __usbdrv_h_included__ -#include "usbconfig.h" -#include "usbportability.h" - -/* -Hardware Prerequisites: -======================= -USB lines D+ and D- MUST be wired to the same I/O port. We recommend that D+ -triggers the interrupt (best achieved by using INT0 for D+), but it is also -possible to trigger the interrupt from D-. If D- is used, interrupts are also -triggered by SOF packets. D- requires a pull-up of 1.5k to +3.5V (and the -device must be powered at 3.5V) to identify as low-speed USB device. A -pull-down or pull-up of 1M SHOULD be connected from D+ to +3.5V to prevent -interference when no USB master is connected. If you use Zener diodes to limit -the voltage on D+ and D-, you MUST use a pull-down resistor, not a pull-up. -We use D+ as interrupt source and not D- because it does not trigger on -keep-alive and RESET states. If you want to count keep-alive events with -USB_COUNT_SOF, you MUST use D- as an interrupt source. - -As a compile time option, the 1.5k pull-up resistor on D- can be made -switchable to allow the device to disconnect at will. See the definition of -usbDeviceConnect() and usbDeviceDisconnect() further down in this file. - -Please adapt the values in usbconfig.h according to your hardware! - -The device MUST be clocked at exactly 12 MHz, 15 MHz, 16 MHz or 20 MHz -or at 12.8 MHz resp. 16.5 MHz +/- 1%. See usbconfig-prototype.h for details. - - -Limitations: -============ -Robustness with respect to communication errors: -The driver assumes error-free communication. It DOES check for errors in -the PID, but does NOT check bit stuffing errors, SE0 in middle of a byte, -token CRC (5 bit) and data CRC (16 bit). CRC checks can not be performed due -to timing constraints: We must start sending a reply within 7 bit times. -Bit stuffing and misplaced SE0 would have to be checked in real-time, but CPU -performance does not permit that. The driver does not check Data0/Data1 -toggling, but application software can implement the check. - -Input characteristics: -Since no differential receiver circuit is used, electrical interference -robustness may suffer. The driver samples only one of the data lines with -an ordinary I/O pin's input characteristics. However, since this is only a -low speed USB implementation and the specification allows for 8 times the -bit rate over the same hardware, we should be on the safe side. Even the spec -requires detection of asymmetric states at high bit rate for SE0 detection. - -Number of endpoints: -The driver supports the following endpoints: - -- Endpoint 0, the default control endpoint. -- Any number of interrupt- or bulk-out endpoints. The data is sent to - usbFunctionWriteOut() and USB_CFG_IMPLEMENT_FN_WRITEOUT must be defined - to 1 to activate this feature. The endpoint number can be found in the - global variable 'usbRxToken'. -- One default interrupt- or bulk-in endpoint. This endpoint is used for - interrupt- or bulk-in transfers which are not handled by any other endpoint. - You must define USB_CFG_HAVE_INTRIN_ENDPOINT in order to activate this - feature and call usbSetInterrupt() to send interrupt/bulk data. -- One additional interrupt- or bulk-in endpoint. This was endpoint 3 in - previous versions of this driver but can now be configured to any endpoint - number. You must define USB_CFG_HAVE_INTRIN_ENDPOINT3 in order to activate - this feature and call usbSetInterrupt3() to send interrupt/bulk data. The - endpoint number can be set with USB_CFG_EP3_NUMBER. - -Please note that the USB standard forbids bulk endpoints for low speed devices! -Most operating systems allow them anyway, but the AVR will spend 90% of the CPU -time in the USB interrupt polling for bulk data. - -Maximum data payload: -Data payload of control in and out transfers may be up to 254 bytes. In order -to accept payload data of out transfers, you need to implement -'usbFunctionWrite()'. - -USB Suspend Mode supply current: -The USB standard limits power consumption to 500uA when the bus is in suspend -mode. This is not a problem for self-powered devices since they don't need -bus power anyway. Bus-powered devices can achieve this only by putting the -CPU in sleep mode. The driver does not implement suspend handling by itself. -However, the application may implement activity monitoring and wakeup from -sleep. The host sends regular SE0 states on the bus to keep it active. These -SE0 states can be detected by using D- as the interrupt source. Define -USB_COUNT_SOF to 1 and use the global variable usbSofCount to check for bus -activity. - -Operation without an USB master: -The driver behaves neutral without connection to an USB master if D- reads -as 1. To avoid spurious interrupts, we recommend a high impedance (e.g. 1M) -pull-down or pull-up resistor on D+ (interrupt). If Zener diodes are used, -use a pull-down. If D- becomes statically 0, the driver may block in the -interrupt routine. - -Interrupt latency: -The application must ensure that the USB interrupt is not disabled for more -than 25 cycles (this is for 12 MHz, faster clocks allow longer latency). -This implies that all interrupt routines must either be declared as "INTERRUPT" -instead of "SIGNAL" (see "avr/signal.h") or that they are written in assembler -with "sei" as the first instruction. - -Maximum interrupt duration / CPU cycle consumption: -The driver handles all USB communication during the interrupt service -routine. The routine will not return before an entire USB message is received -and the reply is sent. This may be up to ca. 1200 cycles @ 12 MHz (= 100us) if -the host conforms to the standard. The driver will consume CPU cycles for all -USB messages, even if they address another (low-speed) device on the same bus. - -*/ - -/* ------------------------------------------------------------------------- */ -/* --------------------------- Module Interface ---------------------------- */ -/* ------------------------------------------------------------------------- */ - -#define USBDRV_VERSION 20090323 -/* This define uniquely identifies a driver version. It is a decimal number - * constructed from the driver's release date in the form YYYYMMDD. If the - * driver's behavior or interface changes, you can use this constant to - * distinguish versions. If it is not defined, the driver's release date is - * older than 2006-01-25. - */ - - -#ifndef USB_PUBLIC -#define USB_PUBLIC -#endif -/* USB_PUBLIC is used as declaration attribute for all functions exported by - * the USB driver. The default is no attribute (see above). You may define it - * to static either in usbconfig.h or from the command line if you include - * usbdrv.c instead of linking against it. Including the C module of the driver - * directly in your code saves a couple of bytes in flash memory. - */ - -#ifndef __ASSEMBLER__ -#ifndef uchar -#define uchar unsigned char -#endif -#ifndef schar -#define schar signed char -#endif -/* shortcuts for well defined 8 bit integer types */ - -#if USB_CFG_LONG_TRANSFERS /* if more than 254 bytes transfer size required */ -# define usbMsgLen_t unsigned -#else -# define usbMsgLen_t uchar -#endif -/* usbMsgLen_t is the data type used for transfer lengths. By default, it is - * defined to uchar, allowing a maximum of 254 bytes (255 is reserved for - * USB_NO_MSG below). If the usbconfig.h defines USB_CFG_LONG_TRANSFERS to 1, - * a 16 bit data type is used, allowing up to 16384 bytes (the rest is used - * for flags in the descriptor configuration). - */ -#define USB_NO_MSG ((usbMsgLen_t)-1) /* constant meaning "no message" */ - -struct usbRequest; /* forward declaration */ - -USB_PUBLIC void usbInit(void); -/* This function must be called before interrupts are enabled and the main - * loop is entered. - */ -USB_PUBLIC void usbPoll(void); -/* This function must be called at regular intervals from the main loop. - * Maximum delay between calls is somewhat less than 50ms (USB timeout for - * accepting a Setup message). Otherwise the device will not be recognized. - * Please note that debug outputs through the UART take ~ 0.5ms per byte - * at 19200 bps. - */ -extern uchar *usbMsgPtr; -/* This variable may be used to pass transmit data to the driver from the - * implementation of usbFunctionWrite(). It is also used internally by the - * driver for standard control requests. - */ -USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]); -/* This function is called when the driver receives a SETUP transaction from - * the host which is not answered by the driver itself (in practice: class and - * vendor requests). All control transfers start with a SETUP transaction where - * the host communicates the parameters of the following (optional) data - * transfer. The SETUP data is available in the 'data' parameter which can - * (and should) be casted to 'usbRequest_t *' for a more user-friendly access - * to parameters. - * - * If the SETUP indicates a control-in transfer, you should provide the - * requested data to the driver. There are two ways to transfer this data: - * (1) Set the global pointer 'usbMsgPtr' to the base of the static RAM data - * block and return the length of the data in 'usbFunctionSetup()'. The driver - * will handle the rest. Or (2) return USB_NO_MSG in 'usbFunctionSetup()'. The - * driver will then call 'usbFunctionRead()' when data is needed. See the - * documentation for usbFunctionRead() for details. - * - * If the SETUP indicates a control-out transfer, the only way to receive the - * data from the host is through the 'usbFunctionWrite()' call. If you - * implement this function, you must return USB_NO_MSG in 'usbFunctionSetup()' - * to indicate that 'usbFunctionWrite()' should be used. See the documentation - * of this function for more information. If you just want to ignore the data - * sent by the host, return 0 in 'usbFunctionSetup()'. - * - * Note that calls to the functions usbFunctionRead() and usbFunctionWrite() - * are only done if enabled by the configuration in usbconfig.h. - */ -USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq); -/* You need to implement this function ONLY if you provide USB descriptors at - * runtime (which is an expert feature). It is very similar to - * usbFunctionSetup() above, but it is called only to request USB descriptor - * data. See the documentation of usbFunctionSetup() above for more info. - */ -#if USB_CFG_HAVE_INTRIN_ENDPOINT -USB_PUBLIC void usbSetInterrupt(uchar *data, uchar len); -/* This function sets the message which will be sent during the next interrupt - * IN transfer. The message is copied to an internal buffer and must not exceed - * a length of 8 bytes. The message may be 0 bytes long just to indicate the - * interrupt status to the host. - * If you need to transfer more bytes, use a control read after the interrupt. - */ -#define usbInterruptIsReady() (usbTxLen1 & 0x10) -/* This macro indicates whether the last interrupt message has already been - * sent. If you set a new interrupt message before the old was sent, the - * message already buffered will be lost. - */ -#if USB_CFG_HAVE_INTRIN_ENDPOINT3 -USB_PUBLIC void usbSetInterrupt3(uchar *data, uchar len); -#define usbInterruptIsReady3() (usbTxLen3 & 0x10) -/* Same as above for endpoint 3 */ -#endif -#endif /* USB_CFG_HAVE_INTRIN_ENDPOINT */ -#if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH /* simplified interface for backward compatibility */ -#define usbHidReportDescriptor usbDescriptorHidReport -/* should be declared as: PROGMEM char usbHidReportDescriptor[]; */ -/* If you implement an HID device, you need to provide a report descriptor. - * The HID report descriptor syntax is a bit complex. If you understand how - * report descriptors are constructed, we recommend that you use the HID - * Descriptor Tool from usb.org, see http://www.usb.org/developers/hidpage/. - * Otherwise you should probably start with a working example. - */ -#endif /* USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH */ -#if USB_CFG_IMPLEMENT_FN_WRITE -USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len); -/* This function is called by the driver to provide a control transfer's - * payload data (control-out). It is called in chunks of up to 8 bytes. The - * total count provided in the current control transfer can be obtained from - * the 'length' property in the setup data. If an error occurred during - * processing, return 0xff (== -1). The driver will answer the entire transfer - * with a STALL token in this case. If you have received the entire payload - * successfully, return 1. If you expect more data, return 0. If you don't - * know whether the host will send more data (you should know, the total is - * provided in the usbFunctionSetup() call!), return 1. - * NOTE: If you return 0xff for STALL, 'usbFunctionWrite()' may still be called - * for the remaining data. You must continue to return 0xff for STALL in these - * calls. - * In order to get usbFunctionWrite() called, define USB_CFG_IMPLEMENT_FN_WRITE - * to 1 in usbconfig.h and return 0xff in usbFunctionSetup().. - */ -#endif /* USB_CFG_IMPLEMENT_FN_WRITE */ -#if USB_CFG_IMPLEMENT_FN_READ -USB_PUBLIC uchar usbFunctionRead(uchar *data, uchar len); -/* This function is called by the driver to ask the application for a control - * transfer's payload data (control-in). It is called in chunks of up to 8 - * bytes each. You should copy the data to the location given by 'data' and - * return the actual number of bytes copied. If you return less than requested, - * the control-in transfer is terminated. If you return 0xff, the driver aborts - * the transfer with a STALL token. - * In order to get usbFunctionRead() called, define USB_CFG_IMPLEMENT_FN_READ - * to 1 in usbconfig.h and return 0xff in usbFunctionSetup().. - */ -#endif /* USB_CFG_IMPLEMENT_FN_READ */ - -extern uchar usbRxToken; /* may be used in usbFunctionWriteOut() below */ -#if USB_CFG_IMPLEMENT_FN_WRITEOUT -USB_PUBLIC void usbFunctionWriteOut(uchar *data, uchar len); -/* This function is called by the driver when data is received on an interrupt- - * or bulk-out endpoint. The endpoint number can be found in the global - * variable usbRxToken. You must define USB_CFG_IMPLEMENT_FN_WRITEOUT to 1 in - * usbconfig.h to get this function called. - */ -#endif /* USB_CFG_IMPLEMENT_FN_WRITEOUT */ -#ifdef USB_CFG_PULLUP_IOPORTNAME -#define usbDeviceConnect() ((USB_PULLUP_DDR |= (1<device, 1=device->host - * t ..... type: 0=standard, 1=class, 2=vendor, 3=reserved - * r ..... recipient: 0=device, 1=interface, 2=endpoint, 3=other - */ - -/* USB setup recipient values */ -#define USBRQ_RCPT_MASK 0x1f -#define USBRQ_RCPT_DEVICE 0 -#define USBRQ_RCPT_INTERFACE 1 -#define USBRQ_RCPT_ENDPOINT 2 - -/* USB request type values */ -#define USBRQ_TYPE_MASK 0x60 -#define USBRQ_TYPE_STANDARD (0<<5) -#define USBRQ_TYPE_CLASS (1<<5) -#define USBRQ_TYPE_VENDOR (2<<5) - -/* USB direction values: */ -#define USBRQ_DIR_MASK 0x80 -#define USBRQ_DIR_HOST_TO_DEVICE (0<<7) -#define USBRQ_DIR_DEVICE_TO_HOST (1<<7) - -/* USB Standard Requests */ -#define USBRQ_GET_STATUS 0 -#define USBRQ_CLEAR_FEATURE 1 -#define USBRQ_SET_FEATURE 3 -#define USBRQ_SET_ADDRESS 5 -#define USBRQ_GET_DESCRIPTOR 6 -#define USBRQ_SET_DESCRIPTOR 7 -#define USBRQ_GET_CONFIGURATION 8 -#define USBRQ_SET_CONFIGURATION 9 -#define USBRQ_GET_INTERFACE 10 -#define USBRQ_SET_INTERFACE 11 -#define USBRQ_SYNCH_FRAME 12 - -/* USB descriptor constants */ -#define USBDESCR_DEVICE 1 -#define USBDESCR_CONFIG 2 -#define USBDESCR_STRING 3 -#define USBDESCR_INTERFACE 4 -#define USBDESCR_ENDPOINT 5 -#define USBDESCR_HID 0x21 -#define USBDESCR_HID_REPORT 0x22 -#define USBDESCR_HID_PHYS 0x23 - -#define USBATTR_BUSPOWER 0x80 -#define USBATTR_SELFPOWER 0x40 -#define USBATTR_REMOTEWAKE 0x20 - -/* USB HID Requests */ -#define USBRQ_HID_GET_REPORT 0x01 -#define USBRQ_HID_GET_IDLE 0x02 -#define USBRQ_HID_GET_PROTOCOL 0x03 -#define USBRQ_HID_SET_REPORT 0x09 -#define USBRQ_HID_SET_IDLE 0x0a -#define USBRQ_HID_SET_PROTOCOL 0x0b - -/* ------------------------------------------------------------------------- */ - -#endif /* __usbdrv_h_included__ */ diff --git a/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm.S b/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm.S deleted file mode 100644 index 52c3d98..0000000 --- a/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm.S +++ /dev/null @@ -1,305 +0,0 @@ -/* Name: usbdrvasm.S - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2007-06-13 - * Tabsize: 4 - * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * Revision: $Id: usbdrvasm.S 722 2009-03-16 19:03:57Z cs $ - */ - -/* -General Description: -This module is the assembler part of the USB driver. This file contains -general code (preprocessor acrobatics and CRC computation) and then includes -the file appropriate for the given clock rate. -*/ - -#define __SFR_OFFSET 0 /* used by avr-libc's register definitions */ -#include "usbportability.h" -#include "usbdrv.h" /* for common defs */ - -/* register names */ -#define x1 r16 -#define x2 r17 -#define shift r18 -#define cnt r19 -#define x3 r20 -#define x4 r21 -#define x5 r22 -#define bitcnt x5 -#define phase x4 -#define leap x4 - -/* Some assembler dependent definitions and declarations: */ - -#ifdef __IAR_SYSTEMS_ASM__ - extern usbRxBuf, usbDeviceAddr, usbNewDeviceAddr, usbInputBufOffset - extern usbCurrentTok, usbRxLen, usbRxToken, usbTxLen - extern usbTxBuf, usbTxStatus1, usbTxStatus3 -# if USB_COUNT_SOF - extern usbSofCount -# endif - public usbCrc16 - public usbCrc16Append - - COMMON INTVEC -# ifndef USB_INTR_VECTOR - ORG INT0_vect -# else /* USB_INTR_VECTOR */ - ORG USB_INTR_VECTOR -# undef USB_INTR_VECTOR -# endif /* USB_INTR_VECTOR */ -# define USB_INTR_VECTOR usbInterruptHandler - rjmp USB_INTR_VECTOR - RSEG CODE - -#else /* __IAR_SYSTEMS_ASM__ */ - -# ifndef USB_INTR_VECTOR /* default to hardware interrupt INT0 */ -# define USB_INTR_VECTOR SIG_INTERRUPT0 -# endif - .text - .global USB_INTR_VECTOR - .type USB_INTR_VECTOR, @function - .global usbCrc16 - .global usbCrc16Append -#endif /* __IAR_SYSTEMS_ASM__ */ - - -#if USB_INTR_PENDING < 0x40 /* This is an I/O address, use in and out */ -# define USB_LOAD_PENDING(reg) in reg, USB_INTR_PENDING -# define USB_STORE_PENDING(reg) out USB_INTR_PENDING, reg -#else /* It's a memory address, use lds and sts */ -# define USB_LOAD_PENDING(reg) lds reg, USB_INTR_PENDING -# define USB_STORE_PENDING(reg) sts USB_INTR_PENDING, reg -#endif - -#define usbTxLen1 usbTxStatus1 -#define usbTxBuf1 (usbTxStatus1 + 1) -#define usbTxLen3 usbTxStatus3 -#define usbTxBuf3 (usbTxStatus3 + 1) - - -;---------------------------------------------------------------------------- -; Utility functions -;---------------------------------------------------------------------------- - -#ifdef __IAR_SYSTEMS_ASM__ -/* Register assignments for usbCrc16 on IAR cc */ -/* Calling conventions on IAR: - * First parameter passed in r16/r17, second in r18/r19 and so on. - * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer) - * Result is passed in r16/r17 - * In case of the "tiny" memory model, pointers are only 8 bit with no - * padding. We therefore pass argument 1 as "16 bit unsigned". - */ -RTMODEL "__rt_version", "3" -/* The line above will generate an error if cc calling conventions change. - * The value "3" above is valid for IAR 4.10B/W32 - */ -# define argLen r18 /* argument 2 */ -# define argPtrL r16 /* argument 1 */ -# define argPtrH r17 /* argument 1 */ - -# define resCrcL r16 /* result */ -# define resCrcH r17 /* result */ - -# define ptrL ZL -# define ptrH ZH -# define ptr Z -# define byte r22 -# define bitCnt r19 -# define polyL r20 -# define polyH r21 -# define scratch r23 - -#else /* __IAR_SYSTEMS_ASM__ */ -/* Register assignments for usbCrc16 on gcc */ -/* Calling conventions on gcc: - * First parameter passed in r24/r25, second in r22/23 and so on. - * Callee must preserve r1-r17, r28/r29 - * Result is passed in r24/r25 - */ -# define argLen r22 /* argument 2 */ -# define argPtrL r24 /* argument 1 */ -# define argPtrH r25 /* argument 1 */ - -# define resCrcL r24 /* result */ -# define resCrcH r25 /* result */ - -# define ptrL XL -# define ptrH XH -# define ptr x -# define byte r18 -# define bitCnt r19 -# define polyL r20 -# define polyH r21 -# define scratch r23 - -#endif - -; extern unsigned usbCrc16(unsigned char *data, unsigned char len); -; data: r24/25 -; len: r22 -; temp variables: -; r18: data byte -; r19: bit counter -; r20/21: polynomial -; r23: scratch -; r24/25: crc-sum -; r26/27=X: ptr -usbCrc16: - mov ptrL, argPtrL - mov ptrH, argPtrH - ldi resCrcL, 0 - ldi resCrcH, 0 - ldi polyL, lo8(0xa001) - ldi polyH, hi8(0xa001) - com argLen ; argLen = -argLen - 1 -crcByteLoop: - subi argLen, -1 - brcc crcReady ; modified loop to ensure that carry is set below - ld byte, ptr+ - ldi bitCnt, -8 ; strange loop counter to ensure that carry is set where we need it - eor resCrcL, byte -crcBitLoop: - ror resCrcH ; carry is always set here - ror resCrcL - brcs crcNoXor - eor resCrcL, polyL - eor resCrcH, polyH -crcNoXor: - subi bitCnt, -1 - brcs crcBitLoop - rjmp crcByteLoop -crcReady: - ret -; Thanks to Reimar Doeffinger for optimizing this CRC routine! - -; extern unsigned usbCrc16Append(unsigned char *data, unsigned char len); -usbCrc16Append: - rcall usbCrc16 - st ptr+, resCrcL - st ptr+, resCrcH - ret - -#undef argLen -#undef argPtrL -#undef argPtrH -#undef resCrcL -#undef resCrcH -#undef ptrL -#undef ptrH -#undef ptr -#undef byte -#undef bitCnt -#undef polyL -#undef polyH -#undef scratch - - -#if USB_CFG_HAVE_MEASURE_FRAME_LENGTH -#ifdef __IAR_SYSTEMS_ASM__ -/* Register assignments for usbMeasureFrameLength on IAR cc */ -/* Calling conventions on IAR: - * First parameter passed in r16/r17, second in r18/r19 and so on. - * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer) - * Result is passed in r16/r17 - * In case of the "tiny" memory model, pointers are only 8 bit with no - * padding. We therefore pass argument 1 as "16 bit unsigned". - */ -# define resL r16 -# define resH r17 -# define cnt16L r30 -# define cnt16H r31 -# define cntH r18 - -#else /* __IAR_SYSTEMS_ASM__ */ -/* Register assignments for usbMeasureFrameLength on gcc */ -/* Calling conventions on gcc: - * First parameter passed in r24/r25, second in r22/23 and so on. - * Callee must preserve r1-r17, r28/r29 - * Result is passed in r24/r25 - */ -# define resL r24 -# define resH r25 -# define cnt16L r24 -# define cnt16H r25 -# define cntH r26 -#endif -# define cnt16 cnt16L - -; extern unsigned usbMeasurePacketLength(void); -; returns time between two idle strobes in multiples of 7 CPU clocks -.global usbMeasureFrameLength -usbMeasureFrameLength: - ldi cntH, 6 ; wait ~ 10 ms for D- == 0 - clr cnt16L - clr cnt16H -usbMFTime16: - dec cntH - breq usbMFTimeout -usbMFWaitStrobe: ; first wait for D- == 0 (idle strobe) - sbiw cnt16, 1 ;[0] [6] - breq usbMFTime16 ;[2] - sbic USBIN, USBMINUS ;[3] - rjmp usbMFWaitStrobe ;[4] -usbMFWaitIdle: ; then wait until idle again - sbis USBIN, USBMINUS ;1 wait for D- == 1 - rjmp usbMFWaitIdle ;2 - ldi cnt16L, 1 ;1 represents cycles so far - clr cnt16H ;1 -usbMFWaitLoop: - in cntH, USBIN ;[0] [7] - adiw cnt16, 1 ;[1] - breq usbMFTimeout ;[3] - andi cntH, USBMASK ;[4] - brne usbMFWaitLoop ;[5] -usbMFTimeout: -#if resL != cnt16L - mov resL, cnt16L - mov resH, cnt16H -#endif - ret - -#undef resL -#undef resH -#undef cnt16 -#undef cnt16L -#undef cnt16H -#undef cntH - -#endif /* USB_CFG_HAVE_MEASURE_FRAME_LENGTH */ - -;---------------------------------------------------------------------------- -; Now include the clock rate specific code -;---------------------------------------------------------------------------- - -#ifndef USB_CFG_CLOCK_KHZ -# define USB_CFG_CLOCK_KHZ 12000 -#endif - -#if USB_CFG_CHECK_CRC /* separate dispatcher for CRC type modules */ -# if USB_CFG_CLOCK_KHZ == 18000 -# include "usbdrvasm18-crc.inc" -# else -# error "USB_CFG_CLOCK_KHZ is not one of the supported crc-rates!" -# endif -#else /* USB_CFG_CHECK_CRC */ -# if USB_CFG_CLOCK_KHZ == 12000 -# include "usbdrvasm12.inc" -# elif USB_CFG_CLOCK_KHZ == 12800 -# include "usbdrvasm128.inc" -# elif USB_CFG_CLOCK_KHZ == 15000 -# include "usbdrvasm15.inc" -# elif USB_CFG_CLOCK_KHZ == 16000 -# include "usbdrvasm16.inc" -# elif USB_CFG_CLOCK_KHZ == 16500 -# include "usbdrvasm165.inc" -# elif USB_CFG_CLOCK_KHZ == 20000 -# include "usbdrvasm20.inc" -# else -# error "USB_CFG_CLOCK_KHZ is not one of the supported non-crc-rates!" -# endif -#endif /* USB_CFG_CHECK_CRC */ diff --git a/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm.asm b/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm.asm deleted file mode 100644 index a534b73..0000000 --- a/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm.asm +++ /dev/null @@ -1,21 +0,0 @@ -/* Name: usbdrvasm.asm - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2006-03-01 - * Tabsize: 4 - * Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id$ - */ - -/* -General Description: -The IAR compiler/assembler system prefers assembler files with file extension -".asm". We simply provide this file as an alias for usbdrvasm.S. - -Thanks to Oleg Semyonov for his help with the IAR tools port! -*/ - -#include "usbdrvasm.S" - -end diff --git a/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm12.inc b/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm12.inc deleted file mode 100644 index 08dddd3..0000000 --- a/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm12.inc +++ /dev/null @@ -1,393 +0,0 @@ -/* Name: usbdrvasm12.inc - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2004-12-29 - * Tabsize: 4 - * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: usbdrvasm12.inc 692 2008-11-07 15:07:40Z cs $ - */ - -/* Do not link this file! Link usbdrvasm.S instead, which includes the - * appropriate implementation! - */ - -/* -General Description: -This file is the 12 MHz version of the asssembler part of the USB driver. It -requires a 12 MHz crystal (not a ceramic resonator and not a calibrated RC -oscillator). - -See usbdrv.h for a description of the entire driver. - -Since almost all of this code is timing critical, don't change unless you -really know what you are doing! Many parts require not only a maximum number -of CPU cycles, but even an exact number of cycles! - - -Timing constraints according to spec (in bit times): -timing subject min max CPUcycles ---------------------------------------------------------------------------- -EOP of OUT/SETUP to sync pattern of DATA0 (both rx) 2 16 16-128 -EOP of IN to sync pattern of DATA0 (rx, then tx) 2 7.5 16-60 -DATAx (rx) to ACK/NAK/STALL (tx) 2 7.5 16-60 -*/ - -;Software-receiver engine. Strict timing! Don't change unless you can preserve timing! -;interrupt response time: 4 cycles + insn running = 7 max if interrupts always enabled -;max allowable interrupt latency: 34 cycles -> max 25 cycles interrupt disable -;max stack usage: [ret(2), YL, SREG, YH, shift, x1, x2, x3, cnt, x4] = 11 bytes -;Numbers in brackets are maximum cycles since SOF. -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt - push YL ;2 [35] push only what is necessary to sync with edge ASAP - in YL, SREG ;1 [37] - push YL ;2 [39] -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of 1/4 bit which meets the spec. - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -foundK: -;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling] -;we have 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push YH ;2 [2] - lds YL, usbInputBufOffset;2 [4] - clr YH ;1 [5] - subi YL, lo8(-(usbRxBuf));1 [6] - sbci YH, hi8(-(usbRxBuf));1 [7] - - sbis USBIN, USBMINUS ;1 [8] we want two bits K [sample 1 cycle too early] - rjmp haveTwoBitsK ;2 [10] - pop YH ;2 [11] undo the push from before - rjmp waitForK ;2 [13] this was not the end of sync, retry -haveTwoBitsK: -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- - push shift ;2 [16] - push x1 ;2 [12] - push x2 ;2 [14] - - in x1, USBIN ;1 [17] <-- sample bit 0 - ldi shift, 0xff ;1 [18] - bst x1, USBMINUS ;1 [19] - bld shift, 0 ;1 [20] - push x3 ;2 [22] - push cnt ;2 [24] - - in x2, USBIN ;1 [25] <-- sample bit 1 - ser x3 ;1 [26] [inserted init instruction] - eor x1, x2 ;1 [27] - bst x1, USBMINUS ;1 [28] - bld shift, 1 ;1 [29] - ldi cnt, USB_BUFSIZE;1 [30] [inserted init instruction] - rjmp rxbit2 ;2 [32] - -;---------------------------------------------------------------------------- -; Receiver loop (numbers in brackets are cycles within byte after instr) -;---------------------------------------------------------------------------- - -unstuff0: ;1 (branch taken) - andi x3, ~0x01 ;1 [15] - mov x1, x2 ;1 [16] x2 contains last sampled (stuffed) bit - in x2, USBIN ;1 [17] <-- sample bit 1 again - ori shift, 0x01 ;1 [18] - rjmp didUnstuff0 ;2 [20] - -unstuff1: ;1 (branch taken) - mov x2, x1 ;1 [21] x1 contains last sampled (stuffed) bit - andi x3, ~0x02 ;1 [22] - ori shift, 0x02 ;1 [23] - nop ;1 [24] - in x1, USBIN ;1 [25] <-- sample bit 2 again - rjmp didUnstuff1 ;2 [27] - -unstuff2: ;1 (branch taken) - andi x3, ~0x04 ;1 [29] - ori shift, 0x04 ;1 [30] - mov x1, x2 ;1 [31] x2 contains last sampled (stuffed) bit - nop ;1 [32] - in x2, USBIN ;1 [33] <-- sample bit 3 - rjmp didUnstuff2 ;2 [35] - -unstuff3: ;1 (branch taken) - in x2, USBIN ;1 [34] <-- sample stuffed bit 3 [one cycle too late] - andi x3, ~0x08 ;1 [35] - ori shift, 0x08 ;1 [36] - rjmp didUnstuff3 ;2 [38] - -unstuff4: ;1 (branch taken) - andi x3, ~0x10 ;1 [40] - in x1, USBIN ;1 [41] <-- sample stuffed bit 4 - ori shift, 0x10 ;1 [42] - rjmp didUnstuff4 ;2 [44] - -unstuff5: ;1 (branch taken) - andi x3, ~0x20 ;1 [48] - in x2, USBIN ;1 [49] <-- sample stuffed bit 5 - ori shift, 0x20 ;1 [50] - rjmp didUnstuff5 ;2 [52] - -unstuff6: ;1 (branch taken) - andi x3, ~0x40 ;1 [56] - in x1, USBIN ;1 [57] <-- sample stuffed bit 6 - ori shift, 0x40 ;1 [58] - rjmp didUnstuff6 ;2 [60] - -; extra jobs done during bit interval: -; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs] -; bit 1: se0 check -; bit 2: overflow check -; bit 3: recovery from delay [bit 0 tasks took too long] -; bit 4: none -; bit 5: none -; bit 6: none -; bit 7: jump, eor -rxLoop: - eor x3, shift ;1 [0] reconstruct: x3 is 0 at bit locations we changed, 1 at others - in x1, USBIN ;1 [1] <-- sample bit 0 - st y+, x3 ;2 [3] store data - ser x3 ;1 [4] - nop ;1 [5] - eor x2, x1 ;1 [6] - bst x2, USBMINUS;1 [7] - bld shift, 0 ;1 [8] - in x2, USBIN ;1 [9] <-- sample bit 1 (or possibly bit 0 stuffed) - andi x2, USBMASK ;1 [10] - breq se0 ;1 [11] SE0 check for bit 1 - andi shift, 0xf9 ;1 [12] -didUnstuff0: - breq unstuff0 ;1 [13] - eor x1, x2 ;1 [14] - bst x1, USBMINUS;1 [15] - bld shift, 1 ;1 [16] -rxbit2: - in x1, USBIN ;1 [17] <-- sample bit 2 (or possibly bit 1 stuffed) - andi shift, 0xf3 ;1 [18] - breq unstuff1 ;1 [19] do remaining work for bit 1 -didUnstuff1: - subi cnt, 1 ;1 [20] - brcs overflow ;1 [21] loop control - eor x2, x1 ;1 [22] - bst x2, USBMINUS;1 [23] - bld shift, 2 ;1 [24] - in x2, USBIN ;1 [25] <-- sample bit 3 (or possibly bit 2 stuffed) - andi shift, 0xe7 ;1 [26] - breq unstuff2 ;1 [27] -didUnstuff2: - eor x1, x2 ;1 [28] - bst x1, USBMINUS;1 [29] - bld shift, 3 ;1 [30] -didUnstuff3: - andi shift, 0xcf ;1 [31] - breq unstuff3 ;1 [32] - in x1, USBIN ;1 [33] <-- sample bit 4 - eor x2, x1 ;1 [34] - bst x2, USBMINUS;1 [35] - bld shift, 4 ;1 [36] -didUnstuff4: - andi shift, 0x9f ;1 [37] - breq unstuff4 ;1 [38] - nop2 ;2 [40] - in x2, USBIN ;1 [41] <-- sample bit 5 - eor x1, x2 ;1 [42] - bst x1, USBMINUS;1 [43] - bld shift, 5 ;1 [44] -didUnstuff5: - andi shift, 0x3f ;1 [45] - breq unstuff5 ;1 [46] - nop2 ;2 [48] - in x1, USBIN ;1 [49] <-- sample bit 6 - eor x2, x1 ;1 [50] - bst x2, USBMINUS;1 [51] - bld shift, 6 ;1 [52] -didUnstuff6: - cpi shift, 0x02 ;1 [53] - brlo unstuff6 ;1 [54] - nop2 ;2 [56] - in x2, USBIN ;1 [57] <-- sample bit 7 - eor x1, x2 ;1 [58] - bst x1, USBMINUS;1 [59] - bld shift, 7 ;1 [60] -didUnstuff7: - cpi shift, 0x04 ;1 [61] - brsh rxLoop ;2 [63] loop control -unstuff7: - andi x3, ~0x80 ;1 [63] - ori shift, 0x80 ;1 [64] - in x2, USBIN ;1 [65] <-- sample stuffed bit 7 - nop ;1 [66] - rjmp didUnstuff7 ;2 [68] - -macro POP_STANDARD ; 12 cycles - pop cnt - pop x3 - pop x2 - pop x1 - pop shift - pop YH - endm -macro POP_RETI ; 5 cycles - pop YL - out SREG, YL - pop YL - endm - -#include "asmcommon.inc" - -;---------------------------------------------------------------------------- -; Transmitting data -;---------------------------------------------------------------------------- - -txByteLoop: -txBitloop: -stuffN1Delay: ; [03] - ror shift ;[-5] [11] [59] - brcc doExorN1 ;[-4] [60] - subi x4, 1 ;[-3] - brne commonN1 ;[-2] - lsl shift ;[-1] compensate ror after rjmp stuffDelay - nop ;[00] stuffing consists of just waiting 8 cycles - rjmp stuffN1Delay ;[01] after ror, C bit is reliably clear - -sendNakAndReti: ;0 [-19] 19 cycles until SOP - ldi x3, USBPID_NAK ;1 [-18] - rjmp usbSendX3 ;2 [-16] -sendAckAndReti: ;0 [-19] 19 cycles until SOP - ldi x3, USBPID_ACK ;1 [-18] - rjmp usbSendX3 ;2 [-16] -sendCntAndReti: ;0 [-17] 17 cycles until SOP - mov x3, cnt ;1 [-16] -usbSendX3: ;0 [-16] - ldi YL, 20 ;1 [-15] 'x3' is R20 - ldi YH, 0 ;1 [-14] - ldi cnt, 2 ;1 [-13] -; rjmp usbSendAndReti fallthrough - -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) or USBOUT = 0x01 -; K = (D+ = 1), (D- = 0) or USBOUT = 0x02 -; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles) - -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte -;uses: x1...x2, x4, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x4 = bitstuff cnt] -;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction) -usbSendAndReti: - in x2, USBDDR ;[-12] 12 cycles until SOP - ori x2, USBMASK ;[-11] - sbi USBOUT, USBMINUS ;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) - out USBDDR, x2 ;[-8] <--- acquire bus - in x1, USBOUT ;[-7] port mirror for tx loop - ldi shift, 0x40 ;[-6] sync byte is first byte sent (we enter loop after ror) - ldi x2, USBMASK ;[-5] - push x4 ;[-4] -doExorN1: - eor x1, x2 ;[-2] [06] [62] - ldi x4, 6 ;[-1] [07] [63] -commonN1: -stuffN2Delay: - out USBOUT, x1 ;[00] [08] [64] <--- set bit - ror shift ;[01] - brcc doExorN2 ;[02] - subi x4, 1 ;[03] - brne commonN2 ;[04] - lsl shift ;[05] compensate ror after rjmp stuffDelay - rjmp stuffN2Delay ;[06] after ror, C bit is reliably clear -doExorN2: - eor x1, x2 ;[04] [12] - ldi x4, 6 ;[05] [13] -commonN2: - nop ;[06] [14] - subi cnt, 171 ;[07] [15] trick: (3 * 171) & 0xff = 1 - out USBOUT, x1 ;[08] [16] <--- set bit - brcs txBitloop ;[09] [25] [41] - -stuff6Delay: - ror shift ;[42] [50] - brcc doExor6 ;[43] - subi x4, 1 ;[44] - brne common6 ;[45] - lsl shift ;[46] compensate ror after rjmp stuffDelay - nop ;[47] stuffing consists of just waiting 8 cycles - rjmp stuff6Delay ;[48] after ror, C bit is reliably clear -doExor6: - eor x1, x2 ;[45] [53] - ldi x4, 6 ;[46] -common6: -stuff7Delay: - ror shift ;[47] [55] - out USBOUT, x1 ;[48] <--- set bit - brcc doExor7 ;[49] - subi x4, 1 ;[50] - brne common7 ;[51] - lsl shift ;[52] compensate ror after rjmp stuffDelay - rjmp stuff7Delay ;[53] after ror, C bit is reliably clear -doExor7: - eor x1, x2 ;[51] [59] - ldi x4, 6 ;[52] -common7: - ld shift, y+ ;[53] - tst cnt ;[55] - out USBOUT, x1 ;[56] <--- set bit - brne txByteLoop ;[57] - -;make SE0: - cbr x1, USBMASK ;[58] prepare SE0 [spec says EOP may be 15 to 18 cycles] - lds x2, usbNewDeviceAddr;[59] - lsl x2 ;[61] we compare with left shifted address - subi YL, 2 + 20 ;[62] Only assign address on data packets, not ACK/NAK in x3 - sbci YH, 0 ;[63] - out USBOUT, x1 ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - breq skipAddrAssign ;[01] - sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer -skipAddrAssign: -;end of usbDeviceAddress transfer - ldi x2, 1< 12.5625 MHz -max frequency: 69.286 cycles for 8 bit -> 12.99 MHz -nominal frequency: 12.77 MHz ( = sqrt(min * max)) - -sampling positions: (next even number in range [+/- 0.5]) -cycle index range: 0 ... 66 -bits: -.5, 8.875, 17.25, 25.625, 34, 42.375, 50.75, 59.125 -[0/1], [9], [17], [25/+26], [34], [+42/43], [51], [59] - -bit number: 0 1 2 3 4 5 6 7 -spare cycles 1 2 1 2 1 1 1 0 - -operations to perform: duration cycle - ---------------- - eor fix, shift 1 -> 00 - andi phase, USBMASK 1 -> 08 - breq se0 1 -> 16 (moved to 11) - st y+, data 2 -> 24, 25 - mov data, fix 1 -> 33 - ser data 1 -> 41 - subi cnt, 1 1 -> 49 - brcs overflow 1 -> 50 - -layout of samples and operations: -[##] = sample bit -<##> = sample phase -*##* = operation - -0: *00* [01] 02 03 04 <05> 06 07 -1: *08* [09] 10 11 12 <13> 14 15 *16* -2: [17] 18 19 20 <21> 22 23 -3: *24* *25* [26] 27 28 29 <30> 31 32 -4: *33* [34] 35 36 37 <38> 39 40 -5: *41* [42] 43 44 45 <46> 47 48 -6: *49* *50* [51] 52 53 54 <55> 56 57 58 -7: [59] 60 61 62 <63> 64 65 66 -*****************************************************************************/ - -/* we prefer positive expressions (do if condition) instead of negative - * (skip if condition), therefore use defines for skip instructions: - */ -#define ifioclr sbis -#define ifioset sbic -#define ifrclr sbrs -#define ifrset sbrc - -/* The registers "fix" and "data" swap their meaning during the loop. Use - * defines to keep their name constant. - */ -#define fix x2 -#define data x1 -#undef phase /* phase has a default definition to x4 */ -#define phase x3 - - -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt, r0 - push YL ;2 push only what is necessary to sync with edge ASAP - in YL, SREG ;1 - push YL ;2 -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of 1/4 bit which meets the spec. - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS ;[0] - rjmp foundK ;[1] -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError - -foundK: -;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling] -;we have 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push YH ;[2] - lds YL, usbInputBufOffset;[4] - clr YH ;[6] - subi YL, lo8(-(usbRxBuf));[7] - sbci YH, hi8(-(usbRxBuf));[8] - - sbis USBIN, USBMINUS ;[9] we want two bits K [we want to sample at 8 + 4 - 1.5 = 10.5] - rjmp haveTwoBitsK ;[10] - pop YH ;[11] undo the push from before - rjmp waitForK ;[13] this was not the end of sync, retry -haveTwoBitsK: -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -#define fix x2 -#define data x1 - - push shift ;[12] - push x1 ;[14] - push x2 ;[16] - ldi shift, 0x80 ;[18] prevent bit-unstuffing but init low bits to 0 - ifioset USBIN, USBMINUS ;[19] [01] <--- bit 0 [10.5 + 8 = 18.5] - ori shift, 1<<0 ;[02] - push x3 ;[03] - push cnt ;[05] - push r0 ;[07] - ifioset USBIN, USBMINUS ;[09] <--- bit 1 - ori shift, 1<<1 ;[10] - ser fix ;[11] - ldi cnt, USB_BUFSIZE ;[12] - mov data, shift ;[13] - lsl shift ;[14] - nop2 ;[15] - ifioset USBIN, USBMINUS ;[17] <--- bit 2 - ori data, 3<<2 ;[18] store in bit 2 AND bit 3 - eor shift, data ;[19] do nrzi decoding - andi data, 1<<3 ;[20] - in phase, USBIN ;[21] <- phase - brne jumpToEntryAfterSet ;[22] if USBMINS at bit 3 was 1 - nop ;[23] - rjmp entryAfterClr ;[24] -jumpToEntryAfterSet: - rjmp entryAfterSet ;[24] - -;---------------------------------------------------------------------------- -; Receiver loop (numbers in brackets are cycles within byte after instr) -;---------------------------------------------------------------------------- -#undef fix -#define fix x1 -#undef data -#define data x2 - -bit7IsSet: - ifrclr phase, USBMINUS ;[62] check phase only if D- changed - lpm ;[63] - in phase, USBIN ;[64] <- phase (one cycle too late) - ori shift, 1 << 7 ;[65] - nop ;[66] -;;;;rjmp bit0AfterSet ; -> [00] == [67] moved block up to save jump -bit0AfterSet: - eor fix, shift ;[00] -#undef fix -#define fix x2 -#undef data -#define data x1 /* we now have result in data, fix is reset to 0xff */ - ifioclr USBIN, USBMINUS ;[01] <--- sample 0 - rjmp bit0IsClr ;[02] - andi shift, ~(7 << 0) ;[03] - breq unstuff0s ;[04] - in phase, USBIN ;[05] <- phase - rjmp bit1AfterSet ;[06] -unstuff0s: - in phase, USBIN ;[06] <- phase (one cycle too late) - andi fix, ~(1 << 0) ;[07] - ifioclr USBIN, USBMINUS ;[00] - ifioset USBIN, USBPLUS ;[01] - rjmp bit0IsClr ;[02] executed if first expr false or second true -jumpToSe0AndStore: - rjmp se0AndStore ;[03] executed only if both bits 0 -bit0IsClr: - ifrset phase, USBMINUS ;[04] check phase only if D- changed - lpm ;[05] - in phase, USBIN ;[06] <- phase (one cycle too late) - ori shift, 1 << 0 ;[07] -bit1AfterClr: - andi phase, USBMASK ;[08] - ifioset USBIN, USBMINUS ;[09] <--- sample 1 - rjmp bit1IsSet ;[10] - breq jumpToSe0AndStore ;[11] - andi shift, ~(7 << 1) ;[12] - in phase, USBIN ;[13] <- phase - breq unstuff1c ;[14] - rjmp bit2AfterClr ;[15] -unstuff1c: - andi fix, ~(1 << 1) ;[16] - nop2 ;[08] - nop2 ;[10] -bit1IsSet: - ifrclr phase, USBMINUS ;[12] check phase only if D- changed - lpm ;[13] - in phase, USBIN ;[14] <- phase (one cycle too late) - ori shift, 1 << 1 ;[15] - nop ;[16] -bit2AfterSet: - ifioclr USBIN, USBMINUS ;[17] <--- sample 2 - rjmp bit2IsClr ;[18] - andi shift, ~(7 << 2) ;[19] - breq unstuff2s ;[20] - in phase, USBIN ;[21] <- phase - rjmp bit3AfterSet ;[22] -unstuff2s: - in phase, USBIN ;[22] <- phase (one cycle too late) - andi fix, ~(1 << 2) ;[23] - nop2 ;[16] - nop2 ;[18] -bit2IsClr: - ifrset phase, USBMINUS ;[20] check phase only if D- changed - lpm ;[21] - in phase, USBIN ;[22] <- phase (one cycle too late) - ori shift, 1 << 2 ;[23] -bit3AfterClr: - st y+, data ;[24] -entryAfterClr: - ifioset USBIN, USBMINUS ;[26] <--- sample 3 - rjmp bit3IsSet ;[27] - andi shift, ~(7 << 3) ;[28] - breq unstuff3c ;[29] - in phase, USBIN ;[30] <- phase - rjmp bit4AfterClr ;[31] -unstuff3c: - in phase, USBIN ;[31] <- phase (one cycle too late) - andi fix, ~(1 << 3) ;[32] - nop2 ;[25] - nop2 ;[27] -bit3IsSet: - ifrclr phase, USBMINUS ;[29] check phase only if D- changed - lpm ;[30] - in phase, USBIN ;[31] <- phase (one cycle too late) - ori shift, 1 << 3 ;[32] -bit4AfterSet: - mov data, fix ;[33] undo this move by swapping defines -#undef fix -#define fix x1 -#undef data -#define data x2 - ifioclr USBIN, USBMINUS ;[34] <--- sample 4 - rjmp bit4IsClr ;[35] - andi shift, ~(7 << 4) ;[36] - breq unstuff4s ;[37] - in phase, USBIN ;[38] <- phase - rjmp bit5AfterSet ;[39] -unstuff4s: - in phase, USBIN ;[39] <- phase (one cycle too late) - andi fix, ~(1 << 4) ;[40] - nop2 ;[33] - nop2 ;[35] -bit4IsClr: - ifrset phase, USBMINUS ;[37] check phase only if D- changed - lpm ;[38] - in phase, USBIN ;[39] <- phase (one cycle too late) - ori shift, 1 << 4 ;[40] -bit5AfterClr: - ser data ;[41] - ifioset USBIN, USBMINUS ;[42] <--- sample 5 - rjmp bit5IsSet ;[43] - andi shift, ~(7 << 5) ;[44] - breq unstuff5c ;[45] - in phase, USBIN ;[46] <- phase - rjmp bit6AfterClr ;[47] -unstuff5c: - in phase, USBIN ;[47] <- phase (one cycle too late) - andi fix, ~(1 << 5) ;[48] - nop2 ;[41] - nop2 ;[43] -bit5IsSet: - ifrclr phase, USBMINUS ;[45] check phase only if D- changed - lpm ;[46] - in phase, USBIN ;[47] <- phase (one cycle too late) - ori shift, 1 << 5 ;[48] -bit6AfterSet: - subi cnt, 1 ;[49] - brcs jumpToOverflow ;[50] - ifioclr USBIN, USBMINUS ;[51] <--- sample 6 - rjmp bit6IsClr ;[52] - andi shift, ~(3 << 6) ;[53] - cpi shift, 2 ;[54] - in phase, USBIN ;[55] <- phase - brlt unstuff6s ;[56] - rjmp bit7AfterSet ;[57] - -jumpToOverflow: - rjmp overflow - -unstuff6s: - andi fix, ~(1 << 6) ;[50] - lpm ;[51] -bit6IsClr: - ifrset phase, USBMINUS ;[54] check phase only if D- changed - lpm ;[55] - in phase, USBIN ;[56] <- phase (one cycle too late) - ori shift, 1 << 6 ;[57] - nop ;[58] -bit7AfterClr: - ifioset USBIN, USBMINUS ;[59] <--- sample 7 - rjmp bit7IsSet ;[60] - andi shift, ~(1 << 7) ;[61] - cpi shift, 4 ;[62] - in phase, USBIN ;[63] <- phase - brlt unstuff7c ;[64] - rjmp bit0AfterClr ;[65] -> [00] == [67] -unstuff7c: - andi fix, ~(1 << 7) ;[58] - nop ;[59] - rjmp bit7IsSet ;[60] - -se0AndStore: - st y+, x1 ;[15/17] cycles after start of byte - rjmp se0 ;[17/19] - -bit7IsClr: - ifrset phase, USBMINUS ;[62] check phase only if D- changed - lpm ;[63] - in phase, USBIN ;[64] <- phase (one cycle too late) - ori shift, 1 << 7 ;[65] - nop ;[66] -;;;;rjmp bit0AfterClr ; -> [00] == [67] moved block up to save jump -bit0AfterClr: - eor fix, shift ;[00] -#undef fix -#define fix x2 -#undef data -#define data x1 /* we now have result in data, fix is reset to 0xff */ - ifioset USBIN, USBMINUS ;[01] <--- sample 0 - rjmp bit0IsSet ;[02] - andi shift, ~(7 << 0) ;[03] - breq unstuff0c ;[04] - in phase, USBIN ;[05] <- phase - rjmp bit1AfterClr ;[06] -unstuff0c: - in phase, USBIN ;[06] <- phase (one cycle too late) - andi fix, ~(1 << 0) ;[07] - ifioclr USBIN, USBMINUS ;[00] - ifioset USBIN, USBPLUS ;[01] - rjmp bit0IsSet ;[02] executed if first expr false or second true - rjmp se0AndStore ;[03] executed only if both bits 0 -bit0IsSet: - ifrclr phase, USBMINUS ;[04] check phase only if D- changed - lpm ;[05] - in phase, USBIN ;[06] <- phase (one cycle too late) - ori shift, 1 << 0 ;[07] -bit1AfterSet: - andi phase, USBMASK ;[08] - ifioclr USBIN, USBMINUS ;[09] <--- sample 1 - rjmp bit1IsClr ;[10] - andi shift, ~(7 << 1) ;[11] - breq unstuff1s ;[12] - in phase, USBIN ;[13] <- phase - nop ;[14] - rjmp bit2AfterSet ;[15] -unstuff1s: - in phase, USBIN ;[14] <- phase (one cycle too late) - andi fix, ~(1 << 1) ;[15] - nop2 ;[08] - nop2 ;[10] -bit1IsClr: - ifrset phase, USBMINUS ;[12] check phase only if D- changed - lpm ;[13] - in phase, USBIN ;[14] <- phase (one cycle too late) - breq se0AndStore ;[15] if we come from unstuff1s, Z bit is never set - ori shift, 1 << 1 ;[16] -bit2AfterClr: - ifioset USBIN, USBMINUS ;[17] <--- sample 2 - rjmp bit2IsSet ;[18] - andi shift, ~(7 << 2) ;[19] - breq unstuff2c ;[20] - in phase, USBIN ;[21] <- phase - rjmp bit3AfterClr ;[22] -unstuff2c: - in phase, USBIN ;[22] <- phase (one cycle too late) - andi fix, ~(1 << 2) ;[23] - nop2 ;[16] - nop2 ;[18] -bit2IsSet: - ifrclr phase, USBMINUS ;[20] check phase only if D- changed - lpm ;[21] - in phase, USBIN ;[22] <- phase (one cycle too late) - ori shift, 1 << 2 ;[23] -bit3AfterSet: - st y+, data ;[24] -entryAfterSet: - ifioclr USBIN, USBMINUS ;[26] <--- sample 3 - rjmp bit3IsClr ;[27] - andi shift, ~(7 << 3) ;[28] - breq unstuff3s ;[29] - in phase, USBIN ;[30] <- phase - rjmp bit4AfterSet ;[31] -unstuff3s: - in phase, USBIN ;[31] <- phase (one cycle too late) - andi fix, ~(1 << 3) ;[32] - nop2 ;[25] - nop2 ;[27] -bit3IsClr: - ifrset phase, USBMINUS ;[29] check phase only if D- changed - lpm ;[30] - in phase, USBIN ;[31] <- phase (one cycle too late) - ori shift, 1 << 3 ;[32] -bit4AfterClr: - mov data, fix ;[33] undo this move by swapping defines -#undef fix -#define fix x1 -#undef data -#define data x2 - ifioset USBIN, USBMINUS ;[34] <--- sample 4 - rjmp bit4IsSet ;[35] - andi shift, ~(7 << 4) ;[36] - breq unstuff4c ;[37] - in phase, USBIN ;[38] <- phase - rjmp bit5AfterClr ;[39] -unstuff4c: - in phase, USBIN ;[39] <- phase (one cycle too late) - andi fix, ~(1 << 4) ;[40] - nop2 ;[33] - nop2 ;[35] -bit4IsSet: - ifrclr phase, USBMINUS ;[37] check phase only if D- changed - lpm ;[38] - in phase, USBIN ;[39] <- phase (one cycle too late) - ori shift, 1 << 4 ;[40] -bit5AfterSet: - ser data ;[41] - ifioclr USBIN, USBMINUS ;[42] <--- sample 5 - rjmp bit5IsClr ;[43] - andi shift, ~(7 << 5) ;[44] - breq unstuff5s ;[45] - in phase, USBIN ;[46] <- phase - rjmp bit6AfterSet ;[47] -unstuff5s: - in phase, USBIN ;[47] <- phase (one cycle too late) - andi fix, ~(1 << 5) ;[48] - nop2 ;[41] - nop2 ;[43] -bit5IsClr: - ifrset phase, USBMINUS ;[45] check phase only if D- changed - lpm ;[46] - in phase, USBIN ;[47] <- phase (one cycle too late) - ori shift, 1 << 5 ;[48] -bit6AfterClr: - subi cnt, 1 ;[49] - brcs overflow ;[50] - ifioset USBIN, USBMINUS ;[51] <--- sample 6 - rjmp bit6IsSet ;[52] - andi shift, ~(3 << 6) ;[53] - cpi shift, 2 ;[54] - in phase, USBIN ;[55] <- phase - brlt unstuff6c ;[56] - rjmp bit7AfterClr ;[57] -unstuff6c: - andi fix, ~(1 << 6) ;[50] - lpm ;[51] -bit6IsSet: - ifrclr phase, USBMINUS ;[54] check phase only if D- changed - lpm ;[55] - in phase, USBIN ;[56] <- phase (one cycle too late) - ori shift, 1 << 6 ;[57] -bit7AfterSet: - ifioclr USBIN, USBMINUS ;[59] <--- sample 7 - rjmp bit7IsClr ;[60] - andi shift, ~(1 << 7) ;[61] - cpi shift, 4 ;[62] - in phase, USBIN ;[63] <- phase - brlt unstuff7s ;[64] - rjmp bit0AfterSet ;[65] -> [00] == [67] -unstuff7s: - andi fix, ~(1 << 7) ;[58] - nop ;[59] - rjmp bit7IsClr ;[60] - -macro POP_STANDARD ; 14 cycles - pop r0 - pop cnt - pop x3 - pop x2 - pop x1 - pop shift - pop YH - endm -macro POP_RETI ; 5 cycles - pop YL - out SREG, YL - pop YL - endm - -#include "asmcommon.inc" - -;---------------------------------------------------------------------------- -; Transmitting data -;---------------------------------------------------------------------------- - -txByteLoop: -txBitloop: -stuffN1Delay: ; [03] - ror shift ;[-5] [11] [63] - brcc doExorN1 ;[-4] [64] - subi x3, 1 ;[-3] - brne commonN1 ;[-2] - lsl shift ;[-1] compensate ror after rjmp stuffDelay - nop ;[00] stuffing consists of just waiting 8 cycles - rjmp stuffN1Delay ;[01] after ror, C bit is reliably clear - -sendNakAndReti: - ldi cnt, USBPID_NAK ;[-19] - rjmp sendCntAndReti ;[-18] -sendAckAndReti: - ldi cnt, USBPID_ACK ;[-17] -sendCntAndReti: - mov r0, cnt ;[-16] - ldi YL, 0 ;[-15] R0 address is 0 - ldi YH, 0 ;[-14] - ldi cnt, 2 ;[-13] -; rjmp usbSendAndReti fallthrough - -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) or USBOUT = 0x01 -; K = (D+ = 1), (D- = 0) or USBOUT = 0x02 -; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles) - -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte -;uses: x1...x3, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x3 = bitstuff cnt] -;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction) -usbSendAndReti: - in x2, USBDDR ;[-10] 10 cycles until SOP - ori x2, USBMASK ;[-9] - sbi USBOUT, USBMINUS ;[-8] prepare idle state; D+ and D- must have been 0 (no pullups) - out USBDDR, x2 ;[-6] <--- acquire bus - in x1, USBOUT ;[-5] port mirror for tx loop - ldi shift, 0x40 ;[-4] sync byte is first byte sent (we enter loop after ror) - ldi x2, USBMASK ;[-3] -doExorN1: - eor x1, x2 ;[-2] [06] [62] - ldi x3, 6 ;[-1] [07] [63] -commonN1: -stuffN2Delay: - out USBOUT, x1 ;[00] [08] [64] <--- set bit - ror shift ;[01] - brcc doExorN2 ;[02] - subi x3, 1 ;[03] - brne commonN2 ;[04] - lsl shift ;[05] compensate ror after rjmp stuffDelay - rjmp stuffN2Delay ;[06] after ror, C bit is reliably clear -doExorN2: - eor x1, x2 ;[04] [12] - ldi x3, 6 ;[05] [13] -commonN2: - nop2 ;[06] [14] - subi cnt, 171 ;[08] [16] trick: (3 * 171) & 0xff = 1 - out USBOUT, x1 ;[09] [17] <--- set bit - brcs txBitloop ;[10] [27] [44] - -stuff6Delay: - ror shift ;[45] [53] - brcc doExor6 ;[46] - subi x3, 1 ;[47] - brne common6 ;[48] - lsl shift ;[49] compensate ror after rjmp stuffDelay - nop ;[50] stuffing consists of just waiting 8 cycles - rjmp stuff6Delay ;[51] after ror, C bit is reliably clear -doExor6: - eor x1, x2 ;[48] [56] - ldi x3, 6 ;[49] -common6: -stuff7Delay: - ror shift ;[50] [58] - out USBOUT, x1 ;[51] <--- set bit - brcc doExor7 ;[52] - subi x3, 1 ;[53] - brne common7 ;[54] - lsl shift ;[55] compensate ror after rjmp stuffDelay - rjmp stuff7Delay ;[56] after ror, C bit is reliably clear -doExor7: - eor x1, x2 ;[54] [62] - ldi x3, 6 ;[55] -common7: - ld shift, y+ ;[56] - nop ;[58] - tst cnt ;[59] - out USBOUT, x1 ;[60] [00]<--- set bit - brne txByteLoop ;[61] [01] -;make SE0: - cbr x1, USBMASK ;[02] prepare SE0 [spec says EOP may be 15 to 18 cycles] - lds x2, usbNewDeviceAddr;[03] - lsl x2 ;[05] we compare with left shifted address - subi YL, 2 + 0 ;[06] Only assign address on data packets, not ACK/NAK in r0 - sbci YH, 0 ;[07] - out USBOUT, x1 ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - breq skipAddrAssign ;[01] - sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer -skipAddrAssign: -;end of usbDeviceAddress transfer - ldi x2, 1< 0) - echo "$s\n"; - } -} - -function printBit($isAfterSet, $bitNum) -{ - ob_start(); - if($isAfterSet){ -?> - ifioclr USBIN, USBMINUS ;[00] <--- sample - rjmp bit#IsClr ;[01] - andi shift, ~(7 << #) ;[02] - breq unstuff#s ;[03] - in phase, USBIN ;[04] <- phase - rjmp bit@AfterSet ;[05] -unstuff#s: - in phase, USBIN ;[05] <- phase (one cycle too late) - andi fix, ~(1 << #) ;[06] - nop2 ;[-1] - nop2 ;[01] -bit#IsClr: - ifrset phase, USBMINUS ;[03] check phase only if D- changed - lpm ;[04] - in phase, USBIN ;[05] <- phase (one cycle too late) - ori shift, 1 << # ;[06] - - ifioset USBIN, USBMINUS ;[00] <--- sample - rjmp bit#IsSet ;[01] - andi shift, ~(7 << #) ;[02] - breq unstuff#c ;[03] - in phase, USBIN ;[04] <- phase - rjmp bit@AfterClr ;[05] -unstuff#c: - in phase, USBIN ;[05] <- phase (one cycle too late) - andi fix, ~(1 << #) ;[06] - nop2 ;[-1] - nop2 ;[01] -bit#IsSet: - ifrclr phase, USBMINUS ;[03] check phase only if D- changed - lpm ;[04] - in phase, USBIN ;[05] <- phase (one cycle too late) - ori shift, 1 << # ;[06] - -*****************************************************************************/ diff --git a/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm15.inc b/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm15.inc deleted file mode 100644 index 1016124..0000000 --- a/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm15.inc +++ /dev/null @@ -1,423 +0,0 @@ -/* Name: usbdrvasm15.inc - * Project: AVR USB driver - * Author: contributed by V. Bosch - * Creation Date: 2007-08-06 - * Tabsize: 4 - * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * Revision: $Id: usbdrvasm15.inc 692 2008-11-07 15:07:40Z cs $ - */ - -/* Do not link this file! Link usbdrvasm.S instead, which includes the - * appropriate implementation! - */ - -/* -General Description: -This file is the 15 MHz version of the asssembler part of the USB driver. It -requires a 15 MHz crystal (not a ceramic resonator and not a calibrated RC -oscillator). - -See usbdrv.h for a description of the entire driver. - -Since almost all of this code is timing critical, don't change unless you -really know what you are doing! Many parts require not only a maximum number -of CPU cycles, but even an exact number of cycles! -*/ - -;max stack usage: [ret(2), YL, SREG, YH, bitcnt, shift, x1, x2, x3, x4, cnt] = 12 bytes -;nominal frequency: 15 MHz -> 10.0 cycles per bit, 80.0 cycles per byte -; Numbers in brackets are clocks counted from center of last sync bit -; when instruction starts - -;---------------------------------------------------------------------------- -; order of registers pushed: -; YL, SREG [sofError] YH, shift, x1, x2, x3, bitcnt, cnt, x4 -;---------------------------------------------------------------------------- -USB_INTR_VECTOR: - push YL ;2 push only what is necessary to sync with edge ASAP - in YL, SREG ;1 - push YL ;2 -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -; -; sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -; sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -;------------------------------------------------------------------------------- -; The following code results in a sampling window of < 1/4 bit -; which meets the spec. -;------------------------------------------------------------------------------- -waitForK: ;- - sbis USBIN, USBMINUS ;1 [00] <-- sample - rjmp foundK ;2 [01] - sbis USBIN, USBMINUS ; <-- sample - rjmp foundK - sbis USBIN, USBMINUS ; <-- sample - rjmp foundK - sbis USBIN, USBMINUS ; <-- sample - rjmp foundK - sbis USBIN, USBMINUS ; <-- sample - rjmp foundK - sbis USBIN, USBMINUS ; <-- sample - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -;------------------------------------------------------------------------------ -; {3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for -; center sampling] -; we have 1 bit time for setup purposes, then sample again. -; Numbers in brackets are cycles from center of first sync (double K) -; bit after the instruction -;------------------------------------------------------------------------------ -foundK: ;- [02] - lds YL, usbInputBufOffset;2 [03+04] tx loop - push YH ;2 [05+06] - clr YH ;1 [07] - subi YL, lo8(-(usbRxBuf)) ;1 [08] [rx loop init] - sbci YH, hi8(-(usbRxBuf)) ;1 [09] [rx loop init] - push shift ;2 [10+11] - ser shift ;1 [12] - sbis USBIN, USBMINUS ;1 [-1] [13] <--sample:we want two bits K (sample 1 cycle too early) - rjmp haveTwoBitsK ;2 [00] [14] - pop shift ;2 [15+16] undo the push from before - pop YH ;2 [17+18] undo the push from before - rjmp waitForK ;2 [19+20] this was not the end of sync, retry -; The entire loop from waitForK until rjmp waitForK above must not exceed two -; bit times (= 20 cycles). - -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -haveTwoBitsK: ;- [01] - push x1 ;2 [02+03] - push x2 ;2 [04+05] - push x3 ;2 [06+07] - push bitcnt ;2 [08+09] - in x1, USBIN ;1 [00] [10] <-- sample bit 0 - bst x1, USBMINUS ;1 [01] - bld shift, 0 ;1 [02] - push cnt ;2 [03+04] - ldi cnt, USB_BUFSIZE ;1 [05] - push x4 ;2 [06+07] tx loop - rjmp rxLoop ;2 [08] -;---------------------------------------------------------------------------- -; Receiver loop (numbers in brackets are cycles within byte after instr) -;---------------------------------------------------------------------------- -unstuff0: ;- [07] (branch taken) - andi x3, ~0x01 ;1 [08] - mov x1, x2 ;1 [09] x2 contains last sampled (stuffed) bit - in x2, USBIN ;1 [00] [10] <-- sample bit 1 again - andi x2, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 1 - ori shift, 0x01 ;1 [03] 0b00000001 - nop ;1 [04] - rjmp didUnstuff0 ;2 [05] -;----------------------------------------------------- -unstuff1: ;- [05] (branch taken) - mov x2, x1 ;1 [06] x1 contains last sampled (stuffed) bit - andi x3, ~0x02 ;1 [07] - ori shift, 0x02 ;1 [08] 0b00000010 - nop ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample bit 2 again - andi x1, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 2 - rjmp didUnstuff1 ;2 [03] -;----------------------------------------------------- -unstuff2: ;- [05] (branch taken) - andi x3, ~0x04 ;1 [06] - ori shift, 0x04 ;1 [07] 0b00000100 - mov x1, x2 ;1 [08] x2 contains last sampled (stuffed) bit - nop ;1 [09] - in x2, USBIN ;1 [00] [10] <-- sample bit 3 - andi x2, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 3 - rjmp didUnstuff2 ;2 [03] -;----------------------------------------------------- -unstuff3: ;- [00] [10] (branch taken) - in x2, USBIN ;1 [01] [11] <-- sample stuffed bit 3 one cycle too late - andi x2, USBMASK ;1 [02] - breq se0Hop ;1 [03] SE0 check for stuffed bit 3 - andi x3, ~0x08 ;1 [04] - ori shift, 0x08 ;1 [05] 0b00001000 - rjmp didUnstuff3 ;2 [06] -;---------------------------------------------------------------------------- -; extra jobs done during bit interval: -; -; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs], -; overflow check, jump to the head of rxLoop -; bit 1: SE0 check -; bit 2: SE0 check, recovery from delay [bit 0 tasks took too long] -; bit 3: SE0 check, recovery from delay [bit 0 tasks took too long] -; bit 4: SE0 check, none -; bit 5: SE0 check, none -; bit 6: SE0 check, none -; bit 7: SE0 check, reconstruct: x3 is 0 at bit locations we changed, 1 at others -;---------------------------------------------------------------------------- -rxLoop: ;- [09] - in x2, USBIN ;1 [00] [10] <-- sample bit 1 (or possibly bit 0 stuffed) - andi x2, USBMASK ;1 [01] - brne SkipSe0Hop ;1 [02] -se0Hop: ;- [02] - rjmp se0 ;2 [03] SE0 check for bit 1 -SkipSe0Hop: ;- [03] - ser x3 ;1 [04] - andi shift, 0xf9 ;1 [05] 0b11111001 - breq unstuff0 ;1 [06] -didUnstuff0: ;- [06] - eor x1, x2 ;1 [07] - bst x1, USBMINUS ;1 [08] - bld shift, 1 ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample bit 2 (or possibly bit 1 stuffed) - andi x1, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 2 - andi shift, 0xf3 ;1 [03] 0b11110011 - breq unstuff1 ;1 [04] do remaining work for bit 1 -didUnstuff1: ;- [04] - eor x2, x1 ;1 [05] - bst x2, USBMINUS ;1 [06] - bld shift, 2 ;1 [07] - nop2 ;2 [08+09] - in x2, USBIN ;1 [00] [10] <-- sample bit 3 (or possibly bit 2 stuffed) - andi x2, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 3 - andi shift, 0xe7 ;1 [03] 0b11100111 - breq unstuff2 ;1 [04] -didUnstuff2: ;- [04] - eor x1, x2 ;1 [05] - bst x1, USBMINUS ;1 [06] - bld shift, 3 ;1 [07] -didUnstuff3: ;- [07] - andi shift, 0xcf ;1 [08] 0b11001111 - breq unstuff3 ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample bit 4 - andi x1, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 4 - eor x2, x1 ;1 [03] - bst x2, USBMINUS ;1 [04] - bld shift, 4 ;1 [05] -didUnstuff4: ;- [05] - andi shift, 0x9f ;1 [06] 0b10011111 - breq unstuff4 ;1 [07] - nop2 ;2 [08+09] - in x2, USBIN ;1 [00] [10] <-- sample bit 5 - andi x2, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for bit 5 - eor x1, x2 ;1 [03] - bst x1, USBMINUS ;1 [04] - bld shift, 5 ;1 [05] -didUnstuff5: ;- [05] - andi shift, 0x3f ;1 [06] 0b00111111 - breq unstuff5 ;1 [07] - nop2 ;2 [08+09] - in x1, USBIN ;1 [00] [10] <-- sample bit 6 - andi x1, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for bit 6 - eor x2, x1 ;1 [03] - bst x2, USBMINUS ;1 [04] - bld shift, 6 ;1 [05] -didUnstuff6: ;- [05] - cpi shift, 0x02 ;1 [06] 0b00000010 - brlo unstuff6 ;1 [07] - nop2 ;2 [08+09] - in x2, USBIN ;1 [00] [10] <-- sample bit 7 - andi x2, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for bit 7 - eor x1, x2 ;1 [03] - bst x1, USBMINUS ;1 [04] - bld shift, 7 ;1 [05] -didUnstuff7: ;- [05] - cpi shift, 0x04 ;1 [06] 0b00000100 - brlo unstuff7 ;1 [07] - eor x3, shift ;1 [08] reconstruct: x3 is 0 at bit locations we changed, 1 at others - nop ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample bit 0 - st y+, x3 ;2 [01+02] store data - eor x2, x1 ;1 [03] - bst x2, USBMINUS ;1 [04] - bld shift, 0 ;1 [05] - subi cnt, 1 ;1 [06] - brcs overflow ;1 [07] - rjmp rxLoop ;2 [08] -;----------------------------------------------------- -unstuff4: ;- [08] - andi x3, ~0x10 ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 4 - andi x1, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for stuffed bit 4 - ori shift, 0x10 ;1 [03] - rjmp didUnstuff4 ;2 [04] -;----------------------------------------------------- -unstuff5: ;- [08] - ori shift, 0x20 ;1 [09] - in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 5 - andi x2, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for stuffed bit 5 - andi x3, ~0x20 ;1 [03] - rjmp didUnstuff5 ;2 [04] -;----------------------------------------------------- -unstuff6: ;- [08] - andi x3, ~0x40 ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 6 - andi x1, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for stuffed bit 6 - ori shift, 0x40 ;1 [03] - rjmp didUnstuff6 ;2 [04] -;----------------------------------------------------- -unstuff7: ;- [08] - andi x3, ~0x80 ;1 [09] - in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 7 - andi x2, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for stuffed bit 7 - ori shift, 0x80 ;1 [03] - rjmp didUnstuff7 ;2 [04] - -macro POP_STANDARD ; 16 cycles - pop x4 - pop cnt - pop bitcnt - pop x3 - pop x2 - pop x1 - pop shift - pop YH - endm -macro POP_RETI ; 5 cycles - pop YL - out SREG, YL - pop YL - endm - -#include "asmcommon.inc" - -;--------------------------------------------------------------------------- -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) -; K = (D+ = 1), (D- = 0) -; Spec allows 7.5 bit times from EOP to SOP for replies -;--------------------------------------------------------------------------- -bitstuffN: ;- [04] - eor x1, x4 ;1 [05] - clr x2 ;1 [06] - nop ;1 [07] - rjmp didStuffN ;1 [08] -;--------------------------------------------------------------------------- -bitstuff6: ;- [04] - eor x1, x4 ;1 [05] - clr x2 ;1 [06] - rjmp didStuff6 ;1 [07] -;--------------------------------------------------------------------------- -bitstuff7: ;- [02] - eor x1, x4 ;1 [03] - clr x2 ;1 [06] - nop ;1 [05] - rjmp didStuff7 ;1 [06] -;--------------------------------------------------------------------------- -sendNakAndReti: ;- [-19] - ldi x3, USBPID_NAK ;1 [-18] - rjmp sendX3AndReti ;1 [-17] -;--------------------------------------------------------------------------- -sendAckAndReti: ;- [-17] - ldi cnt, USBPID_ACK ;1 [-16] -sendCntAndReti: ;- [-16] - mov x3, cnt ;1 [-15] -sendX3AndReti: ;- [-15] - ldi YL, 20 ;1 [-14] x3==r20 address is 20 - ldi YH, 0 ;1 [-13] - ldi cnt, 2 ;1 [-12] -; rjmp usbSendAndReti fallthrough -;--------------------------------------------------------------------------- -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] -;uses: x1...x4, btcnt, shift, cnt, Y -;Numbers in brackets are time since first bit of sync pattern is sent -;We need not to match the transfer rate exactly because the spec demands -;only 1.5% precision anyway. -usbSendAndReti: ;- [-13] 13 cycles until SOP - in x2, USBDDR ;1 [-12] - ori x2, USBMASK ;1 [-11] - sbi USBOUT, USBMINUS ;2 [-09-10] prepare idle state; D+ and D- must have been 0 (no pullups) - in x1, USBOUT ;1 [-08] port mirror for tx loop - out USBDDR, x2 ;1 [-07] <- acquire bus - ; need not init x2 (bitstuff history) because sync starts with 0 - ldi x4, USBMASK ;1 [-06] exor mask - ldi shift, 0x80 ;1 [-05] sync byte is first byte sent - ldi bitcnt, 6 ;1 [-04] -txBitLoop: ;- [-04] [06] - sbrs shift, 0 ;1 [-03] [07] - eor x1, x4 ;1 [-02] [08] - ror shift ;1 [-01] [09] -didStuffN: ;- [09] - out USBOUT, x1 ;1 [00] [10] <-- out N - ror x2 ;1 [01] - cpi x2, 0xfc ;1 [02] - brcc bitstuffN ;1 [03] - dec bitcnt ;1 [04] - brne txBitLoop ;1 [05] - sbrs shift, 0 ;1 [06] - eor x1, x4 ;1 [07] - ror shift ;1 [08] -didStuff6: ;- [08] - nop ;1 [09] - out USBOUT, x1 ;1 [00] [10] <-- out 6 - ror x2 ;1 [01] - cpi x2, 0xfc ;1 [02] - brcc bitstuff6 ;1 [03] - sbrs shift, 0 ;1 [04] - eor x1, x4 ;1 [05] - ror shift ;1 [06] - ror x2 ;1 [07] -didStuff7: ;- [07] - ldi bitcnt, 6 ;1 [08] - cpi x2, 0xfc ;1 [09] - out USBOUT, x1 ;1 [00] [10] <-- out 7 - brcc bitstuff7 ;1 [01] - ld shift, y+ ;2 [02+03] - dec cnt ;1 [04] - brne txBitLoop ;1 [05] -makeSE0: - cbr x1, USBMASK ;1 [06] prepare SE0 [spec says EOP may be 19 to 23 cycles] - lds x2, usbNewDeviceAddr;2 [07+08] - lsl x2 ;1 [09] we compare with left shifted address -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - out USBOUT, x1 ;1 [00] [10] <-- out SE0-- from now 2 bits==20 cycl. until bus idle - subi YL, 20 + 2 ;1 [01] Only assign address on data packets, not ACK/NAK in x3 - sbci YH, 0 ;1 [02] - breq skipAddrAssign ;1 [03] - sts usbDeviceAddr, x2 ;2 [04+05] if not skipped: SE0 is one cycle longer -;---------------------------------------------------------------------------- -;end of usbDeviceAddress transfer -skipAddrAssign: ;- [03/04] - ldi x2, 1< 10.6666666 cycles per bit, 85.333333333 cycles per byte -; Numbers in brackets are clocks counted from center of last sync bit -; when instruction starts - -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt - push YL ;[-25] push only what is necessary to sync with edge ASAP - in YL, SREG ;[-23] - push YL ;[-22] - push YH ;[-20] -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of < 1/4 bit which meets the spec. - sbis USBIN, USBMINUS ;[-15] - rjmp foundK ;[-14] - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -foundK: ;[-12] -;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling] -;we have 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push bitcnt ;[-12] -; [---] ;[-11] - lds YL, usbInputBufOffset;[-10] -; [---] ;[-9] - clr YH ;[-8] - subi YL, lo8(-(usbRxBuf));[-7] [rx loop init] - sbci YH, hi8(-(usbRxBuf));[-6] [rx loop init] - push shift ;[-5] -; [---] ;[-4] - ldi bitcnt, 0x55 ;[-3] [rx loop init] - sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early) - rjmp haveTwoBitsK ;[-1] - pop shift ;[0] undo the push from before - pop bitcnt ;[2] undo the push from before - rjmp waitForK ;[4] this was not the end of sync, retry -; The entire loop from waitForK until rjmp waitForK above must not exceed two -; bit times (= 21 cycles). - -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -haveTwoBitsK: - push x1 ;[1] - push x2 ;[3] - push x3 ;[5] - ldi shift, 0 ;[7] - ldi x3, 1<<4 ;[8] [rx loop init] first sample is inverse bit, compensate that - push x4 ;[9] == leap - - in x1, USBIN ;[11] <-- sample bit 0 - andi x1, USBMASK ;[12] - bst x1, USBMINUS ;[13] - bld shift, 7 ;[14] - push cnt ;[15] - ldi leap, 0 ;[17] [rx loop init] - ldi cnt, USB_BUFSIZE;[18] [rx loop init] - rjmp rxbit1 ;[19] arrives at [21] - -;---------------------------------------------------------------------------- -; Receiver loop (numbers in brackets are cycles within byte after instr) -;---------------------------------------------------------------------------- - -unstuff6: - andi x2, USBMASK ;[03] - ori x3, 1<<6 ;[04] will not be shifted any more - andi shift, ~0x80;[05] - mov x1, x2 ;[06] sampled bit 7 is actually re-sampled bit 6 - subi leap, 3 ;[07] since this is a short (10 cycle) bit, enforce leap bit - rjmp didUnstuff6 ;[08] - -unstuff7: - ori x3, 1<<7 ;[09] will not be shifted any more - in x2, USBIN ;[00] [10] re-sample bit 7 - andi x2, USBMASK ;[01] - andi shift, ~0x80;[02] - subi leap, 3 ;[03] since this is a short (10 cycle) bit, enforce leap bit - rjmp didUnstuff7 ;[04] - -unstuffEven: - ori x3, 1<<6 ;[09] will be shifted right 6 times for bit 0 - in x1, USBIN ;[00] [10] - andi shift, ~0x80;[01] - andi x1, USBMASK ;[02] - breq se0 ;[03] - subi leap, 3 ;[04] since this is a short (10 cycle) bit, enforce leap bit - nop ;[05] - rjmp didUnstuffE ;[06] - -unstuffOdd: - ori x3, 1<<5 ;[09] will be shifted right 4 times for bit 1 - in x2, USBIN ;[00] [10] - andi shift, ~0x80;[01] - andi x2, USBMASK ;[02] - breq se0 ;[03] - subi leap, 3 ;[04] since this is a short (10 cycle) bit, enforce leap bit - nop ;[05] - rjmp didUnstuffO ;[06] - -rxByteLoop: - andi x1, USBMASK ;[03] - eor x2, x1 ;[04] - subi leap, 1 ;[05] - brpl skipLeap ;[06] - subi leap, -3 ;1 one leap cycle every 3rd byte -> 85 + 1/3 cycles per byte - nop ;1 -skipLeap: - subi x2, 1 ;[08] - ror shift ;[09] -didUnstuff6: - cpi shift, 0xfc ;[10] - in x2, USBIN ;[00] [11] <-- sample bit 7 - brcc unstuff6 ;[01] - andi x2, USBMASK ;[02] - eor x1, x2 ;[03] - subi x1, 1 ;[04] - ror shift ;[05] -didUnstuff7: - cpi shift, 0xfc ;[06] - brcc unstuff7 ;[07] - eor x3, shift ;[08] reconstruct: x3 is 1 at bit locations we changed, 0 at others - st y+, x3 ;[09] store data -rxBitLoop: - in x1, USBIN ;[00] [11] <-- sample bit 0/2/4 - andi x1, USBMASK ;[01] - eor x2, x1 ;[02] - andi x3, 0x3f ;[03] topmost two bits reserved for 6 and 7 - subi x2, 1 ;[04] - ror shift ;[05] - cpi shift, 0xfc ;[06] - brcc unstuffEven ;[07] -didUnstuffE: - lsr x3 ;[08] - lsr x3 ;[09] -rxbit1: - in x2, USBIN ;[00] [10] <-- sample bit 1/3/5 - andi x2, USBMASK ;[01] - breq se0 ;[02] - eor x1, x2 ;[03] - subi x1, 1 ;[04] - ror shift ;[05] - cpi shift, 0xfc ;[06] - brcc unstuffOdd ;[07] -didUnstuffO: - subi bitcnt, 0xab;[08] == addi 0x55, 0x55 = 0x100/3 - brcs rxBitLoop ;[09] - - subi cnt, 1 ;[10] - in x1, USBIN ;[00] [11] <-- sample bit 6 - brcc rxByteLoop ;[01] - rjmp overflow - -macro POP_STANDARD ; 14 cycles - pop cnt - pop x4 - pop x3 - pop x2 - pop x1 - pop shift - pop bitcnt - endm -macro POP_RETI ; 7 cycles - pop YH - pop YL - out SREG, YL - pop YL - endm - -#include "asmcommon.inc" - -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) -; K = (D+ = 1), (D- = 0) -; Spec allows 7.5 bit times from EOP to SOP for replies - -bitstuffN: - eor x1, x4 ;[5] - ldi x2, 0 ;[6] - nop2 ;[7] - nop ;[9] - out USBOUT, x1 ;[10] <-- out - rjmp didStuffN ;[0] - -bitstuff6: - eor x1, x4 ;[5] - ldi x2, 0 ;[6] Carry is zero due to brcc - rol shift ;[7] compensate for ror shift at branch destination - rjmp didStuff6 ;[8] - -bitstuff7: - ldi x2, 0 ;[2] Carry is zero due to brcc - rjmp didStuff7 ;[3] - - -sendNakAndReti: - ldi x3, USBPID_NAK ;[-18] - rjmp sendX3AndReti ;[-17] -sendAckAndReti: - ldi cnt, USBPID_ACK ;[-17] -sendCntAndReti: - mov x3, cnt ;[-16] -sendX3AndReti: - ldi YL, 20 ;[-15] x3==r20 address is 20 - ldi YH, 0 ;[-14] - ldi cnt, 2 ;[-13] -; rjmp usbSendAndReti fallthrough - -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] -;uses: x1...x4, btcnt, shift, cnt, Y -;Numbers in brackets are time since first bit of sync pattern is sent -;We don't match the transfer rate exactly (don't insert leap cycles every third -;byte) because the spec demands only 1.5% precision anyway. -usbSendAndReti: ; 12 cycles until SOP - in x2, USBDDR ;[-12] - ori x2, USBMASK ;[-11] - sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) - in x1, USBOUT ;[-8] port mirror for tx loop - out USBDDR, x2 ;[-7] <- acquire bus -; need not init x2 (bitstuff history) because sync starts with 0 - ldi x4, USBMASK ;[-6] exor mask - ldi shift, 0x80 ;[-5] sync byte is first byte sent -txByteLoop: - ldi bitcnt, 0x35 ;[-4] [6] binary 0011 0101 -txBitLoop: - sbrs shift, 0 ;[-3] [7] - eor x1, x4 ;[-2] [8] - out USBOUT, x1 ;[-1] [9] <-- out N - ror shift ;[0] [10] - ror x2 ;[1] -didStuffN: - cpi x2, 0xfc ;[2] - brcc bitstuffN ;[3] - lsr bitcnt ;[4] - brcc txBitLoop ;[5] - brne txBitLoop ;[6] - - sbrs shift, 0 ;[7] - eor x1, x4 ;[8] -didStuff6: - out USBOUT, x1 ;[-1] [9] <-- out 6 - ror shift ;[0] [10] - ror x2 ;[1] - cpi x2, 0xfc ;[2] - brcc bitstuff6 ;[3] - ror shift ;[4] -didStuff7: - ror x2 ;[5] - sbrs x2, 7 ;[6] - eor x1, x4 ;[7] - nop ;[8] - cpi x2, 0xfc ;[9] - out USBOUT, x1 ;[-1][10] <-- out 7 - brcc bitstuff7 ;[0] [11] - ld shift, y+ ;[1] - dec cnt ;[3] - brne txByteLoop ;[4] -;make SE0: - cbr x1, USBMASK ;[5] prepare SE0 [spec says EOP may be 21 to 25 cycles] - lds x2, usbNewDeviceAddr;[6] - lsl x2 ;[8] we compare with left shifted address - subi YL, 20 + 2 ;[9] Only assign address on data packets, not ACK/NAK in x3 - sbci YH, 0 ;[10] - out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - breq skipAddrAssign ;[0] - sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer -skipAddrAssign: -;end of usbDeviceAddress transfer - ldi x2, 1< max 52 cycles interrupt disable -;max stack usage: [ret(2), r0, SREG, YL, YH, shift, x1, x2, x3, x4, cnt] = 12 bytes -;nominal frequency: 16.5 MHz -> 11 cycles per bit -; 16.3125 MHz < F_CPU < 16.6875 MHz (+/- 1.1%) -; Numbers in brackets are clocks counted from center of last sync bit -; when instruction starts - - -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG [sofError], r0, YH, shift, x1, x2, x3, x4, cnt - push YL ;[-23] push only what is necessary to sync with edge ASAP - in YL, SREG ;[-21] - push YL ;[-20] -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of < 1/4 bit which meets the spec. - sbis USBIN, USBMINUS ;[-15] - rjmp foundK ;[-14] - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -foundK: ;[-12] -;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling] -;we have 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push r0 ;[-12] -; [---] ;[-11] - push YH ;[-10] -; [---] ;[-9] - lds YL, usbInputBufOffset;[-8] -; [---] ;[-7] - clr YH ;[-6] - subi YL, lo8(-(usbRxBuf));[-5] [rx loop init] - sbci YH, hi8(-(usbRxBuf));[-4] [rx loop init] - mov r0, x2 ;[-3] [rx loop init] - sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early) - rjmp haveTwoBitsK ;[-1] - pop YH ;[0] undo the pushes from before - pop r0 ;[2] - rjmp waitForK ;[4] this was not the end of sync, retry -; The entire loop from waitForK until rjmp waitForK above must not exceed two -; bit times (= 22 cycles). - -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -haveTwoBitsK: ;[1] - push shift ;[1] - push x1 ;[3] - push x2 ;[5] - push x3 ;[7] - ldi shift, 0xff ;[9] [rx loop init] - ori x3, 0xff ;[10] [rx loop init] == ser x3, clear zero flag - - in x1, USBIN ;[11] <-- sample bit 0 - bst x1, USBMINUS ;[12] - bld shift, 0 ;[13] - push x4 ;[14] == phase -; [---] ;[15] - push cnt ;[16] -; [---] ;[17] - ldi phase, 0 ;[18] [rx loop init] - ldi cnt, USB_BUFSIZE;[19] [rx loop init] - rjmp rxbit1 ;[20] -; [---] ;[21] - -;---------------------------------------------------------------------------- -; Receiver loop (numbers in brackets are cycles within byte after instr) -;---------------------------------------------------------------------------- -/* -byte oriented operations done during loop: -bit 0: store data -bit 1: SE0 check -bit 2: overflow check -bit 3: catch up -bit 4: rjmp to achieve conditional jump range -bit 5: PLL -bit 6: catch up -bit 7: jump, fixup bitstuff -; 87 [+ 2] cycles ------------------------------------------------------------------- -*/ -continueWithBit5: - in x2, USBIN ;[055] <-- bit 5 - eor r0, x2 ;[056] - or phase, r0 ;[057] - sbrc phase, USBMINUS ;[058] - lpm ;[059] optional nop3; modifies r0 - in phase, USBIN ;[060] <-- phase - eor x1, x2 ;[061] - bst x1, USBMINUS ;[062] - bld shift, 5 ;[063] - andi shift, 0x3f ;[064] - in x1, USBIN ;[065] <-- bit 6 - breq unstuff5 ;[066] *** unstuff escape - eor phase, x1 ;[067] - eor x2, x1 ;[068] - bst x2, USBMINUS ;[069] - bld shift, 6 ;[070] -didUnstuff6: ;[ ] - in r0, USBIN ;[071] <-- phase - cpi shift, 0x02 ;[072] - brlo unstuff6 ;[073] *** unstuff escape -didUnstuff5: ;[ ] - nop2 ;[074] -; [---] ;[075] - in x2, USBIN ;[076] <-- bit 7 - eor x1, x2 ;[077] - bst x1, USBMINUS ;[078] - bld shift, 7 ;[079] -didUnstuff7: ;[ ] - eor r0, x2 ;[080] - or phase, r0 ;[081] - in r0, USBIN ;[082] <-- phase - cpi shift, 0x04 ;[083] - brsh rxLoop ;[084] -; [---] ;[085] -unstuff7: ;[ ] - andi x3, ~0x80 ;[085] - ori shift, 0x80 ;[086] - in x2, USBIN ;[087] <-- sample stuffed bit 7 - nop ;[088] - rjmp didUnstuff7 ;[089] -; [---] ;[090] - ;[080] - -unstuff5: ;[067] - eor phase, x1 ;[068] - andi x3, ~0x20 ;[069] - ori shift, 0x20 ;[070] - in r0, USBIN ;[071] <-- phase - mov x2, x1 ;[072] - nop ;[073] - nop2 ;[074] -; [---] ;[075] - in x1, USBIN ;[076] <-- bit 6 - eor r0, x1 ;[077] - or phase, r0 ;[078] - eor x2, x1 ;[079] - bst x2, USBMINUS ;[080] - bld shift, 6 ;[081] no need to check bitstuffing, we just had one - in r0, USBIN ;[082] <-- phase - rjmp didUnstuff5 ;[083] -; [---] ;[084] - ;[074] - -unstuff6: ;[074] - andi x3, ~0x40 ;[075] - in x1, USBIN ;[076] <-- bit 6 again - ori shift, 0x40 ;[077] - nop2 ;[078] -; [---] ;[079] - rjmp didUnstuff6 ;[080] -; [---] ;[081] - ;[071] - -unstuff0: ;[013] - eor r0, x2 ;[014] - or phase, r0 ;[015] - andi x2, USBMASK ;[016] check for SE0 - in r0, USBIN ;[017] <-- phase - breq didUnstuff0 ;[018] direct jump to se0 would be too long - andi x3, ~0x01 ;[019] - ori shift, 0x01 ;[020] - mov x1, x2 ;[021] mov existing sample - in x2, USBIN ;[022] <-- bit 1 again - rjmp didUnstuff0 ;[023] -; [---] ;[024] - ;[014] - -unstuff1: ;[024] - eor r0, x1 ;[025] - or phase, r0 ;[026] - andi x3, ~0x02 ;[027] - in r0, USBIN ;[028] <-- phase - ori shift, 0x02 ;[029] - mov x2, x1 ;[030] - rjmp didUnstuff1 ;[031] -; [---] ;[032] - ;[022] - -unstuff2: ;[035] - eor r0, x2 ;[036] - or phase, r0 ;[037] - andi x3, ~0x04 ;[038] - in r0, USBIN ;[039] <-- phase - ori shift, 0x04 ;[040] - mov x1, x2 ;[041] - rjmp didUnstuff2 ;[042] -; [---] ;[043] - ;[033] - -unstuff3: ;[043] - in x2, USBIN ;[044] <-- bit 3 again - eor r0, x2 ;[045] - or phase, r0 ;[046] - andi x3, ~0x08 ;[047] - ori shift, 0x08 ;[048] - nop ;[049] - in r0, USBIN ;[050] <-- phase - rjmp didUnstuff3 ;[051] -; [---] ;[052] - ;[042] - -unstuff4: ;[053] - andi x3, ~0x10 ;[054] - in x1, USBIN ;[055] <-- bit 4 again - ori shift, 0x10 ;[056] - rjmp didUnstuff4 ;[057] -; [---] ;[058] - ;[048] - -rxLoop: ;[085] - eor x3, shift ;[086] reconstruct: x3 is 0 at bit locations we changed, 1 at others - in x1, USBIN ;[000] <-- bit 0 - st y+, x3 ;[001] -; [---] ;[002] - eor r0, x1 ;[003] - or phase, r0 ;[004] - eor x2, x1 ;[005] - in r0, USBIN ;[006] <-- phase - ser x3 ;[007] - bst x2, USBMINUS ;[008] - bld shift, 0 ;[009] - andi shift, 0xf9 ;[010] -rxbit1: ;[ ] - in x2, USBIN ;[011] <-- bit 1 - breq unstuff0 ;[012] *** unstuff escape - andi x2, USBMASK ;[013] SE0 check for bit 1 -didUnstuff0: ;[ ] Z only set if we detected SE0 in bitstuff - breq se0 ;[014] - eor r0, x2 ;[015] - or phase, r0 ;[016] - in r0, USBIN ;[017] <-- phase - eor x1, x2 ;[018] - bst x1, USBMINUS ;[019] - bld shift, 1 ;[020] - andi shift, 0xf3 ;[021] -didUnstuff1: ;[ ] - in x1, USBIN ;[022] <-- bit 2 - breq unstuff1 ;[023] *** unstuff escape - eor r0, x1 ;[024] - or phase, r0 ;[025] - subi cnt, 1 ;[026] overflow check - brcs overflow ;[027] - in r0, USBIN ;[028] <-- phase - eor x2, x1 ;[029] - bst x2, USBMINUS ;[030] - bld shift, 2 ;[031] - andi shift, 0xe7 ;[032] -didUnstuff2: ;[ ] - in x2, USBIN ;[033] <-- bit 3 - breq unstuff2 ;[034] *** unstuff escape - eor r0, x2 ;[035] - or phase, r0 ;[036] - eor x1, x2 ;[037] - bst x1, USBMINUS ;[038] - in r0, USBIN ;[039] <-- phase - bld shift, 3 ;[040] - andi shift, 0xcf ;[041] -didUnstuff3: ;[ ] - breq unstuff3 ;[042] *** unstuff escape - nop ;[043] - in x1, USBIN ;[044] <-- bit 4 - eor x2, x1 ;[045] - bst x2, USBMINUS ;[046] - bld shift, 4 ;[047] -didUnstuff4: ;[ ] - eor r0, x1 ;[048] - or phase, r0 ;[049] - in r0, USBIN ;[050] <-- phase - andi shift, 0x9f ;[051] - breq unstuff4 ;[052] *** unstuff escape - rjmp continueWithBit5;[053] -; [---] ;[054] - -macro POP_STANDARD ; 16 cycles - pop cnt - pop x4 - pop x3 - pop x2 - pop x1 - pop shift - pop YH - pop r0 - endm -macro POP_RETI ; 5 cycles - pop YL - out SREG, YL - pop YL - endm - -#include "asmcommon.inc" - - -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) -; K = (D+ = 1), (D- = 0) -; Spec allows 7.5 bit times from EOP to SOP for replies - -bitstuff7: - eor x1, x4 ;[4] - ldi x2, 0 ;[5] - nop2 ;[6] C is zero (brcc) - rjmp didStuff7 ;[8] - -bitstuffN: - eor x1, x4 ;[5] - ldi x2, 0 ;[6] - lpm ;[7] 3 cycle NOP, modifies r0 - out USBOUT, x1 ;[10] <-- out - rjmp didStuffN ;[0] - -#define bitStatus x3 - -sendNakAndReti: - ldi cnt, USBPID_NAK ;[-19] - rjmp sendCntAndReti ;[-18] -sendAckAndReti: - ldi cnt, USBPID_ACK ;[-17] -sendCntAndReti: - mov r0, cnt ;[-16] - ldi YL, 0 ;[-15] R0 address is 0 - ldi YH, 0 ;[-14] - ldi cnt, 2 ;[-13] -; rjmp usbSendAndReti fallthrough - -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] -;uses: x1...x4, shift, cnt, Y -;Numbers in brackets are time since first bit of sync pattern is sent -usbSendAndReti: ; 12 cycles until SOP - in x2, USBDDR ;[-12] - ori x2, USBMASK ;[-11] - sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) - in x1, USBOUT ;[-8] port mirror for tx loop - out USBDDR, x2 ;[-7] <- acquire bus -; need not init x2 (bitstuff history) because sync starts with 0 - ldi x4, USBMASK ;[-6] exor mask - ldi shift, 0x80 ;[-5] sync byte is first byte sent - ldi bitStatus, 0xff ;[-4] init bit loop counter, works for up to 12 bytes -byteloop: -bitloop: - sbrs shift, 0 ;[8] [-3] - eor x1, x4 ;[9] [-2] - out USBOUT, x1 ;[10] [-1] <-- out - ror shift ;[0] - ror x2 ;[1] -didStuffN: - cpi x2, 0xfc ;[2] - brcc bitstuffN ;[3] - nop ;[4] - subi bitStatus, 37 ;[5] 256 / 7 ~=~ 37 - brcc bitloop ;[6] when we leave the loop, bitStatus has almost the initial value - sbrs shift, 0 ;[7] - eor x1, x4 ;[8] - ror shift ;[9] -didStuff7: - out USBOUT, x1 ;[10] <-- out - ror x2 ;[0] - cpi x2, 0xfc ;[1] - brcc bitstuff7 ;[2] - ld shift, y+ ;[3] - dec cnt ;[5] - brne byteloop ;[6] -;make SE0: - cbr x1, USBMASK ;[7] prepare SE0 [spec says EOP may be 21 to 25 cycles] - lds x2, usbNewDeviceAddr;[8] - lsl x2 ;[10] we compare with left shifted address - out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - subi YL, 2 ;[0] Only assign address on data packets, not ACK/NAK in r0 - sbci YH, 0 ;[1] - breq skipAddrAssign ;[2] - sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer -skipAddrAssign: -;end of usbDeviceAddress transfer - ldi x2, 1< 12 cycles per bit -; Numbers in brackets are clocks counted from center of last sync bit -; when instruction starts -;register use in receive loop to receive the data bytes: -; shift assembles the byte currently being received -; x1 holds the D+ and D- line state -; x2 holds the previous line state -; cnt holds the number of bytes left in the receive buffer -; x3 holds the higher crc byte (see algorithm below) -; x4 is used as temporary register for the crc algorithm -; x5 is used for unstuffing: when unstuffing the last received bit is inverted in shift (to prevent further -; unstuffing calls. In the same time the corresponding bit in x5 is cleared to mark the bit as beening iverted -; zl lower crc value and crc table index -; zh used for crc table accesses - -;-------------------------------------------------------------------------------------------------------------- -; CRC mods: -; table driven crc checker, Z points to table in prog space -; ZL is the lower crc byte, x3 is the higher crc byte -; x4 is used as temp register to store different results -; the initialization of the crc register is not 0xFFFF but 0xFE54. This is because during the receipt of the -; first data byte an virtual zero data byte is added to the crc register, this results in the correct initial -; value of 0xFFFF at beginning of the second data byte before the first data byte is added to the crc. -; The magic number 0xFE54 results form the crc table: At tabH[0x54] = 0xFF = crcH (required) and -; tabL[0x54] = 0x01 -> crcL = 0x01 xor 0xFE = 0xFF -; bitcnt is renamed to x5 and is used for unstuffing purposes, the unstuffing works like in the 12MHz version -;-------------------------------------------------------------------------------------------------------------- -; CRC algorithm: -; The crc register is formed by x3 (higher byte) and ZL (lower byte). The algorithm uses a 'reversed' form -; i.e. that it takes the least significant bit first and shifts to the right. So in fact the highest order -; bit seen from the polynomial devision point of view is the lsb of ZL. (If this sounds strange to you i -; propose a research on CRC :-) ) -; Each data byte received is xored to ZL, the lower crc byte. This byte now builds the crc -; table index. Next the new high byte is loaded from the table and stored in x4 until we have space in x3 -; (its destination). -; Afterwards the lower table is loaded from the table and stored in ZL (the old index is overwritten as -; we don't need it anymore. In fact this is a right shift by 8 bits.) Now the old crc high value is xored -; to ZL, this is the second shift of the old crc value. Now x4 (the temp reg) is moved to x3 and the crc -; calculation is done. -; Prior to the first byte the two CRC register have to be initialized to 0xFFFF (as defined in usb spec) -; however the crc engine also runs during the receipt of the first byte, therefore x3 and zl are initialized -; to a magic number which results in a crc value of 0xFFFF after the first complete byte. -; -; This algorithm is split into the extra cycles of the different bits: -; bit7: XOR the received byte to ZL -; bit5: load the new high byte to x4 -; bit6: load the lower xor byte from the table, xor zl and x3, store result in zl (=the new crc low value) -; move x4 (the new high byte) to x3, the crc value is ready -; - - -macro POP_STANDARD ; 18 cycles - pop ZH - pop ZL - pop cnt - pop x5 - pop x3 - pop x2 - pop x1 - pop shift - pop x4 - endm -macro POP_RETI ; 7 cycles - pop YH - pop YL - out SREG, YL - pop YL - endm - -macro CRC_CLEANUP_AND_CHECK - ; the last byte has already been xored with the lower crc byte, we have to do the table lookup and xor - ; x3 is the higher crc byte, zl the lower one - ldi ZH, hi8(usbCrcTableHigh);[+1] get the new high byte from the table - lpm x2, Z ;[+2][+3][+4] - ldi ZH, hi8(usbCrcTableLow);[+5] get the new low xor byte from the table - lpm ZL, Z ;[+6][+7][+8] - eor ZL, x3 ;[+7] xor the old high byte with the value from the table, x2:ZL now holds the crc value - cpi ZL, 0x01 ;[+8] if the crc is ok we have a fixed remainder value of 0xb001 in x2:ZL (see usb spec) - brne ignorePacket ;[+9] detected a crc fault -> paket is ignored and retransmitted by the host - cpi x2, 0xb0 ;[+10] - brne ignorePacket ;[+11] detected a crc fault -> paket is ignored and retransmitted by the host - endm - - -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG, YH, [sofError], x4, shift, x1, x2, x3, x5, cnt, ZL, ZH - push YL ;[-28] push only what is necessary to sync with edge ASAP - in YL, SREG ;[-26] - push YL ;[-25] - push YH ;[-23] -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of < 1/4 bit which meets the spec. - sbis USBIN, USBMINUS ;[-17] - rjmp foundK ;[-16] - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -foundK: ;[-15] -;{3, 5} after falling D- edge, average delay: 4 cycles -;bit0 should be at 30 (2.5 bits) for center sampling. Currently at 4 so 26 cylces till bit 0 sample -;use 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push x4 ;[-14] -; [---] ;[-13] - lds YL, usbInputBufOffset;[-12] used to toggle the two usb receive buffers -; [---] ;[-11] - clr YH ;[-10] - subi YL, lo8(-(usbRxBuf));[-9] [rx loop init] - sbci YH, hi8(-(usbRxBuf));[-8] [rx loop init] - push shift ;[-7] -; [---] ;[-6] - ldi shift, 0x80 ;[-5] the last bit is the end of byte marker for the pid receiver loop - clc ;[-4] the carry has to be clear for receipt of pid bit 0 - sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early) - rjmp haveTwoBitsK ;[-2] - pop shift ;[-1] undo the push from before - pop x4 ;[1] - rjmp waitForK ;[3] this was not the end of sync, retry -; The entire loop from waitForK until rjmp waitForK above must not exceed two -; bit times (= 24 cycles). - -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -haveTwoBitsK: - push x1 ;[0] - push x2 ;[2] - push x3 ;[4] crc high byte - ldi x2, 1< jump back and store the byte - ori shift, 0x01 ;[11] invert the last received bit to prevent furhter unstuffing - in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors - andi x5, 0xFE ;[1] mark this bit as inverted (will be corrected before storing shift) - eor x1, x2 ;[2] x1 and x2 have to be different because the stuff bit is always a zero - andi x1, USBMASK ;[3] mask the interesting bits - breq stuffErr ;[4] if the stuff bit is a 1-bit something went wrong - mov x1, x2 ;[5] the next bit expects the last state to be in x1 - rjmp didunstuff0 ;[6] - ;[7] jump delay of rjmp didunstuffX - -unstuff1: ;[11] this is the jump delay of breq unstuffX - in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors - ori shift, 0x02 ;[1] invert the last received bit to prevent furhter unstuffing - andi x5, 0xFD ;[2] mark this bit as inverted (will be corrected before storing shift) - eor x2, x1 ;[3] x1 and x2 have to be different because the stuff bit is always a zero - andi x2, USBMASK ;[4] mask the interesting bits - breq stuffErr ;[5] if the stuff bit is a 1-bit something went wrong - mov x2, x1 ;[6] the next bit expects the last state to be in x2 - nop2 ;[7] - ;[8] - rjmp didunstuff1 ;[9] - ;[10] jump delay of rjmp didunstuffX - -unstuff2: ;[9] this is the jump delay of breq unstuffX - ori shift, 0x04 ;[10] invert the last received bit to prevent furhter unstuffing - andi x5, 0xFB ;[11] mark this bit as inverted (will be corrected before storing shift) - in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors - eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero - andi x1, USBMASK ;[2] mask the interesting bits - breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong - mov x1, x2 ;[4] the next bit expects the last state to be in x1 - nop2 ;[5] - ;[6] - rjmp didunstuff2 ;[7] - ;[8] jump delay of rjmp didunstuffX - -unstuff3: ;[9] this is the jump delay of breq unstuffX - ori shift, 0x08 ;[10] invert the last received bit to prevent furhter unstuffing - andi x5, 0xF7 ;[11] mark this bit as inverted (will be corrected before storing shift) - in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors - eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero - andi x2, USBMASK ;[2] mask the interesting bits - breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong - mov x2, x1 ;[4] the next bit expects the last state to be in x2 - nop2 ;[5] - ;[6] - rjmp didunstuff3 ;[7] - ;[8] jump delay of rjmp didunstuffX - - - -; the include has to be here due to branch distance restirctions -#define __USE_CRC__ -#include "asmcommon.inc" - - - -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) -; K = (D+ = 1), (D- = 0) -; Spec allows 7.5 bit times from EOP to SOP for replies -; 7.5 bit times is 90 cycles. ...there is plenty of time - - -sendNakAndReti: - ldi x3, USBPID_NAK ;[-18] - rjmp sendX3AndReti ;[-17] -sendAckAndReti: - ldi cnt, USBPID_ACK ;[-17] -sendCntAndReti: - mov x3, cnt ;[-16] -sendX3AndReti: - ldi YL, 20 ;[-15] x3==r20 address is 20 - ldi YH, 0 ;[-14] - ldi cnt, 2 ;[-13] -; rjmp usbSendAndReti fallthrough - -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] -;uses: x1...x4, btcnt, shift, cnt, Y -;Numbers in brackets are time since first bit of sync pattern is sent - -usbSendAndReti: ; 12 cycles until SOP - in x2, USBDDR ;[-12] - ori x2, USBMASK ;[-11] - sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) - in x1, USBOUT ;[-8] port mirror for tx loop - out USBDDR, x2 ;[-6] <- acquire bus - ldi x2, 0 ;[-6] init x2 (bitstuff history) because sync starts with 0 - ldi x4, USBMASK ;[-5] exor mask - ldi shift, 0x80 ;[-4] sync byte is first byte sent -txByteLoop: - ldi bitcnt, 0x40 ;[-3]=[9] binary 01000000 -txBitLoop: ; the loop sends the first 7 bits of the byte - sbrs shift, 0 ;[-2]=[10] if we have to send a 1 don't change the line state - eor x1, x4 ;[-1]=[11] - out USBOUT, x1 ;[0] - ror shift ;[1] - ror x2 ;[2] transfers the last sent bit to the stuffing history -didStuffN: - nop ;[3] - nop ;[4] - cpi x2, 0xfc ;[5] if we sent six consecutive ones - brcc bitstuffN ;[6] - lsr bitcnt ;[7] - brne txBitLoop ;[8] restart the loop while the 1 is still in the bitcount - -; transmit bit 7 - sbrs shift, 0 ;[9] - eor x1, x4 ;[10] -didStuff7: - ror shift ;[11] - out USBOUT, x1 ;[0] transfer bit 7 to the pins - ror x2 ;[1] move the bit into the stuffing history - cpi x2, 0xfc ;[2] - brcc bitstuff7 ;[3] - ld shift, y+ ;[4] get next byte to transmit - dec cnt ;[5] decrement byte counter - brne txByteLoop ;[7] if we have more bytes start next one - ;[8] branch delay - -;make SE0: - cbr x1, USBMASK ;[8] prepare SE0 [spec says EOP may be 25 to 30 cycles] - lds x2, usbNewDeviceAddr;[9] - lsl x2 ;[11] we compare with left shifted address - out USBOUT, x1 ;[0] <-- out SE0 -- from now 2 bits = 24 cycles until bus idle - subi YL, 20 + 2 ;[1] Only assign address on data packets, not ACK/NAK in x3 - sbci YH, 0 ;[2] -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - breq skipAddrAssign ;[3] - sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer -skipAddrAssign: -;end of usbDeviceAddress transfer - ldi x2, 1< -int main (int argc, char **argv) -{ - int i, j; - for (i=0; i<512; i++){ - unsigned short crc = i & 0xff; - for(j=0; j<8; j++) crc = (crc >> 1) ^ ((crc & 1) ? 0xa001 : 0); - if((i & 7) == 0) printf("\n.byte "); - printf("0x%02x, ", (i > 0xff ? (crc >> 8) : crc) & 0xff); - if(i == 255) printf("\n"); - } - return 0; -} - -// Use the following algorithm to compute CRC values: -ushort computeCrc(uchar *msg, uchar msgLen) -{ - uchar i; - ushort crc = 0xffff; - for(i = 0; i < msgLen; i++) - crc = usbCrcTable16[lo8(crc) ^ msg[i]] ^ hi8(crc); - return crc; -} -*/ - -.balign 256 -usbCrcTableLow: -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 - -; .balign 256 -usbCrcTableHigh: -.byte 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2 -.byte 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04 -.byte 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E -.byte 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8 -.byte 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A -.byte 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC -.byte 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6 -.byte 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10 -.byte 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32 -.byte 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4 -.byte 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE -.byte 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38 -.byte 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA -.byte 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C -.byte 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26 -.byte 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0 -.byte 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62 -.byte 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4 -.byte 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE -.byte 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68 -.byte 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA -.byte 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C -.byte 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76 -.byte 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0 -.byte 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92 -.byte 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54 -.byte 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E -.byte 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98 -.byte 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A -.byte 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C -.byte 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86 -.byte 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 - diff --git a/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm20.inc b/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm20.inc deleted file mode 100644 index 5cfaa5f..0000000 --- a/tools/avrusb/examples/custom-class/firmware/usbdrv/usbdrvasm20.inc +++ /dev/null @@ -1,360 +0,0 @@ -/* Name: usbdrvasm20.inc - * Project: AVR USB driver - * Author: Jeroen Benschop - * Based on usbdrvasm16.inc from Christian Starkjohann - * Creation Date: 2008-03-05 - * Tabsize: 4 - * Copyright: (c) 2008 by Jeroen Benschop and OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * Revision: $Id: usbdrvasm20.inc 692 2008-11-07 15:07:40Z cs $ - */ - -/* Do not link this file! Link usbdrvasm.S instead, which includes the - * appropriate implementation! - */ - -/* -General Description: -This file is the 20 MHz version of the asssembler part of the USB driver. It -requires a 20 MHz crystal (not a ceramic resonator and not a calibrated RC -oscillator). - -See usbdrv.h for a description of the entire driver. - -Since almost all of this code is timing critical, don't change unless you -really know what you are doing! Many parts require not only a maximum number -of CPU cycles, but even an exact number of cycles! -*/ - -#define leap2 x3 -#ifdef __IAR_SYSTEMS_ASM__ -#define nextInst $+2 -#else -#define nextInst .+0 -#endif - -;max stack usage: [ret(2), YL, SREG, YH, bitcnt, shift, x1, x2, x3, x4, cnt] = 12 bytes -;nominal frequency: 20 MHz -> 13.333333 cycles per bit, 106.666667 cycles per byte -; Numbers in brackets are clocks counted from center of last sync bit -; when instruction starts -;register use in receive loop: -; shift assembles the byte currently being received -; x1 holds the D+ and D- line state -; x2 holds the previous line state -; x4 (leap) is used to add a leap cycle once every three bytes received -; X3 (leap2) is used to add a leap cycle once every three stuff bits received -; bitcnt is used to determine when a stuff bit is due -; cnt holds the number of bytes left in the receive buffer - -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt - push YL ;[-28] push only what is necessary to sync with edge ASAP - in YL, SREG ;[-26] - push YL ;[-25] - push YH ;[-23] -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of < 1/4 bit which meets the spec. - sbis USBIN, USBMINUS ;[-19] - rjmp foundK ;[-18] - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -foundK: ;[-16] -;{3, 5} after falling D- edge, average delay: 4 cycles -;bit0 should be at 34 for center sampling. Currently at 4 so 30 cylces till bit 0 sample -;use 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push bitcnt ;[-16] -; [---] ;[-15] - lds YL, usbInputBufOffset;[-14] -; [---] ;[-13] - clr YH ;[-12] - subi YL, lo8(-(usbRxBuf));[-11] [rx loop init] - sbci YH, hi8(-(usbRxBuf));[-10] [rx loop init] - push shift ;[-9] -; [---] ;[-8] - ldi shift,0x40 ;[-7] set msb to "1" so processing bit7 can be detected - nop2 ;[-6] -; [---] ;[-5] - ldi bitcnt, 5 ;[-4] [rx loop init] - sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early) - rjmp haveTwoBitsK ;[-2] - pop shift ;[-1] undo the push from before - pop bitcnt ;[1] - rjmp waitForK ;[3] this was not the end of sync, retry -; The entire loop from waitForK until rjmp waitForK above must not exceed two -; bit times (= 27 cycles). - -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -haveTwoBitsK: - push x1 ;[0] - push x2 ;[2] - push x3 ;[4] (leap2) - ldi leap2, 0x55 ;[6] add leap cycle on 2nd,5th,8th,... stuff bit - push x4 ;[7] == leap - ldi leap, 0x55 ;[9] skip leap cycle on 2nd,5th,8th,... byte received - push cnt ;[10] - ldi cnt, USB_BUFSIZE ;[12] [rx loop init] - ldi x2, 1< -#ifndef __IAR_SYSTEMS_ASM__ -# include -#endif - -#define __attribute__(arg) /* not supported on IAR */ - -#ifdef __IAR_SYSTEMS_ASM__ -# define __ASSEMBLER__ /* IAR does not define standard macro for asm */ -#endif - -#ifdef __HAS_ELPM__ -# define PROGMEM __farflash -#else -# define PROGMEM __flash -#endif - -#define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr)) - -/* The following definitions are not needed by the driver, but may be of some - * help if you port a gcc based project to IAR. - */ -#define cli() __disable_interrupt() -#define sei() __enable_interrupt() -#define wdt_reset() __watchdog_reset() -#define _BV(x) (1 << (x)) - -/* assembler compatibility macros */ -#define nop2 rjmp $+2 /* jump to next instruction */ -#define XL r26 -#define XH r27 -#define YL r28 -#define YH r29 -#define ZL r30 -#define ZH r31 -#define lo8(x) LOW(x) -#define hi8(x) (((x)>>8) & 0xff) /* not HIGH to allow XLINK to make a proper range check */ - -/* Depending on the device you use, you may get problems with the way usbdrv.h - * handles the differences between devices. Since IAR does not use #defines - * for MCU registers, we can't check for the existence of a particular - * register with an #ifdef. If the autodetection mechanism fails, include - * definitions for the required USB_INTR_* macros in your usbconfig.h. See - * usbconfig-prototype.h and usbdrv.h for details. - */ - -/* ------------------------------------------------------------------------- */ -#elif __CODEVISIONAVR__ /* check for CodeVision AVR */ -/* ------------------------------------------------------------------------- */ -/* This port is not working (yet) */ - -/* #define F_CPU _MCU_CLOCK_FREQUENCY_ seems to be defined automatically */ - -#include -#include - -#define __attribute__(arg) /* not supported on IAR */ - -#define PROGMEM __flash -#define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr)) - -#ifndef __ASSEMBLER__ -static inline void cli(void) -{ - #asm("cli"); -} -static inline void sei(void) -{ - #asm("sei"); -} -#endif -#define _delay_ms(t) delay_ms(t) -#define _BV(x) (1 << (x)) -#define USB_CFG_USE_SWITCH_STATEMENT 1 /* macro for if() cascase fails for unknown reason */ - -#define macro .macro -#define endm .endmacro -#define nop2 rjmp .+0 /* jump to next instruction */ - -/* ------------------------------------------------------------------------- */ -#else /* default development environment is avr-gcc/avr-libc */ -/* ------------------------------------------------------------------------- */ - -#include -#ifdef __ASSEMBLER__ -# define _VECTOR(N) __vector_ ## N /* io.h does not define this for asm */ -#else -# include -#endif - -#define USB_READ_FLASH(addr) pgm_read_byte(addr) - -#define macro .macro -#define endm .endm -#define nop2 rjmp .+0 /* jump to next instruction */ - -#endif /* development environment */ - -/* for conveniecne, ensure that PRG_RDB exists */ -#ifndef PRG_RDB -# define PRG_RDB(addr) USB_READ_FLASH(addr) -#endif -#endif /* __usbportability_h_INCLUDED__ */ diff --git a/tools/avrusb/examples/hid-custom-rq/Readme.txt b/tools/avrusb/examples/hid-custom-rq/Readme.txt deleted file mode 100644 index 6a2ab3b..0000000 --- a/tools/avrusb/examples/hid-custom-rq/Readme.txt +++ /dev/null @@ -1,28 +0,0 @@ -This is the Readme file for the hid-custom-rq example. This is basically the -same as the custom-class example, except that the device conforms to the USB -HID class. - - -WHAT IS DEMONSTRATED? -===================== -This example demonstrates how custom requests can be sent to devices which -are otherwise HID compliant. This mechanism can be used to prevent the -"driver CD" dialog on Windows and still control the device with libusb-win32. -It can also be used to extend the functionality of the USB class, e.g. by -setting parameters. - -Please note that you should install the filter version of libusb-win32 to -take full advantage or this mode. The device driver version only has access -to devices which have been registered for it with a *.inf file. The filter -version has access to all devices. - - -MORE INFORMATION -================ -For information about how to build this example and how to use the command -line tool see the Readme file in the custom-class example. - - ----------------------------------------------------------------------------- -(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH. -http://www.obdev.at/ diff --git a/tools/avrusb/examples/hid-custom-rq/commandline/Makefile b/tools/avrusb/examples/hid-custom-rq/commandline/Makefile deleted file mode 100644 index 5894ca8..0000000 --- a/tools/avrusb/examples/hid-custom-rq/commandline/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -# Name: Makefile -# Project: hid-custom-rq example -# Author: Christian Starkjohann -# Creation Date: 2008-04-06 -# Tabsize: 4 -# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH -# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) -# This Revision: $Id: Makefile 692 2008-11-07 15:07:40Z cs $ - - -# Concigure the following definitions according to your system. -# This Makefile has been tested on Mac OS X, Linux and Windows. - -# Use the following 3 lines on Unix (uncomment the framework on Mac OS X): -USBFLAGS = `libusb-config --cflags` -USBLIBS = `libusb-config --libs` -EXE_SUFFIX = - -# Use the following 3 lines on Windows and comment out the 3 above. You may -# have to change the include paths to where you installed libusb-win32 -#USBFLAGS = -I/usr/local/include -#USBLIBS = -L/usr/local/lib -lusb -#EXE_SUFFIX = .exe - -NAME = set-led - -OBJECTS = opendevice.o $(NAME).o - -CC = gcc -CFLAGS = $(CPPFLAGS) $(USBFLAGS) -O -g -Wall -LIBS = $(USBLIBS) - -PROGRAM = $(NAME)$(EXE_SUFFIX) - - -all: $(PROGRAM) - -.c.o: - $(CC) $(CFLAGS) -c $< - -$(PROGRAM): $(OBJECTS) - $(CC) -o $(PROGRAM) $(OBJECTS) $(LIBS) - -strip: $(PROGRAM) - strip $(PROGRAM) - -clean: - rm -f *.o $(PROGRAM) diff --git a/tools/avrusb/examples/hid-custom-rq/commandline/Makefile.windows b/tools/avrusb/examples/hid-custom-rq/commandline/Makefile.windows deleted file mode 100644 index 4ea1df6..0000000 --- a/tools/avrusb/examples/hid-custom-rq/commandline/Makefile.windows +++ /dev/null @@ -1,18 +0,0 @@ -# Name: Makefile.windows -# Project: hid-custom-rq example -# Author: Christian Starkjohann -# Creation Date: 2008-04-06 -# Tabsize: 4 -# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH -# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) -# This Revision: $Id$ - -# You may use this file with -# make -f Makefile.windows -# on Windows with MinGW instead of editing the main Makefile. - -include Makefile - -USBFLAGS = -I/usr/local/mingw/include -USBLIBS = -L/usr/local/mingw/lib -lusb -EXE_SUFFIX = .exe diff --git a/tools/avrusb/examples/hid-custom-rq/commandline/opendevice.c b/tools/avrusb/examples/hid-custom-rq/commandline/opendevice.c deleted file mode 100644 index 791175b..0000000 --- a/tools/avrusb/examples/hid-custom-rq/commandline/opendevice.c +++ /dev/null @@ -1,203 +0,0 @@ -/* Name: opendevice.c - * Project: AVR-USB host-side library - * Author: Christian Starkjohann - * Creation Date: 2008-04-10 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: opendevice.c 692 2008-11-07 15:07:40Z cs $ - */ - -/* -General Description: -The functions in this module can be used to find and open a device based on -libusb or libusb-win32. -*/ - -#include -#include "opendevice.h" - -/* ------------------------------------------------------------------------- */ - -#define MATCH_SUCCESS 1 -#define MATCH_FAILED 0 -#define MATCH_ABORT -1 - -/* private interface: match text and p, return MATCH_SUCCESS, MATCH_FAILED, or MATCH_ABORT. */ -static int _shellStyleMatch(char *text, char *p) -{ -int last, matched, reverse; - - for(; *p; text++, p++){ - if(*text == 0 && *p != '*') - return MATCH_ABORT; - switch(*p){ - case '\\': - /* Literal match with following character. */ - p++; - /* FALLTHROUGH */ - default: - if(*text != *p) - return MATCH_FAILED; - continue; - case '?': - /* Match anything. */ - continue; - case '*': - while(*++p == '*') - /* Consecutive stars act just like one. */ - continue; - if(*p == 0) - /* Trailing star matches everything. */ - return MATCH_SUCCESS; - while(*text) - if((matched = _shellStyleMatch(text++, p)) != MATCH_FAILED) - return matched; - return MATCH_ABORT; - case '[': - reverse = p[1] == '^'; - if(reverse) /* Inverted character class. */ - p++; - matched = MATCH_FAILED; - if(p[1] == ']' || p[1] == '-') - if(*++p == *text) - matched = MATCH_SUCCESS; - for(last = *p; *++p && *p != ']'; last = *p) - if (*p == '-' && p[1] != ']' ? *text <= *++p && *text >= last : *text == *p) - matched = MATCH_SUCCESS; - if(matched == reverse) - return MATCH_FAILED; - continue; - } - } - return *text == 0; -} - -/* public interface for shell style matching: returns 0 if fails, 1 if matches */ -static int shellStyleMatch(char *text, char *pattern) -{ - if(pattern == NULL) /* NULL pattern is synonymous to "*" */ - return 1; - return _shellStyleMatch(text, pattern) == MATCH_SUCCESS; -} - -/* ------------------------------------------------------------------------- */ - -int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen) -{ -char buffer[256]; -int rval, i; - - if((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use libusb version if it works */ - return rval; - if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, 0x0409, buffer, sizeof(buffer), 5000)) < 0) - return rval; - if(buffer[1] != USB_DT_STRING){ - *buf = 0; - return 0; - } - if((unsigned char)buffer[0] < rval) - rval = (unsigned char)buffer[0]; - rval /= 2; - /* lossy conversion to ISO Latin1: */ - for(i=1;i buflen) /* destination buffer overflow */ - break; - buf[i-1] = buffer[2 * i]; - if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */ - buf[i-1] = '?'; - } - buf[i-1] = 0; - return i-1; -} - -/* ------------------------------------------------------------------------- */ - -int usbOpenDevice(usb_dev_handle **device, int vendorID, char *vendorNamePattern, int productID, char *productNamePattern, char *serialNamePattern, FILE *printMatchingDevicesFp, FILE *warningsFp) -{ -struct usb_bus *bus; -struct usb_device *dev; -usb_dev_handle *handle = NULL; -int errorCode = USBOPEN_ERR_NOTFOUND; - - usb_find_busses(); - usb_find_devices(); - for(bus = usb_get_busses(); bus; bus = bus->next){ - for(dev = bus->devices; dev; dev = dev->next){ /* iterate over all devices on all busses */ - if((vendorID == 0 || dev->descriptor.idVendor == vendorID) - && (productID == 0 || dev->descriptor.idProduct == productID)){ - char vendor[256], product[256], serial[256]; - int len; - handle = usb_open(dev); /* we need to open the device in order to query strings */ - if(!handle){ - errorCode = USBOPEN_ERR_ACCESS; - if(warningsFp != NULL) - fprintf(warningsFp, "Warning: cannot open VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); - continue; - } - /* now check whether the names match: */ - len = vendor[0] = 0; - if(dev->descriptor.iManufacturer > 0){ - len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, vendor, sizeof(vendor)); - } - if(len < 0){ - errorCode = USBOPEN_ERR_ACCESS; - if(warningsFp != NULL) - fprintf(warningsFp, "Warning: cannot query manufacturer for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); - }else{ - errorCode = USBOPEN_ERR_NOTFOUND; - /* printf("seen device from vendor ->%s<-\n", vendor); */ - if(shellStyleMatch(vendor, vendorNamePattern)){ - len = product[0] = 0; - if(dev->descriptor.iProduct > 0){ - len = usbGetStringAscii(handle, dev->descriptor.iProduct, product, sizeof(product)); - } - if(len < 0){ - errorCode = USBOPEN_ERR_ACCESS; - if(warningsFp != NULL) - fprintf(warningsFp, "Warning: cannot query product for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); - }else{ - errorCode = USBOPEN_ERR_NOTFOUND; - /* printf("seen product ->%s<-\n", product); */ - if(shellStyleMatch(product, productNamePattern)){ - len = serial[0] = 0; - if(dev->descriptor.iSerialNumber > 0){ - len = usbGetStringAscii(handle, dev->descriptor.iSerialNumber, serial, sizeof(serial)); - } - if(len < 0){ - errorCode = USBOPEN_ERR_ACCESS; - if(warningsFp != NULL) - fprintf(warningsFp, "Warning: cannot query serial for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); - } - if(shellStyleMatch(serial, serialNamePattern)){ - if(printMatchingDevicesFp != NULL){ - if(serial[0] == 0){ - fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product); - }else{ - fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\" serial=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product, serial); - } - }else{ - break; - } - } - } - } - } - } - usb_close(handle); - handle = NULL; - } - } - if(handle) /* we have found a deice */ - break; - } - if(handle != NULL){ - errorCode = 0; - *device = handle; - } - if(printMatchingDevicesFp != NULL) /* never return an error for listing only */ - errorCode = 0; - return errorCode; -} - -/* ------------------------------------------------------------------------- */ diff --git a/tools/avrusb/examples/hid-custom-rq/commandline/opendevice.h b/tools/avrusb/examples/hid-custom-rq/commandline/opendevice.h deleted file mode 100644 index 5e9b68b..0000000 --- a/tools/avrusb/examples/hid-custom-rq/commandline/opendevice.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Name: opendevice.h - * Project: AVR-USB host-side library - * Author: Christian Starkjohann - * Creation Date: 2008-04-10 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: opendevice.h 692 2008-11-07 15:07:40Z cs $ - */ - -/* -General Description: -This module offers additional functionality for host side drivers based on -libusb or libusb-win32. It includes a function to find and open a device -based on numeric IDs and textual description. It also includes a function to -obtain textual descriptions from a device. - -To use this functionality, simply copy opendevice.c and opendevice.h into your -project and add them to your Makefile. You may modify and redistribute these -files according to the GNU General Public License (GPL) version 2 or 3. -*/ - -#ifndef __OPENDEVICE_H_INCLUDED__ -#define __OPENDEVICE_H_INCLUDED__ - -#include /* this is libusb, see http://libusb.sourceforge.net/ */ -#include - -int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen); -/* This function gets a string descriptor from the device. 'index' is the - * string descriptor index. The string is returned in ISO Latin 1 encoding in - * 'buf' and it is terminated with a 0-character. The buffer size must be - * passed in 'buflen' to prevent buffer overflows. A libusb device handle - * must be given in 'dev'. - * Returns: The length of the string (excluding the terminating 0) or - * a negative number in case of an error. If there was an error, use - * usb_strerror() to obtain the error message. - */ - -int usbOpenDevice(usb_dev_handle **device, int vendorID, char *vendorNamePattern, int productID, char *productNamePattern, char *serialNamePattern, FILE *printMatchingDevicesFp, FILE *warningsFp); -/* This function iterates over all devices on all USB busses and searches for - * a device. Matching is done first by means of Vendor- and Product-ID (passed - * in 'vendorID' and 'productID'. An ID of 0 matches any numeric ID (wildcard). - * When a device matches by its IDs, matching by names is performed. Name - * matching can be done on textual vendor name ('vendorNamePattern'), product - * name ('productNamePattern') and serial number ('serialNamePattern'). A - * device matches only if all non-null pattern match. If you don't care about - * a string, pass NULL for the pattern. Patterns are Unix shell style pattern: - * '*' stands for 0 or more characters, '?' for one single character, a list - * of characters in square brackets for a single character from the list - * (dashes are allowed to specify a range) and if the lis of characters begins - * with a caret ('^'), it matches one character which is NOT in the list. - * Other parameters to the function: If 'warningsFp' is not NULL, warning - * messages are printed to this file descriptor with fprintf(). If - * 'printMatchingDevicesFp' is not NULL, no device is opened but matching - * devices are printed to the given file descriptor with fprintf(). - * If a device is opened, the resulting USB handle is stored in '*device'. A - * pointer to a "usb_dev_handle *" type variable must be passed here. - * Returns: 0 on success, an error code (see defines below) on failure. - */ - -/* usbOpenDevice() error codes: */ -#define USBOPEN_SUCCESS 0 /* no error */ -#define USBOPEN_ERR_ACCESS 1 /* not enough permissions to open device */ -#define USBOPEN_ERR_IO 2 /* I/O error */ -#define USBOPEN_ERR_NOTFOUND 3 /* device not found */ - - -/* Obdev's free USB IDs, see USBID-License.txt for details */ - -#define USB_VID_OBDEV_SHARED 5824 /* obdev's shared vendor ID */ -#define USB_PID_OBDEV_SHARED_CUSTOM 1500 /* shared PID for custom class devices */ -#define USB_PID_OBDEV_SHARED_HID 1503 /* shared PID for HIDs except mice & keyboards */ -#define USB_PID_OBDEV_SHARED_CDCACM 1505 /* shared PID for CDC Modem devices */ -#define USB_PID_OBDEV_SHARED_MIDI 1508 /* shared PID for MIDI class devices */ - -#endif /* __OPENDEVICE_H_INCLUDED__ */ diff --git a/tools/avrusb/examples/hid-custom-rq/commandline/set-led.c b/tools/avrusb/examples/hid-custom-rq/commandline/set-led.c deleted file mode 100644 index 52b2a3b..0000000 --- a/tools/avrusb/examples/hid-custom-rq/commandline/set-led.c +++ /dev/null @@ -1,135 +0,0 @@ -/* Name: set-led.c - * Project: hid-custom-rq example - * Author: Christian Starkjohann - * Creation Date: 2008-04-10 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: set-led.c 692 2008-11-07 15:07:40Z cs $ - */ - -/* -General Description: -This is the host-side driver for the custom-class example device. It searches -the USB for the LEDControl device and sends the requests understood by this -device. -This program must be linked with libusb on Unix and libusb-win32 on Windows. -See http://libusb.sourceforge.net/ or http://libusb-win32.sourceforge.net/ -respectively. -*/ - -#include -#include -#include -#include /* this is libusb */ -#include "opendevice.h" /* common code moved to separate module */ - -#include "../firmware/requests.h" /* custom request numbers */ -#include "../firmware/usbconfig.h" /* device's VID/PID and names */ - -static void usage(char *name) -{ - fprintf(stderr, "usage:\n"); - fprintf(stderr, " %s on ....... turn on LED\n", name); - fprintf(stderr, " %s off ...... turn off LED\n", name); - fprintf(stderr, " %s status ... ask current status of LED\n", name); -#if ENABLE_TEST - fprintf(stderr, " %s test ..... run driver reliability test\n", name); -#endif /* ENABLE_TEST */ -} - -int main(int argc, char **argv) -{ -usb_dev_handle *handle = NULL; -const unsigned char rawVid[2] = {USB_CFG_VENDOR_ID}, rawPid[2] = {USB_CFG_DEVICE_ID}; -char vendor[] = {USB_CFG_VENDOR_NAME, 0}, product[] = {USB_CFG_DEVICE_NAME, 0}; -char buffer[4]; -int cnt, vid, pid, isOn; - - usb_init(); - if(argc < 2){ /* we need at least one argument */ - usage(argv[0]); - exit(1); - } - /* compute VID/PID from usbconfig.h so that there is a central source of information */ - vid = rawVid[1] * 256 + rawVid[0]; - pid = rawPid[1] * 256 + rawPid[0]; - /* The following function is in opendevice.c: */ - if(usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) != 0){ - fprintf(stderr, "Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid, pid); - exit(1); - } - /* Since we use only control endpoint 0, we don't need to choose a - * configuration and interface. Reading device descriptor and setting a - * configuration and interface is done through endpoint 0 after all. - * However, newer versions of Linux require that we claim an interface - * even for endpoint 0. Enable the following code if your operating system - * needs it: */ -#if 0 - int retries = 1, usbConfiguration = 1, usbInterface = 0; - if(usb_set_configuration(handle, usbConfiguration) && showWarnings){ - fprintf(stderr, "Warning: could not set configuration: %s\n", usb_strerror()); - } - /* now try to claim the interface and detach the kernel HID driver on - * Linux and other operating systems which support the call. */ - while((len = usb_claim_interface(handle, usbInterface)) != 0 && retries-- > 0){ -#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP - if(usb_detach_kernel_driver_np(handle, 0) < 0 && showWarnings){ - fprintf(stderr, "Warning: could not detach kernel driver: %s\n", usb_strerror()); - } -#endif - } -#endif - - if(strcasecmp(argv[1], "status") == 0){ - cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_GET_STATUS, 0, 0, buffer, sizeof(buffer), 5000); - if(cnt < 1){ - if(cnt < 0){ - fprintf(stderr, "USB error: %s\n", usb_strerror()); - }else{ - fprintf(stderr, "only %d bytes received.\n", cnt); - } - }else{ - printf("LED is %s\n", buffer[0] ? "on" : "off"); - } - }else if((isOn = (strcasecmp(argv[1], "on") == 0)) || strcasecmp(argv[1], "off") == 0){ - cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, CUSTOM_RQ_SET_STATUS, isOn, 0, buffer, 0, 5000); - if(cnt < 0){ - fprintf(stderr, "USB error: %s\n", usb_strerror()); - } -#if ENABLE_TEST - }else if(strcasecmp(argv[1], "test") == 0){ - int i; - srandomdev(); - for(i = 0; i < 50000; i++){ - int value = random() & 0xffff, index = random() & 0xffff; - int rxValue, rxIndex; - if((i+1) % 100 == 0){ - fprintf(stderr, "\r%05d", i+1); - fflush(stderr); - } - cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_ECHO, value, index, buffer, sizeof(buffer), 5000); - if(cnt < 0){ - fprintf(stderr, "\nUSB error in iteration %d: %s\n", i, usb_strerror()); - break; - }else if(cnt != 4){ - fprintf(stderr, "\nerror in iteration %d: %d bytes received instead of 4\n", i, cnt); - break; - } - rxValue = ((int)buffer[0] & 0xff) | (((int)buffer[1] & 0xff) << 8); - rxIndex = ((int)buffer[2] & 0xff) | (((int)buffer[3] & 0xff) << 8); - if(rxValue != value || rxIndex != index){ - fprintf(stderr, "\ndata error in iteration %d:\n", i); - fprintf(stderr, "rxValue = 0x%04x value = 0x%04x\n", rxValue, value); - fprintf(stderr, "rxIndex = 0x%04x index = 0x%04x\n", rxIndex, index); - } - } - fprintf(stderr, "\nTest completed.\n"); -#endif /* ENABLE_TEST */ - }else{ - usage(argv[0]); - exit(1); - } - usb_close(handle); - return 0; -} diff --git a/tools/avrusb/examples/hid-custom-rq/firmware/Makefile b/tools/avrusb/examples/hid-custom-rq/firmware/Makefile deleted file mode 100644 index f2372db..0000000 --- a/tools/avrusb/examples/hid-custom-rq/firmware/Makefile +++ /dev/null @@ -1,164 +0,0 @@ -# Name: Makefile -# Project: hid-custom-rq example -# Author: Christian Starkjohann -# Creation Date: 2008-04-07 -# Tabsize: 4 -# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH -# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) -# This Revision: $Id: Makefile 692 2008-11-07 15:07:40Z cs $ - -DEVICE = atmega168 -F_CPU = 16000000 # in Hz -FUSE_L = # see below for fuse values for particular devices -FUSE_H = -AVRDUDE = avrdude -c usbasp -p $(DEVICE) # edit this line for your programmer - -CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0 -OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o - -COMPILE = avr-gcc -Wall -Os -DF_CPU=$(F_CPU) $(CFLAGS) -mmcu=$(DEVICE) - -############################################################################## -# Fuse values for particular devices -############################################################################## -# If your device is not listed here, go to -# http://palmavr.sourceforge.net/cgi-bin/fc.cgi -# and choose options for external crystal clock and no clock divider -# -################################## ATMega8 ################################## -# ATMega8 FUSE_L (Fuse low byte): -# 0x9f = 1 0 0 1 1 1 1 1 -# ^ ^ \ / \--+--/ -# | | | +------- CKSEL 3..0 (external >8M crystal) -# | | +--------------- SUT 1..0 (crystal osc, BOD enabled) -# | +------------------ BODEN (BrownOut Detector enabled) -# +-------------------- BODLEVEL (2.7V) -# ATMega8 FUSE_H (Fuse high byte): -# 0xc9 = 1 1 0 0 1 0 0 1 <-- BOOTRST (boot reset vector at 0x0000) -# ^ ^ ^ ^ ^ ^ ^------ BOOTSZ0 -# | | | | | +-------- BOOTSZ1 -# | | | | + --------- EESAVE (don't preserve EEPROM over chip erase) -# | | | +-------------- CKOPT (full output swing) -# | | +---------------- SPIEN (allow serial programming) -# | +------------------ WDTON (WDT not always on) -# +-------------------- RSTDISBL (reset pin is enabled) -# -############################## ATMega48/88/168 ############################## -# ATMega*8 FUSE_L (Fuse low byte): -# 0xdf = 1 1 0 1 1 1 1 1 -# ^ ^ \ / \--+--/ -# | | | +------- CKSEL 3..0 (external >8M crystal) -# | | +--------------- SUT 1..0 (crystal osc, BOD enabled) -# | +------------------ CKOUT (if 0: Clock output enabled) -# +-------------------- CKDIV8 (if 0: divide by 8) -# ATMega*8 FUSE_H (Fuse high byte): -# 0xde = 1 1 0 1 1 1 1 0 -# ^ ^ ^ ^ ^ \-+-/ -# | | | | | +------ BODLEVEL 0..2 (110 = 1.8 V) -# | | | | + --------- EESAVE (preserve EEPROM over chip erase) -# | | | +-------------- WDTON (if 0: watchdog always on) -# | | +---------------- SPIEN (allow serial programming) -# | +------------------ DWEN (debug wire enable) -# +-------------------- RSTDISBL (reset pin is enabled) -# -############################## ATTiny25/45/85 ############################### -# ATMega*5 FUSE_L (Fuse low byte): -# 0xef = 1 1 1 0 1 1 1 1 -# ^ ^ \+/ \--+--/ -# | | | +------- CKSEL 3..0 (clock selection -> crystal @ 12 MHz) -# | | +--------------- SUT 1..0 (BOD enabled, fast rising power) -# | +------------------ CKOUT (clock output on CKOUT pin -> disabled) -# +-------------------- CKDIV8 (divide clock by 8 -> don't divide) -# ATMega*5 FUSE_H (Fuse high byte): -# 0xdd = 1 1 0 1 1 1 0 1 -# ^ ^ ^ ^ ^ \-+-/ -# | | | | | +------ BODLEVEL 2..0 (brownout trigger level -> 2.7V) -# | | | | +---------- EESAVE (preserve EEPROM on Chip Erase -> not preserved) -# | | | +-------------- WDTON (watchdog timer always on -> disable) -# | | +---------------- SPIEN (enable serial programming -> enabled) -# | +------------------ DWEN (debug wire enable) -# +-------------------- RSTDISBL (disable external reset -> enabled) -# -################################ ATTiny2313 ################################# -# ATTiny2313 FUSE_L (Fuse low byte): -# 0xef = 1 1 1 0 1 1 1 1 -# ^ ^ \+/ \--+--/ -# | | | +------- CKSEL 3..0 (clock selection -> crystal @ 12 MHz) -# | | +--------------- SUT 1..0 (BOD enabled, fast rising power) -# | +------------------ CKOUT (clock output on CKOUT pin -> disabled) -# +-------------------- CKDIV8 (divide clock by 8 -> don't divide) -# ATTiny2313 FUSE_H (Fuse high byte): -# 0xdb = 1 1 0 1 1 0 1 1 -# ^ ^ ^ ^ \-+-/ ^ -# | | | | | +---- RSTDISBL (disable external reset -> enabled) -# | | | | +-------- BODLEVEL 2..0 (brownout trigger level -> 2.7V) -# | | | +-------------- WDTON (watchdog timer always on -> disable) -# | | +---------------- SPIEN (enable serial programming -> enabled) -# | +------------------ EESAVE (preserve EEPROM on Chip Erase -> not preserved) -# +-------------------- DWEN (debug wire enable) - - -# symbolic targets: -help: - @echo "This Makefile has no default rule. Use one of the following:" - @echo "make hex ....... to build main.hex" - @echo "make program ... to flash fuses and firmware" - @echo "make fuse ...... to flash the fuses" - @echo "make flash ..... to flash the firmware (use this on metaboard)" - @echo "make clean ..... to delete objects and hex file" - -hex: main.hex - -program: flash fuse - -# rule for programming fuse bits: -fuse: - @[ "$(FUSE_H)" != "" -a "$(FUSE_L)" != "" ] || \ - { echo "*** Edit Makefile and choose values for FUSE_L and FUSE_H!"; exit 1; } - $(AVRDUDE) -U hfuse:w:$(FUSE_H):m -U lfuse:w:$(FUSE_L):m - -# rule for uploading firmware: -flash: main.hex - $(AVRDUDE) -U flash:w:main.hex:i - -# rule for deleting dependent files (those which can be built by Make): -clean: - rm -f main.hex main.lst main.obj main.cof main.list main.map main.eep.hex main.elf *.o usbdrv/*.o main.s usbdrv/oddebug.s usbdrv/usbdrv.s - -# Generic rule for compiling C files: -.c.o: - $(COMPILE) -c $< -o $@ - -# Generic rule for assembling Assembler source files: -.S.o: - $(COMPILE) -x assembler-with-cpp -c $< -o $@ -# "-x assembler-with-cpp" should not be necessary since this is the default -# file type for the .S (with capital S) extension. However, upper case -# characters are not always preserved on Windows. To ensure WinAVR -# compatibility define the file type manually. - -# Generic rule for compiling C to assembler, used for debugging only. -.c.s: - $(COMPILE) -S $< -o $@ - -# file targets: - -# Since we don't want to ship the driver multipe times, we copy it into this project: -usbdrv: - cp -r ../../../usbdrv . - -main.elf: usbdrv $(OBJECTS) # usbdrv dependency only needed because we copy it - $(COMPILE) -o main.elf $(OBJECTS) - -main.hex: main.elf - rm -f main.hex main.eep.hex - avr-objcopy -j .text -j .data -O ihex main.elf main.hex - avr-size main.hex - -# debugging targets: - -disasm: main.elf - avr-objdump -d main.elf - -cpp: - $(COMPILE) -E main.c diff --git a/tools/avrusb/examples/hid-custom-rq/firmware/main.c b/tools/avrusb/examples/hid-custom-rq/firmware/main.c deleted file mode 100644 index d4cbb01..0000000 --- a/tools/avrusb/examples/hid-custom-rq/firmware/main.c +++ /dev/null @@ -1,121 +0,0 @@ -/* Name: main.c - * Project: hid-custom-rq example - * Author: Christian Starkjohann - * Creation Date: 2008-04-07 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: main.c 692 2008-11-07 15:07:40Z cs $ - */ - -/* -This example should run on most AVRs with only little changes. No special -hardware resources except INT0 are used. You may have to change usbconfig.h for -different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or -at least be connected to INT0 as well. -We assume that an LED is connected to port B bit 0. If you connect it to a -different port or bit, change the macros below: -*/ -#define LED_PORT_DDR DDRB -#define LED_PORT_OUTPUT PORTB -#define LED_BIT 0 - -#include -#include -#include /* for sei() */ -#include /* for _delay_ms() */ - -#include /* required by usbdrv.h */ -#include "usbdrv.h" -#include "oddebug.h" /* This is also an example for using debug macros */ -#include "requests.h" /* The custom request numbers we use */ - -/* ------------------------------------------------------------------------- */ -/* ----------------------------- USB interface ----------------------------- */ -/* ------------------------------------------------------------------------- */ - -PROGMEM char usbHidReportDescriptor[22] = { /* USB report descriptor */ - 0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop) - 0x09, 0x01, // USAGE (Vendor Usage 1) - 0xa1, 0x01, // COLLECTION (Application) - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) - 0x75, 0x08, // REPORT_SIZE (8) - 0x95, 0x01, // REPORT_COUNT (1) - 0x09, 0x00, // USAGE (Undefined) - 0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf) - 0xc0 // END_COLLECTION -}; -/* The descriptor above is a dummy only, it silences the drivers. The report - * it describes consists of one byte of undefined data. - * We don't transfer our data through HID reports, we use custom requests - * instead. - */ - -/* ------------------------------------------------------------------------- */ - -usbMsgLen_t usbFunctionSetup(uchar data[8]) -{ -usbRequest_t *rq = (void *)data; - - if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_VENDOR){ - DBG1(0x50, &rq->bRequest, 1); /* debug output: print our request */ - if(rq->bRequest == CUSTOM_RQ_SET_STATUS){ - if(rq->wValue.bytes[0] & 1){ /* set LED */ - LED_PORT_OUTPUT |= _BV(LED_BIT); - }else{ /* clear LED */ - LED_PORT_OUTPUT &= ~_BV(LED_BIT); - } - }else if(rq->bRequest == CUSTOM_RQ_GET_STATUS){ - static uchar dataBuffer[1]; /* buffer must stay valid when usbFunctionSetup returns */ - dataBuffer[0] = ((LED_PORT_OUTPUT & _BV(LED_BIT)) != 0); - usbMsgPtr = dataBuffer; /* tell the driver which data to return */ - return 1; /* tell the driver to send 1 byte */ - } - }else{ - /* calss requests USBRQ_HID_GET_REPORT and USBRQ_HID_SET_REPORT are - * not implemented since we never call them. The operating system - * won't call them either because our descriptor defines no meaning. - */ - } - return 0; /* default for not implemented requests: return no data back to host */ -} - -/* ------------------------------------------------------------------------- */ - -int main(void) -{ -uchar i; - - wdt_enable(WDTO_1S); - /* Even if you don't use the watchdog, turn it off here. On newer devices, - * the status of the watchdog (on/off, period) is PRESERVED OVER RESET! - */ - DBG1(0x00, 0, 0); /* debug output: main starts */ - /* RESET status: all port bits are inputs without pull-up. - * That's the way we need D+ and D-. Therefore we don't need any - * additional hardware initialization. - */ - odDebugInit(); - usbInit(); - usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */ - i = 0; - while(--i){ /* fake USB disconnect for > 250 ms */ - wdt_reset(); - _delay_ms(1); - } - usbDeviceConnect(); - LED_PORT_DDR |= _BV(LED_BIT); /* make the LED bit an output */ - sei(); - DBG1(0x01, 0, 0); /* debug output: main loop starts */ - for(;;){ /* main event loop */ -#if 0 /* this is a bit too aggressive for a debug output */ - DBG2(0x02, 0, 0); /* debug output: main loop iterates */ -#endif - wdt_reset(); - usbPoll(); - } - return 0; -} - -/* ------------------------------------------------------------------------- */ diff --git a/tools/avrusb/examples/hid-custom-rq/firmware/requests.h b/tools/avrusb/examples/hid-custom-rq/firmware/requests.h deleted file mode 100644 index 79282b6..0000000 --- a/tools/avrusb/examples/hid-custom-rq/firmware/requests.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Name: requests.h - * Project: custom-class, a basic USB example - * Author: Christian Starkjohann - * Creation Date: 2008-04-09 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: requests.h 692 2008-11-07 15:07:40Z cs $ - */ - -/* This header is shared between the firmware and the host software. It - * defines the USB request numbers (and optionally data types) used to - * communicate between the host and the device. - */ - -#ifndef __REQUESTS_H_INCLUDED__ -#define __REQUESTS_H_INCLUDED__ - -#define CUSTOM_RQ_SET_STATUS 1 -/* Set the LED status. Control-OUT. - * The requested status is passed in the "wValue" field of the control - * transfer. No OUT data is sent. Bit 0 of the low byte of wValue controls - * the LED. - */ - -#define CUSTOM_RQ_GET_STATUS 2 -/* Get the current LED status. Control-IN. - * This control transfer involves a 1 byte data phase where the device sends - * the current status to the host. The status is in bit 0 of the byte. - */ - -#endif /* __REQUESTS_H_INCLUDED__ */ diff --git a/tools/avrusb/examples/hid-custom-rq/firmware/usbconfig.h b/tools/avrusb/examples/hid-custom-rq/firmware/usbconfig.h deleted file mode 100644 index 864af93..0000000 --- a/tools/avrusb/examples/hid-custom-rq/firmware/usbconfig.h +++ /dev/null @@ -1,350 +0,0 @@ -/* Name: usbconfig.h - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2005-04-01 - * Tabsize: 4 - * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: usbconfig-prototype.h 734 2009-03-23 11:10:07Z cs $ - */ - -#ifndef __usbconfig_h_included__ -#define __usbconfig_h_included__ - -/* -General Description: -This file is an example configuration (with inline documentation) for the USB -driver. It configures AVR-USB for USB D+ connected to Port D bit 2 (which is -also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may -wire the lines to any other port, as long as D+ is also wired to INT0 (or any -other hardware interrupt, as long as it is the highest level interrupt, see -section at the end of this file). -*/ - -/* ---------------------------- Hardware Config ---------------------------- */ - -#define USB_CFG_IOPORTNAME D -/* This is the port where the USB bus is connected. When you configure it to - * "B", the registers PORTB, PINB and DDRB will be used. - */ -#define USB_CFG_DMINUS_BIT 4 -/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected. - * This may be any bit in the port. - */ -#define USB_CFG_DPLUS_BIT 2 -/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected. - * This may be any bit in the port. Please note that D+ must also be connected - * to interrupt pin INT0! [You can also use other interrupts, see section - * "Optional MCU Description" below, or you can connect D- to the interrupt, as - * it is required if you use the USB_COUNT_SOF feature. If you use D- for the - * interrupt, the USB interrupt will also be triggered at Start-Of-Frame - * markers every millisecond.] - */ -#define USB_CFG_CLOCK_KHZ (F_CPU/1000) -/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000, - * 16500 and 20000. The 12.8 MHz and 16.5 MHz versions of the code require no - * crystal, they tolerate +/- 1% deviation from the nominal frequency. All - * other rates require a precision of 2000 ppm and thus a crystal! - * Default if not specified: 12 MHz - */ -#define USB_CFG_CHECK_CRC 0 -/* Define this to 1 if you want that the driver checks integrity of incoming - * data packets (CRC checks). CRC checks cost quite a bit of code size and are - * currently only available for 18 MHz crystal clock. You must choose - * USB_CFG_CLOCK_KHZ = 18000 if you enable this option. - */ - -/* ----------------------- Optional Hardware Config ------------------------ */ - -/* #define USB_CFG_PULLUP_IOPORTNAME D */ -/* If you connect the 1.5k pullup resistor from D- to a port pin instead of - * V+, you can connect and disconnect the device from firmware by calling - * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h). - * This constant defines the port on which the pullup resistor is connected. - */ -/* #define USB_CFG_PULLUP_BIT 4 */ -/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined - * above) where the 1.5k pullup resistor is connected. See description - * above for details. - */ - -/* --------------------------- Functional Range ---------------------------- */ - -#define USB_CFG_HAVE_INTRIN_ENDPOINT 1 -/* Define this to 1 if you want to compile a version with two endpoints: The - * default control endpoint 0 and an interrupt-in endpoint (any other endpoint - * number). - */ -#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0 -/* Define this to 1 if you want to compile a version with three endpoints: The - * default control endpoint 0, an interrupt-in endpoint 3 (or the number - * configured below) and a catch-all default interrupt-in endpoint as above. - * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature. - */ -#define USB_CFG_EP3_NUMBER 3 -/* If the so-called endpoint 3 is used, it can now be configured to any other - * endpoint number (except 0) with this macro. Default if undefined is 3. - */ -/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */ -/* The above macro defines the startup condition for data toggling on the - * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1. - * Since the token is toggled BEFORE sending any data, the first packet is - * sent with the oposite value of this configuration! - */ -#define USB_CFG_IMPLEMENT_HALT 0 -/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature - * for endpoint 1 (interrupt endpoint). Although you may not need this feature, - * it is required by the standard. We have made it a config option because it - * bloats the code considerably. - */ -#define USB_CFG_SUPPRESS_INTR_CODE 0 -/* Define this to 1 if you want to declare interrupt-in endpoints, but don't - * want to send any data over them. If this macro is defined to 1, functions - * usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if - * you need the interrupt-in endpoints in order to comply to an interface - * (e.g. HID), but never want to send any data. This option saves a couple - * of bytes in flash memory and the transmit buffers in RAM. - */ -#define USB_CFG_INTR_POLL_INTERVAL 100 -/* If you compile a version with endpoint 1 (interrupt-in), this is the poll - * interval. The value is in milliseconds and must not be less than 10 ms for - * low speed devices. - */ -#define USB_CFG_IS_SELF_POWERED 0 -/* Define this to 1 if the device has its own power supply. Set it to 0 if the - * device is powered from the USB bus. - */ -#define USB_CFG_MAX_BUS_POWER 40 -/* Set this variable to the maximum USB bus power consumption of your device. - * The value is in milliamperes. [It will be divided by two since USB - * communicates power requirements in units of 2 mA.] - */ -#define USB_CFG_IMPLEMENT_FN_WRITE 0 -/* Set this to 1 if you want usbFunctionWrite() to be called for control-out - * transfers. Set it to 0 if you don't need it and want to save a couple of - * bytes. - */ -#define USB_CFG_IMPLEMENT_FN_READ 0 -/* Set this to 1 if you need to send control replies which are generated - * "on the fly" when usbFunctionRead() is called. If you only want to send - * data from a static buffer, set it to 0 and return the data from - * usbFunctionSetup(). This saves a couple of bytes. - */ -#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0 -/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints. - * You must implement the function usbFunctionWriteOut() which receives all - * interrupt/bulk data sent to any endpoint other than 0. The endpoint number - * can be found in 'usbRxToken'. - */ -#define USB_CFG_HAVE_FLOWCONTROL 0 -/* Define this to 1 if you want flowcontrol over USB data. See the definition - * of the macros usbDisableAllRequests() and usbEnableAllRequests() in - * usbdrv.h. - */ -#define USB_CFG_LONG_TRANSFERS 0 -/* Define this to 1 if you want to send/receive blocks of more than 254 bytes - * in a single control-in or control-out transfer. Note that the capability - * for long transfers increases the driver size. - */ -/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */ -/* This macro is a hook if you want to do unconventional things. If it is - * defined, it's inserted at the beginning of received message processing. - * If you eat the received message and don't want default processing to - * proceed, do a return after doing your things. One possible application - * (besides debugging) is to flash a status LED on each packet. - */ -/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */ -/* This macro is a hook if you need to know when an USB RESET occurs. It has - * one parameter which distinguishes between the start of RESET state and its - * end. - */ -/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */ -/* This macro (if defined) is executed when a USB SET_ADDRESS request was - * received. - */ -#define USB_COUNT_SOF 0 -/* define this macro to 1 if you need the global variable "usbSofCount" which - * counts SOF packets. This feature requires that the hardware interrupt is - * connected to D- instead of D+. - */ -/* #ifdef __ASSEMBLER__ - * macro myAssemblerMacro - * in YL, TCNT0 - * sts timer0Snapshot, YL - * endm - * #endif - * #define USB_SOF_HOOK myAssemblerMacro - * This macro (if defined) is executed in the assembler module when a - * Start Of Frame condition is detected. It is recommended to define it to - * the name of an assembler macro which is defined here as well so that more - * than one assembler instruction can be used. The macro may use the register - * YL and modify SREG. If it lasts longer than a couple of cycles, USB messages - * immediately after an SOF pulse may be lost and must be retried by the host. - * What can you do with this hook? Since the SOF signal occurs exactly every - * 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in - * designs running on the internal RC oscillator. - * Please note that Start Of Frame detection works only if D- is wired to the - * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES! - */ -#define USB_CFG_CHECK_DATA_TOGGLING 0 -/* define this macro to 1 if you want to filter out duplicate data packets - * sent by the host. Duplicates occur only as a consequence of communication - * errors, when the host does not receive an ACK. Please note that you need to - * implement the filtering yourself in usbFunctionWriteOut() and - * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable - * for each control- and out-endpoint to check for duplicate packets. - */ -#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0 -/* define this macro to 1 if you want the function usbMeasureFrameLength() - * compiled in. This function can be used to calibrate the AVR's RC oscillator. - */ - -/* -------------------------- Device Description --------------------------- */ - -#define USB_CFG_VENDOR_ID 0xc0, 0x16 -/* USB vendor ID for the device, low byte first. If you have registered your - * own Vendor ID, define it here. Otherwise you use one of obdev's free shared - * VID/PID pairs. Be sure to read USBID-License.txt for rules! - */ -#define USB_CFG_DEVICE_ID 0xdf, 0x05 /* obdev's shared PID for HIDs */ -/* This is the ID of the product, low byte first. It is interpreted in the - * scope of the vendor ID. If you have registered your own VID with usb.org - * or if you have licensed a PID from somebody else, define it here. Otherwise - * you use obdev's free shared VID/PID pair. Be sure to read the rules in - * USBID-License.txt! - */ -#define USB_CFG_DEVICE_VERSION 0x00, 0x01 -/* Version number of the device: Minor number first, then major number. - */ -#define USB_CFG_VENDOR_NAME 'o', 'b', 'd', 'e', 'v', '.', 'a', 't' -#define USB_CFG_VENDOR_NAME_LEN 8 -/* These two values define the vendor name returned by the USB device. The name - * must be given as a list of characters under single quotes. The characters - * are interpreted as Unicode (UTF-16) entities. - * If you don't want a vendor name string, undefine these macros. - * ALWAYS define a vendor name containing your Internet domain name if you use - * obdev's free shared VID/PID pair. See the file USBID-License.txt for - * details. - */ -#define USB_CFG_DEVICE_NAME 'L', 'E', 'D', 'C', 't', 'l', 'H', 'I', 'D' -#define USB_CFG_DEVICE_NAME_LEN 9 -/* Same as above for the device name. If you don't want a device name, undefine - * the macros. See the file USBID-License.txt before you assign a name if you - * use a shared VID/PID. - */ -/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */ -/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */ -/* Same as above for the serial number. If you don't want a serial number, - * undefine the macros. - * It may be useful to provide the serial number through other means than at - * compile time. See the section about descriptor properties below for how - * to fine tune control over USB descriptors such as the string descriptor - * for the serial number. - */ -#define USB_CFG_DEVICE_CLASS 0 -#define USB_CFG_DEVICE_SUBCLASS 0 -/* See USB specification if you want to conform to an existing device class. - * Class 0xff is "vendor specific". - */ -#define USB_CFG_INTERFACE_CLASS 3 -#define USB_CFG_INTERFACE_SUBCLASS 0 -#define USB_CFG_INTERFACE_PROTOCOL 0 -/* See USB specification if you want to conform to an existing device class or - * protocol. The following classes must be set at interface level: - * HID class is 3, no subclass and protocol required (but may be useful!) - * CDC class is 2, use subclass 2 and protocol 1 for ACM - */ -#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 22 -/* Define this to the length of the HID report descriptor, if you implement - * an HID device. Otherwise don't define it or define it to 0. - * If you use this define, you must add a PROGMEM character array named - * "usbHidReportDescriptor" to your code which contains the report descriptor. - * Don't forget to keep the array and this define in sync! - */ - -/* #define USB_PUBLIC static */ -/* Use the define above if you #include usbdrv.c instead of linking against it. - * This technique saves a couple of bytes in flash memory. - */ - -/* ------------------- Fine Control over USB Descriptors ------------------- */ -/* If you don't want to use the driver's default USB descriptors, you can - * provide our own. These can be provided as (1) fixed length static data in - * flash memory, (2) fixed length static data in RAM or (3) dynamically at - * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more - * information about this function. - * Descriptor handling is configured through the descriptor's properties. If - * no properties are defined or if they are 0, the default descriptor is used. - * Possible properties are: - * + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched - * at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is - * used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if - * you want RAM pointers. - * + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found - * in static memory is in RAM, not in flash memory. - * + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash), - * the driver must know the descriptor's length. The descriptor itself is - * found at the address of a well known identifier (see below). - * List of static descriptor names (must be declared PROGMEM if in flash): - * char usbDescriptorDevice[]; - * char usbDescriptorConfiguration[]; - * char usbDescriptorHidReport[]; - * char usbDescriptorString0[]; - * int usbDescriptorStringVendor[]; - * int usbDescriptorStringDevice[]; - * int usbDescriptorStringSerialNumber[]; - * Other descriptors can't be provided statically, they must be provided - * dynamically at runtime. - * - * Descriptor properties are or-ed or added together, e.g.: - * #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18)) - * - * The following descriptors are defined: - * USB_CFG_DESCR_PROPS_DEVICE - * USB_CFG_DESCR_PROPS_CONFIGURATION - * USB_CFG_DESCR_PROPS_STRINGS - * USB_CFG_DESCR_PROPS_STRING_0 - * USB_CFG_DESCR_PROPS_STRING_VENDOR - * USB_CFG_DESCR_PROPS_STRING_PRODUCT - * USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER - * USB_CFG_DESCR_PROPS_HID - * USB_CFG_DESCR_PROPS_HID_REPORT - * USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver) - * - * Note about string descriptors: String descriptors are not just strings, they - * are Unicode strings prefixed with a 2 byte header. Example: - * int serialNumberDescriptor[] = { - * USB_STRING_DESCRIPTOR_HEADER(6), - * 'S', 'e', 'r', 'i', 'a', 'l' - * }; - */ - -#define USB_CFG_DESCR_PROPS_DEVICE 0 -#define USB_CFG_DESCR_PROPS_CONFIGURATION 0 -#define USB_CFG_DESCR_PROPS_STRINGS 0 -#define USB_CFG_DESCR_PROPS_STRING_0 0 -#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0 -#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0 -#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0 -#define USB_CFG_DESCR_PROPS_HID 0 -#define USB_CFG_DESCR_PROPS_HID_REPORT 0 -#define USB_CFG_DESCR_PROPS_UNKNOWN 0 - -/* ----------------------- Optional MCU Description ------------------------ */ - -/* The following configurations have working defaults in usbdrv.h. You - * usually don't need to set them explicitly. Only if you want to run - * the driver on a device which is not yet supported or with a compiler - * which is not fully supported (such as IAR C) or if you use a differnt - * interrupt than INT0, you may have to define some of these. - */ -/* #define USB_INTR_CFG MCUCR */ -/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */ -/* #define USB_INTR_CFG_CLR 0 */ -/* #define USB_INTR_ENABLE GIMSK */ -/* #define USB_INTR_ENABLE_BIT INT0 */ -/* #define USB_INTR_PENDING GIFR */ -/* #define USB_INTR_PENDING_BIT INTF0 */ -/* #define USB_INTR_VECTOR SIG_INTERRUPT0 */ - -#endif /* __usbconfig_h_included__ */ diff --git a/tools/avrusb/examples/hid-data/Readme.txt b/tools/avrusb/examples/hid-data/Readme.txt deleted file mode 100644 index cb17baa..0000000 --- a/tools/avrusb/examples/hid-data/Readme.txt +++ /dev/null @@ -1,75 +0,0 @@ -This is the Readme file for the hid-data example. In this example, we show -how blocks of data can be exchanged with the device using only functionality -compliant to the HID class. Since class drivers for HID are included with -Windows, you don't need to install drivers on Windows. - - -WHAT IS DEMONSTRATED? -===================== -This example demonstrates how the HID class can be misused to transfer fixed -size blocks of data (up to the driver's transfer size limit) over HID feature -reports. This technique is of great value on Windows because no driver DLLs -are needed (the hid-custom-rq example still requires the libusb-win32 DLL, -although it may be in the program's directory). The host side application -requires no installation, it can even be started directly from a CD. This -example also demonstrates how to transfer data using usbFunctionWrite() and -usbFunctionRead(). - - -PREREQUISITES -============= -Target hardware: You need an AVR based circuit based on one of the examples -(see the "circuits" directory at the top level of this package), e.g. the -metaboard (http://www.obdev.at/goto.php?t=metaboard). - -AVR development environment: You need the gcc tool chain for the AVR, see -the Prerequisites section in the top level Readme file for how to obtain it. - -Host development environment: A C compiler and libusb on Unix. On Windows -you need the Driver Development Kit (DDK) Instead of libusb. MinGW ships -with a free version of the DDK. - - -BUILDING THE FIRMWARE -===================== -Change to the "firmware" directory and modify Makefile according to your -architecture (CPU clock, target device, fuse values) and ISP programmer. Then -edit usbconfig.h according to your pin assignments for D+ and D-. The default -settings are for the metaboard hardware. - -Type "make hex" to build main.hex, then "make flash" to upload the firmware -to the device. Don't forget to run "make fuse" once to program the fuses. If -you use a prototyping board with boot loader, follow the instructions of the -boot loader instead. - -Please note that the first "make hex" copies the driver from the top level -into the firmware directory. If you use a different build system than our -Makefile, you must copy the driver by hand. - - -BUILDING THE HOST SOFTWARE -========================== -Make sure that you have libusb (on Unix) or the DDK (on Windows) installed. -We recommend MinGW on Windows since it includes a free version of the DDK. -Then change to directory "commandline" and run "make" on Unix or -"make -f Makefile.windows" on Windows. - - -USING THE COMMAND LINE TOOL -=========================== -The device implements a data store of 128 bytes in EEPROM. You can send a -block of 128 bytes to the device or read the block using the command line -tool. - -To send a block to the device, use e.g. - - hidtool write 0x01,0x02,0x03,0x04,... - -and to receive the block, use - - hidtool read - - ----------------------------------------------------------------------------- -(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH. -http://www.obdev.at/ diff --git a/tools/avrusb/examples/hid-data/commandline/Makefile b/tools/avrusb/examples/hid-data/commandline/Makefile deleted file mode 100644 index dabfa42..0000000 --- a/tools/avrusb/examples/hid-data/commandline/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -# Name: Makefile -# Project: hid-data example -# Author: Christian Starkjohann -# Creation Date: 2008-04-11 -# Tabsize: 4 -# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH -# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) -# This Revision: $Id: Makefile 692 2008-11-07 15:07:40Z cs $ - -# Please read the definitions below and edit them as appropriate for your -# system: - -# Use the following 3 lines on Unix and Mac OS X: -USBFLAGS= `libusb-config --cflags` -USBLIBS= `libusb-config --libs` -EXE_SUFFIX= - -# Use the following 3 lines on Windows and comment out the 3 above: -#USBFLAGS= -#USBLIBS= -lhid -lusb -lsetupapi -#EXE_SUFFIX= .exe - -CC= gcc -CFLAGS= -O -Wall $(USBFLAGS) -LIBS= $(USBLIBS) - -OBJ= hidtool.o hiddata.o -PROGRAM= hidtool$(EXE_SUFFIX) - -all: $(PROGRAM) - -$(PROGRAM): $(OBJ) - $(CC) -o $(PROGRAM) $(OBJ) $(LIBS) - -strip: $(PROGRAM) - strip $(PROGRAM) - -clean: - rm -f $(OBJ) $(PROGRAM) - -.c.o: - $(CC) $(ARCH_COMPILE) $(CFLAGS) -c $*.c -o $*.o diff --git a/tools/avrusb/examples/hid-data/commandline/Makefile.windows b/tools/avrusb/examples/hid-data/commandline/Makefile.windows deleted file mode 100644 index a66dffc..0000000 --- a/tools/avrusb/examples/hid-data/commandline/Makefile.windows +++ /dev/null @@ -1,18 +0,0 @@ -# Name: Makefile.windows -# Project: hid-data example -# Author: Christian Starkjohann -# Creation Date: 2008-04-11 -# Tabsize: 4 -# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH -# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) -# This Revision: $Id$ - -# You may use this file with -# make -f Makefile.windows -# on Windows with MinGW instead of editing the main Makefile. - -include Makefile - -USBFLAGS= -USBLIBS= -lhid -lsetupapi -EXE_SUFFIX= .exe diff --git a/tools/avrusb/examples/hid-data/commandline/hiddata.c b/tools/avrusb/examples/hid-data/commandline/hiddata.c deleted file mode 100644 index 8e7d975..0000000 --- a/tools/avrusb/examples/hid-data/commandline/hiddata.c +++ /dev/null @@ -1,317 +0,0 @@ -/* Name: hiddata.c - * Author: Christian Starkjohann - * Creation Date: 2008-04-11 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: hiddata.c 692 2008-11-07 15:07:40Z cs $ - */ - -#include -#include "hiddata.h" - -/* ######################################################################## */ -#if defined(WIN32) /* ##################################################### */ -/* ######################################################################## */ - -#include -#include -#include "hidsdi.h" -#include - -#ifdef DEBUG -#define DEBUG_PRINT(arg) printf arg -#else -#define DEBUG_PRINT(arg) -#endif - -/* ------------------------------------------------------------------------ */ - -static void convertUniToAscii(char *buffer) -{ -unsigned short *uni = (void *)buffer; -char *ascii = buffer; - - while(*uni != 0){ - if(*uni >= 256){ - *ascii++ = '?'; - }else{ - *ascii++ = *uni++; - } - } - *ascii++ = 0; -} - -int usbhidOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int usesReportIDs) -{ -GUID hidGuid; /* GUID for HID driver */ -HDEVINFO deviceInfoList; -SP_DEVICE_INTERFACE_DATA deviceInfo; -SP_DEVICE_INTERFACE_DETAIL_DATA *deviceDetails = NULL; -DWORD size; -int i, openFlag = 0; /* may be FILE_FLAG_OVERLAPPED */ -int errorCode = USBOPEN_ERR_NOTFOUND; -HANDLE handle = INVALID_HANDLE_VALUE; -HIDD_ATTRIBUTES deviceAttributes; - - HidD_GetHidGuid(&hidGuid); - deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); - deviceInfo.cbSize = sizeof(deviceInfo); - for(i=0;;i++){ - if(handle != INVALID_HANDLE_VALUE){ - CloseHandle(handle); - handle = INVALID_HANDLE_VALUE; - } - if(!SetupDiEnumDeviceInterfaces(deviceInfoList, 0, &hidGuid, i, &deviceInfo)) - break; /* no more entries */ - /* first do a dummy call just to determine the actual size required */ - SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL); - if(deviceDetails != NULL) - free(deviceDetails); - deviceDetails = malloc(size); - deviceDetails->cbSize = sizeof(*deviceDetails); - /* this call is for real: */ - SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails, size, &size, NULL); - DEBUG_PRINT(("checking HID path \"%s\"\n", deviceDetails->DevicePath)); - /* attempt opening for R/W -- we don't care about devices which can't be accessed */ - handle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, openFlag, NULL); - if(handle == INVALID_HANDLE_VALUE){ - DEBUG_PRINT(("opening failed: %d\n", (int)GetLastError())); - /* errorCode = USBOPEN_ERR_ACCESS; opening will always fail for mouse -- ignore */ - continue; - } - deviceAttributes.Size = sizeof(deviceAttributes); - HidD_GetAttributes(handle, &deviceAttributes); - DEBUG_PRINT(("device attributes: vid=%d pid=%d\n", deviceAttributes.VendorID, deviceAttributes.ProductID)); - if(deviceAttributes.VendorID != vendor || deviceAttributes.ProductID != product) - continue; /* ignore this device */ - errorCode = USBOPEN_ERR_NOTFOUND; - if(vendorName != NULL && productName != NULL){ - char buffer[512]; - if(!HidD_GetManufacturerString(handle, buffer, sizeof(buffer))){ - DEBUG_PRINT(("error obtaining vendor name\n")); - errorCode = USBOPEN_ERR_IO; - continue; - } - convertUniToAscii(buffer); - DEBUG_PRINT(("vendorName = \"%s\"\n", buffer)); - if(strcmp(vendorName, buffer) != 0) - continue; - if(!HidD_GetProductString(handle, buffer, sizeof(buffer))){ - DEBUG_PRINT(("error obtaining product name\n")); - errorCode = USBOPEN_ERR_IO; - continue; - } - convertUniToAscii(buffer); - DEBUG_PRINT(("productName = \"%s\"\n", buffer)); - if(strcmp(productName, buffer) != 0) - continue; - } - break; /* we have found the device we are looking for! */ - } - SetupDiDestroyDeviceInfoList(deviceInfoList); - if(deviceDetails != NULL) - free(deviceDetails); - if(handle != INVALID_HANDLE_VALUE){ - *device = (usbDevice_t *)handle; - errorCode = 0; - } - return errorCode; -} - -/* ------------------------------------------------------------------------ */ - -void usbhidCloseDevice(usbDevice_t *device) -{ - CloseHandle((HANDLE)device); -} - -/* ------------------------------------------------------------------------ */ - -int usbhidSetReport(usbDevice_t *device, char *buffer, int len) -{ -BOOLEAN rval; - - rval = HidD_SetFeature((HANDLE)device, buffer, len); - return rval == 0 ? USBOPEN_ERR_IO : 0; -} - -/* ------------------------------------------------------------------------ */ - -int usbhidGetReport(usbDevice_t *device, int reportNumber, char *buffer, int *len) -{ -BOOLEAN rval = 0; - - buffer[0] = reportNumber; - rval = HidD_GetFeature((HANDLE)device, buffer, *len); - return rval == 0 ? USBOPEN_ERR_IO : 0; -} - -/* ------------------------------------------------------------------------ */ - -/* ######################################################################## */ -#else /* defined WIN32 #################################################### */ -/* ######################################################################## */ - -#include -#include - -#define usbDevice usb_dev_handle /* use libusb's device structure */ - -/* ------------------------------------------------------------------------- */ - -#define USBRQ_HID_GET_REPORT 0x01 -#define USBRQ_HID_SET_REPORT 0x09 - -#define USB_HID_REPORT_TYPE_FEATURE 3 - - -static int usesReportIDs; - -/* ------------------------------------------------------------------------- */ - -static int usbhidGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen) -{ -char buffer[256]; -int rval, i; - - if((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use libusb version if it works */ - return rval; - if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, 0x0409, buffer, sizeof(buffer), 5000)) < 0) - return rval; - if(buffer[1] != USB_DT_STRING){ - *buf = 0; - return 0; - } - if((unsigned char)buffer[0] < rval) - rval = (unsigned char)buffer[0]; - rval /= 2; - /* lossy conversion to ISO Latin1: */ - for(i=1;i buflen) /* destination buffer overflow */ - break; - buf[i-1] = buffer[2 * i]; - if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */ - buf[i-1] = '?'; - } - buf[i-1] = 0; - return i-1; -} - -int usbhidOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int _usesReportIDs) -{ -struct usb_bus *bus; -struct usb_device *dev; -usb_dev_handle *handle = NULL; -int errorCode = USBOPEN_ERR_NOTFOUND; -static int didUsbInit = 0; - - if(!didUsbInit){ - usb_init(); - didUsbInit = 1; - } - usb_find_busses(); - usb_find_devices(); - for(bus=usb_get_busses(); bus; bus=bus->next){ - for(dev=bus->devices; dev; dev=dev->next){ - if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product){ - char string[256]; - int len; - handle = usb_open(dev); /* we need to open the device in order to query strings */ - if(!handle){ - errorCode = USBOPEN_ERR_ACCESS; - fprintf(stderr, "Warning: cannot open USB device: %s\n", usb_strerror()); - continue; - } - if(vendorName == NULL && productName == NULL){ /* name does not matter */ - break; - } - /* now check whether the names match: */ - len = usbhidGetStringAscii(handle, dev->descriptor.iManufacturer, string, sizeof(string)); - if(len < 0){ - errorCode = USBOPEN_ERR_IO; - fprintf(stderr, "Warning: cannot query manufacturer for device: %s\n", usb_strerror()); - }else{ - errorCode = USBOPEN_ERR_NOTFOUND; - /* fprintf(stderr, "seen device from vendor ->%s<-\n", string); */ - if(strcmp(string, vendorName) == 0){ - len = usbhidGetStringAscii(handle, dev->descriptor.iProduct, string, sizeof(string)); - if(len < 0){ - errorCode = USBOPEN_ERR_IO; - fprintf(stderr, "Warning: cannot query product for device: %s\n", usb_strerror()); - }else{ - errorCode = USBOPEN_ERR_NOTFOUND; - /* fprintf(stderr, "seen product ->%s<-\n", string); */ - if(strcmp(string, productName) == 0) - break; - } - } - } - usb_close(handle); - handle = NULL; - } - } - if(handle) - break; - } - if(handle != NULL){ - errorCode = 0; - *device = (void *)handle; - usesReportIDs = _usesReportIDs; - } - return errorCode; -} - -/* ------------------------------------------------------------------------- */ - -void usbhidCloseDevice(usbDevice_t *device) -{ - if(device != NULL) - usb_close((void *)device); -} - -/* ------------------------------------------------------------------------- */ - -int usbhidSetReport(usbDevice_t *device, char *buffer, int len) -{ -int bytesSent; - - if(!usesReportIDs){ - buffer++; /* skip dummy report ID */ - len--; - } - bytesSent = usb_control_msg((void *)device, USB_TYPE_CLASS | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, USBRQ_HID_SET_REPORT, USB_HID_REPORT_TYPE_FEATURE << 8 | (buffer[0] & 0xff), 0, buffer, len, 5000); - if(bytesSent != len){ - if(bytesSent < 0) - fprintf(stderr, "Error sending message: %s\n", usb_strerror()); - return USBOPEN_ERR_IO; - } - return 0; -} - -/* ------------------------------------------------------------------------- */ - -int usbhidGetReport(usbDevice_t *device, int reportNumber, char *buffer, int *len) -{ -int bytesReceived, maxLen = *len; - - if(!usesReportIDs){ - buffer++; /* make room for dummy report ID */ - maxLen--; - } - bytesReceived = usb_control_msg((void *)device, USB_TYPE_CLASS | USB_RECIP_DEVICE | USB_ENDPOINT_IN, USBRQ_HID_GET_REPORT, USB_HID_REPORT_TYPE_FEATURE << 8 | reportNumber, 0, buffer, maxLen, 5000); - if(bytesReceived < 0){ - fprintf(stderr, "Error sending message: %s\n", usb_strerror()); - return USBOPEN_ERR_IO; - } - *len = bytesReceived; - if(!usesReportIDs){ - buffer[-1] = reportNumber; /* add dummy report ID */ - (*len)++; - } - return 0; -} - -/* ######################################################################## */ -#endif /* defined WIN32 ################################################### */ -/* ######################################################################## */ diff --git a/tools/avrusb/examples/hid-data/commandline/hiddata.h b/tools/avrusb/examples/hid-data/commandline/hiddata.h deleted file mode 100644 index fce0743..0000000 --- a/tools/avrusb/examples/hid-data/commandline/hiddata.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Name: hiddata.h - * Author: Christian Starkjohann - * Creation Date: 2008-04-11 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: hiddata.h 692 2008-11-07 15:07:40Z cs $ - */ - -#ifndef __HIDDATA_H_INCLUDED__ -#define __HIDDATA_H_INCLUDED__ - -/* -General Description: -This module implements an abstraction layer for data transfer over HID feature -requests. The implementation uses native Windows functions on Windows so that -no driver installation is required and libusb on Unix. You must link the -appropriate libraries in either case: "-lhid -lusb -lsetupapi" on Windows and -`libusb-config --libs` on Unix. -*/ - -/* ------------------------------------------------------------------------ */ - -#define USBOPEN_SUCCESS 0 /* no error */ -#define USBOPEN_ERR_ACCESS 1 /* not enough permissions to open device */ -#define USBOPEN_ERR_IO 2 /* I/O error */ -#define USBOPEN_ERR_NOTFOUND 3 /* device not found */ - -/* ------------------------------------------------------------------------ */ - -typedef struct usbDevice usbDevice_t; -/* Opaque data type representing the USB device. This can be a Windows handle - * or a libusb handle, depending on the backend implementation. - */ - -/* ------------------------------------------------------------------------ */ - -int usbhidOpenDevice(usbDevice_t **device, int vendorID, char *vendorName, int productID, char *productName, int usesReportIDs); -/* This function opens a USB device. 'vendorID' and 'productID' are the numeric - * Vendor-ID and Product-ID of the device we want to open. If 'vendorName' and - * 'productName' are both not NULL, only devices with matching manufacturer- - * and product name strings are accepted. If the device uses report IDs, - * 'usesReportIDs' must be set to a non-zero value. - * Returns: If a matching device has been found, USBOPEN_SUCCESS is returned - * and '*device' is set to an opaque pointer representing the device. The - * device must be closed with usbhidCloseDevice(). If the device has not been - * found or opening failed, an error code is returned. - */ -void usbhidCloseDevice(usbDevice_t *device); -/* Every device opened with usbhidOpenDevice() must be closed with this function. - */ -int usbhidSetReport(usbDevice_t *device, char *buffer, int len); -/* This function sends a feature report to the device. The report ID must be - * in the first byte of buffer and the length 'len' of the report is specified - * including this report ID. If no report IDs are used, buffer[0] must be set - * to 0 (dummy report ID). - * Returns: 0 on success, an error code otherwise. - */ -int usbhidGetReport(usbDevice_t *device, int reportID, char *buffer, int *len); -/* This function obtains a feature report from the device. The requested - * report-ID is passed in 'reportID'. The caller must pass a buffer of the size - * of the expected report in 'buffer' and initialize the variable pointed to by - * 'len' to the total size of this buffer. Upon successful return, the report - * (prefixed with the report-ID) is in 'buffer' and the actual length of the - * report is returned in '*len'. - * Returns: 0 on success, an error code otherwise. - */ - -/* ------------------------------------------------------------------------ */ - -#endif /* __HIDDATA_H_INCLUDED__ */ diff --git a/tools/avrusb/examples/hid-data/commandline/hidsdi.h b/tools/avrusb/examples/hid-data/commandline/hidsdi.h deleted file mode 100644 index a549ab1..0000000 --- a/tools/avrusb/examples/hid-data/commandline/hidsdi.h +++ /dev/null @@ -1,49 +0,0 @@ -/* Name: hidsdi.h - * Author: Christian Starkjohann - * Creation Date: 2006-02-02 - * Tabsize: 4 - * Copyright: (c) 2006-2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: hidsdi.h 692 2008-11-07 15:07:40Z cs $ - */ - -/* -General Description -This file is a replacement for hidsdi.h from the Windows DDK. It defines some -of the types and function prototypes of this header for our project. If you -have the Windows DDK version of this file or a version shipped with MinGW, use -that instead. -*/ - -#ifndef _HIDSDI_H -#define _HIDSDI_H - -#include - -#include -#include - -typedef struct{ - ULONG Size; - USHORT VendorID; - USHORT ProductID; - USHORT VersionNumber; -}HIDD_ATTRIBUTES; - -void __stdcall HidD_GetHidGuid(OUT LPGUID hidGuid); - -BOOLEAN __stdcall HidD_GetAttributes(IN HANDLE device, OUT HIDD_ATTRIBUTES *attributes); - -BOOLEAN __stdcall HidD_GetManufacturerString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen); -BOOLEAN __stdcall HidD_GetProductString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen); -BOOLEAN __stdcall HidD_GetSerialNumberString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen); - -BOOLEAN __stdcall HidD_GetFeature(IN HANDLE device, OUT void *reportBuffer, IN ULONG bufferLen); -BOOLEAN __stdcall HidD_SetFeature(IN HANDLE device, IN void *reportBuffer, IN ULONG bufferLen); - -BOOLEAN __stdcall HidD_GetNumInputBuffers(IN HANDLE device, OUT ULONG *numBuffers); -BOOLEAN __stdcall HidD_SetNumInputBuffers(IN HANDLE device, OUT ULONG numBuffers); - -#include - -#endif diff --git a/tools/avrusb/examples/hid-data/commandline/hidtool b/tools/avrusb/examples/hid-data/commandline/hidtool deleted file mode 100644 index 7a8f9f851ff94cad9040e79744e5c32cd18d523a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14265 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 diff --git a/tools/avrusb/examples/hid-data/commandline/hidtool.c b/tools/avrusb/examples/hid-data/commandline/hidtool.c deleted file mode 100644 index 9b581cd..0000000 --- a/tools/avrusb/examples/hid-data/commandline/hidtool.c +++ /dev/null @@ -1,127 +0,0 @@ -/* Name: hidtool.c - * Project: hid-data example - * Author: Christian Starkjohann - * Creation Date: 2008-04-11 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: hidtool.c 723 2009-03-16 19:04:32Z cs $ - */ - -#include -#include -#include -#include "hiddata.h" -#include "../firmware/usbconfig.h" /* for device VID, PID, vendor name and product name */ - -/* ------------------------------------------------------------------------- */ - -static char *usbErrorMessage(int errCode) -{ -static char buffer[80]; - - switch(errCode){ - case USBOPEN_ERR_ACCESS: return "Access to device denied"; - case USBOPEN_ERR_NOTFOUND: return "The specified device was not found"; - case USBOPEN_ERR_IO: return "Communication error with device"; - default: - sprintf(buffer, "Unknown USB error %d", errCode); - return buffer; - } - return NULL; /* not reached */ -} - -static usbDevice_t *openDevice(void) -{ -usbDevice_t *dev = NULL; -unsigned char rawVid[2] = {USB_CFG_VENDOR_ID}, rawPid[2] = {USB_CFG_DEVICE_ID}; -char vendorName[] = {USB_CFG_VENDOR_NAME, 0}, productName[] = {USB_CFG_DEVICE_NAME, 0}; -int vid = rawVid[0] + 256 * rawVid[1]; -int pid = rawPid[0] + 256 * rawPid[1]; -int err; - - if((err = usbhidOpenDevice(&dev, vid, vendorName, pid, productName, 0)) != 0){ - fprintf(stderr, "error finding %s: %s\n", productName, usbErrorMessage(err)); - return NULL; - } - return dev; -} - -/* ------------------------------------------------------------------------- */ - -static void hexdump(char *buffer, int len) -{ -int i; -FILE *fp = stdout; - - for(i = 0; i < len; i++){ - if(i != 0){ - if(i % 16 == 0){ - fprintf(fp, "\n"); - }else{ - fprintf(fp, " "); - } - } - fprintf(fp, "0x%02x", buffer[i] & 0xff); - } - if(i != 0) - fprintf(fp, "\n"); -} - -static int hexread(char *buffer, char *string, int buflen) -{ -char *s; -int pos = 0; - - while((s = strtok(string, ", ")) != NULL && pos < buflen){ - string = NULL; - buffer[pos++] = (char)strtol(s, NULL, 0); - } - return pos; -} - -/* ------------------------------------------------------------------------- */ - -static void usage(char *myName) -{ - fprintf(stderr, "usage:\n"); - fprintf(stderr, " %s read\n", myName); - fprintf(stderr, " %s write \n", myName); -} - -int main(int argc, char **argv) -{ -usbDevice_t *dev; -char buffer[129]; /* room for dummy report ID */ -int err; - - if(argc < 2){ - usage(argv[0]); - exit(1); - } - if((dev = openDevice()) == NULL) - exit(1); - if(strcasecmp(argv[1], "read") == 0){ - int len = sizeof(buffer); - if((err = usbhidGetReport(dev, 0, buffer, &len)) != 0){ - fprintf(stderr, "error reading data: %s\n", usbErrorMessage(err)); - }else{ - hexdump(buffer + 1, sizeof(buffer) - 1); - } - }else if(strcasecmp(argv[1], "write") == 0){ - int i, pos; - memset(buffer, 0, sizeof(buffer)); - for(pos = 1, i = 2; i < argc && pos < sizeof(buffer); i++){ - pos += hexread(buffer + pos, argv[i], sizeof(buffer) - pos); - } - if((err = usbhidSetReport(dev, buffer, sizeof(buffer))) != 0) /* add a dummy report ID */ - fprintf(stderr, "error writing data: %s\n", usbErrorMessage(err)); - }else{ - usage(argv[0]); - exit(1); - } - usbhidCloseDevice(dev); - return 0; -} - -/* ------------------------------------------------------------------------- */ diff --git a/tools/avrusb/examples/hid-data/firmware/Makefile b/tools/avrusb/examples/hid-data/firmware/Makefile deleted file mode 100644 index 5876ab0..0000000 --- a/tools/avrusb/examples/hid-data/firmware/Makefile +++ /dev/null @@ -1,164 +0,0 @@ -# Name: Makefile -# Project: hid-data example -# Author: Christian Starkjohann -# Creation Date: 2008-04-07 -# Tabsize: 4 -# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH -# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) -# This Revision: $Id: Makefile 692 2008-11-07 15:07:40Z cs $ - -DEVICE = atmega168 -F_CPU = 16000000 # in Hz -FUSE_L = # see below for fuse values for particular devices -FUSE_H = -AVRDUDE = avrdude -c usbasp -p $(DEVICE) # edit this line for your programmer - -CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0 -OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o - -COMPILE = avr-gcc -Wall -Os -DF_CPU=$(F_CPU) $(CFLAGS) -mmcu=$(DEVICE) - -############################################################################## -# Fuse values for particular devices -############################################################################## -# If your device is not listed here, go to -# http://palmavr.sourceforge.net/cgi-bin/fc.cgi -# and choose options for external crystal clock and no clock divider -# -################################## ATMega8 ################################## -# ATMega8 FUSE_L (Fuse low byte): -# 0x9f = 1 0 0 1 1 1 1 1 -# ^ ^ \ / \--+--/ -# | | | +------- CKSEL 3..0 (external >8M crystal) -# | | +--------------- SUT 1..0 (crystal osc, BOD enabled) -# | +------------------ BODEN (BrownOut Detector enabled) -# +-------------------- BODLEVEL (2.7V) -# ATMega8 FUSE_H (Fuse high byte): -# 0xc9 = 1 1 0 0 1 0 0 1 <-- BOOTRST (boot reset vector at 0x0000) -# ^ ^ ^ ^ ^ ^ ^------ BOOTSZ0 -# | | | | | +-------- BOOTSZ1 -# | | | | + --------- EESAVE (don't preserve EEPROM over chip erase) -# | | | +-------------- CKOPT (full output swing) -# | | +---------------- SPIEN (allow serial programming) -# | +------------------ WDTON (WDT not always on) -# +-------------------- RSTDISBL (reset pin is enabled) -# -############################## ATMega48/88/168 ############################## -# ATMega*8 FUSE_L (Fuse low byte): -# 0xdf = 1 1 0 1 1 1 1 1 -# ^ ^ \ / \--+--/ -# | | | +------- CKSEL 3..0 (external >8M crystal) -# | | +--------------- SUT 1..0 (crystal osc, BOD enabled) -# | +------------------ CKOUT (if 0: Clock output enabled) -# +-------------------- CKDIV8 (if 0: divide by 8) -# ATMega*8 FUSE_H (Fuse high byte): -# 0xde = 1 1 0 1 1 1 1 0 -# ^ ^ ^ ^ ^ \-+-/ -# | | | | | +------ BODLEVEL 0..2 (110 = 1.8 V) -# | | | | + --------- EESAVE (preserve EEPROM over chip erase) -# | | | +-------------- WDTON (if 0: watchdog always on) -# | | +---------------- SPIEN (allow serial programming) -# | +------------------ DWEN (debug wire enable) -# +-------------------- RSTDISBL (reset pin is enabled) -# -############################## ATTiny25/45/85 ############################### -# ATMega*5 FUSE_L (Fuse low byte): -# 0xef = 1 1 1 0 1 1 1 1 -# ^ ^ \+/ \--+--/ -# | | | +------- CKSEL 3..0 (clock selection -> crystal @ 12 MHz) -# | | +--------------- SUT 1..0 (BOD enabled, fast rising power) -# | +------------------ CKOUT (clock output on CKOUT pin -> disabled) -# +-------------------- CKDIV8 (divide clock by 8 -> don't divide) -# ATMega*5 FUSE_H (Fuse high byte): -# 0xdd = 1 1 0 1 1 1 0 1 -# ^ ^ ^ ^ ^ \-+-/ -# | | | | | +------ BODLEVEL 2..0 (brownout trigger level -> 2.7V) -# | | | | +---------- EESAVE (preserve EEPROM on Chip Erase -> not preserved) -# | | | +-------------- WDTON (watchdog timer always on -> disable) -# | | +---------------- SPIEN (enable serial programming -> enabled) -# | +------------------ DWEN (debug wire enable) -# +-------------------- RSTDISBL (disable external reset -> enabled) -# -################################ ATTiny2313 ################################# -# ATTiny2313 FUSE_L (Fuse low byte): -# 0xef = 1 1 1 0 1 1 1 1 -# ^ ^ \+/ \--+--/ -# | | | +------- CKSEL 3..0 (clock selection -> crystal @ 12 MHz) -# | | +--------------- SUT 1..0 (BOD enabled, fast rising power) -# | +------------------ CKOUT (clock output on CKOUT pin -> disabled) -# +-------------------- CKDIV8 (divide clock by 8 -> don't divide) -# ATTiny2313 FUSE_H (Fuse high byte): -# 0xdb = 1 1 0 1 1 0 1 1 -# ^ ^ ^ ^ \-+-/ ^ -# | | | | | +---- RSTDISBL (disable external reset -> enabled) -# | | | | +-------- BODLEVEL 2..0 (brownout trigger level -> 2.7V) -# | | | +-------------- WDTON (watchdog timer always on -> disable) -# | | +---------------- SPIEN (enable serial programming -> enabled) -# | +------------------ EESAVE (preserve EEPROM on Chip Erase -> not preserved) -# +-------------------- DWEN (debug wire enable) - - -# symbolic targets: -help: - @echo "This Makefile has no default rule. Use one of the following:" - @echo "make hex ....... to build main.hex" - @echo "make program ... to flash fuses and firmware" - @echo "make fuse ...... to flash the fuses" - @echo "make flash ..... to flash the firmware (use this on metaboard)" - @echo "make clean ..... to delete objects and hex file" - -hex: main.hex - -program: flash fuse - -# rule for programming fuse bits: -fuse: - @[ "$(FUSE_H)" != "" -a "$(FUSE_L)" != "" ] || \ - { echo "*** Edit Makefile and choose values for FUSE_L and FUSE_H!"; exit 1; } - $(AVRDUDE) -U hfuse:w:$(FUSE_H):m -U lfuse:w:$(FUSE_L):m - -# rule for uploading firmware: -flash: main.hex - $(AVRDUDE) -U flash:w:main.hex:i - -# rule for deleting dependent files (those which can be built by Make): -clean: - rm -f main.hex main.lst main.obj main.cof main.list main.map main.eep.hex main.elf *.o usbdrv/*.o main.s usbdrv/oddebug.s usbdrv/usbdrv.s - -# Generic rule for compiling C files: -.c.o: - $(COMPILE) -c $< -o $@ - -# Generic rule for assembling Assembler source files: -.S.o: - $(COMPILE) -x assembler-with-cpp -c $< -o $@ -# "-x assembler-with-cpp" should not be necessary since this is the default -# file type for the .S (with capital S) extension. However, upper case -# characters are not always preserved on Windows. To ensure WinAVR -# compatibility define the file type manually. - -# Generic rule for compiling C to assembler, used for debugging only. -.c.s: - $(COMPILE) -S $< -o $@ - -# file targets: - -# Since we don't want to ship the driver multipe times, we copy it into this project: -usbdrv: - cp -r ../../../usbdrv . - -main.elf: usbdrv $(OBJECTS) # usbdrv dependency only needed because we copy it - $(COMPILE) -o main.elf $(OBJECTS) - -main.hex: main.elf - rm -f main.hex main.eep.hex - avr-objcopy -j .text -j .data -O ihex main.elf main.hex - avr-size main.hex - -# debugging targets: - -disasm: main.elf - avr-objdump -d main.elf - -cpp: - $(COMPILE) -E main.c diff --git a/tools/avrusb/examples/hid-data/firmware/main.c b/tools/avrusb/examples/hid-data/firmware/main.c deleted file mode 100644 index 71d0eb2..0000000 --- a/tools/avrusb/examples/hid-data/firmware/main.c +++ /dev/null @@ -1,141 +0,0 @@ -/* Name: main.c - * Project: hid-data, example how to use HID for data transfer - * Author: Christian Starkjohann - * Creation Date: 2008-04-11 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: main.c 692 2008-11-07 15:07:40Z cs $ - */ - -/* -This example should run on most AVRs with only little changes. No special -hardware resources except INT0 are used. You may have to change usbconfig.h for -different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or -at least be connected to INT0 as well. -*/ - -#include -#include -#include /* for sei() */ -#include /* for _delay_ms() */ -#include - -#include /* required by usbdrv.h */ -#include "usbdrv.h" -#include "oddebug.h" /* This is also an example for using debug macros */ - -/* ------------------------------------------------------------------------- */ -/* ----------------------------- USB interface ----------------------------- */ -/* ------------------------------------------------------------------------- */ - -PROGMEM char usbHidReportDescriptor[22] = { /* USB report descriptor */ - 0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop) - 0x09, 0x01, // USAGE (Vendor Usage 1) - 0xa1, 0x01, // COLLECTION (Application) - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) - 0x75, 0x08, // REPORT_SIZE (8) - 0x95, 0x80, // REPORT_COUNT (128) - 0x09, 0x00, // USAGE (Undefined) - 0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf) - 0xc0 // END_COLLECTION -}; -/* Since we define only one feature report, we don't use report-IDs (which - * would be the first byte of the report). The entire report consists of 128 - * opaque data bytes. - */ - -/* The following variables store the status of the current data transfer */ -static uchar currentAddress; -static uchar bytesRemaining; - -/* ------------------------------------------------------------------------- */ - -/* usbFunctionRead() is called when the host requests a chunk of data from - * the device. For more information see the documentation in usbdrv/usbdrv.h. - */ -uchar usbFunctionRead(uchar *data, uchar len) -{ - if(len > bytesRemaining) - len = bytesRemaining; - eeprom_read_block(data, (uchar *)0 + currentAddress, len); - currentAddress += len; - bytesRemaining -= len; - return len; -} - -/* usbFunctionWrite() is called when the host sends a chunk of data to the - * device. For more information see the documentation in usbdrv/usbdrv.h. - */ -uchar usbFunctionWrite(uchar *data, uchar len) -{ - if(bytesRemaining == 0) - return 1; /* end of transfer */ - if(len > bytesRemaining) - len = bytesRemaining; - eeprom_write_block(data, (uchar *)0 + currentAddress, len); - currentAddress += len; - bytesRemaining -= len; - return bytesRemaining == 0; /* return 1 if this was the last chunk */ -} - -/* ------------------------------------------------------------------------- */ - -usbMsgLen_t usbFunctionSetup(uchar data[8]) -{ -usbRequest_t *rq = (void *)data; - - if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* HID class request */ - if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */ - /* since we have only one report type, we can ignore the report-ID */ - bytesRemaining = 128; - currentAddress = 0; - return USB_NO_MSG; /* use usbFunctionRead() to obtain data */ - }else if(rq->bRequest == USBRQ_HID_SET_REPORT){ - /* since we have only one report type, we can ignore the report-ID */ - bytesRemaining = 128; - currentAddress = 0; - return USB_NO_MSG; /* use usbFunctionWrite() to receive data from host */ - } - }else{ - /* ignore vendor type requests, we don't use any */ - } - return 0; -} - -/* ------------------------------------------------------------------------- */ - -int main(void) -{ -uchar i; - - wdt_enable(WDTO_1S); - /* Even if you don't use the watchdog, turn it off here. On newer devices, - * the status of the watchdog (on/off, period) is PRESERVED OVER RESET! - */ - DBG1(0x00, 0, 0); /* debug output: main starts */ - /* RESET status: all port bits are inputs without pull-up. - * That's the way we need D+ and D-. Therefore we don't need any - * additional hardware initialization. - */ - odDebugInit(); - usbInit(); - usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */ - i = 0; - while(--i){ /* fake USB disconnect for > 250 ms */ - wdt_reset(); - _delay_ms(1); - } - usbDeviceConnect(); - sei(); - DBG1(0x01, 0, 0); /* debug output: main loop starts */ - for(;;){ /* main event loop */ - DBG1(0x02, 0, 0); /* debug output: main loop iterates */ - wdt_reset(); - usbPoll(); - } - return 0; -} - -/* ------------------------------------------------------------------------- */ diff --git a/tools/avrusb/examples/hid-data/firmware/usbconfig.h b/tools/avrusb/examples/hid-data/firmware/usbconfig.h deleted file mode 100644 index fc507ea..0000000 --- a/tools/avrusb/examples/hid-data/firmware/usbconfig.h +++ /dev/null @@ -1,350 +0,0 @@ -/* Name: usbconfig.h - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2005-04-01 - * Tabsize: 4 - * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: usbconfig-prototype.h 734 2009-03-23 11:10:07Z cs $ - */ - -#ifndef __usbconfig_h_included__ -#define __usbconfig_h_included__ - -/* -General Description: -This file is an example configuration (with inline documentation) for the USB -driver. It configures AVR-USB for USB D+ connected to Port D bit 2 (which is -also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may -wire the lines to any other port, as long as D+ is also wired to INT0 (or any -other hardware interrupt, as long as it is the highest level interrupt, see -section at the end of this file). -*/ - -/* ---------------------------- Hardware Config ---------------------------- */ - -#define USB_CFG_IOPORTNAME D -/* This is the port where the USB bus is connected. When you configure it to - * "B", the registers PORTB, PINB and DDRB will be used. - */ -#define USB_CFG_DMINUS_BIT 4 -/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected. - * This may be any bit in the port. - */ -#define USB_CFG_DPLUS_BIT 2 -/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected. - * This may be any bit in the port. Please note that D+ must also be connected - * to interrupt pin INT0! [You can also use other interrupts, see section - * "Optional MCU Description" below, or you can connect D- to the interrupt, as - * it is required if you use the USB_COUNT_SOF feature. If you use D- for the - * interrupt, the USB interrupt will also be triggered at Start-Of-Frame - * markers every millisecond.] - */ -#define USB_CFG_CLOCK_KHZ (F_CPU/1000) -/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000, - * 16500 and 20000. The 12.8 MHz and 16.5 MHz versions of the code require no - * crystal, they tolerate +/- 1% deviation from the nominal frequency. All - * other rates require a precision of 2000 ppm and thus a crystal! - * Default if not specified: 12 MHz - */ -#define USB_CFG_CHECK_CRC 0 -/* Define this to 1 if you want that the driver checks integrity of incoming - * data packets (CRC checks). CRC checks cost quite a bit of code size and are - * currently only available for 18 MHz crystal clock. You must choose - * USB_CFG_CLOCK_KHZ = 18000 if you enable this option. - */ - -/* ----------------------- Optional Hardware Config ------------------------ */ - -/* #define USB_CFG_PULLUP_IOPORTNAME D */ -/* If you connect the 1.5k pullup resistor from D- to a port pin instead of - * V+, you can connect and disconnect the device from firmware by calling - * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h). - * This constant defines the port on which the pullup resistor is connected. - */ -/* #define USB_CFG_PULLUP_BIT 4 */ -/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined - * above) where the 1.5k pullup resistor is connected. See description - * above for details. - */ - -/* --------------------------- Functional Range ---------------------------- */ - -#define USB_CFG_HAVE_INTRIN_ENDPOINT 1 -/* Define this to 1 if you want to compile a version with two endpoints: The - * default control endpoint 0 and an interrupt-in endpoint (any other endpoint - * number). - */ -#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0 -/* Define this to 1 if you want to compile a version with three endpoints: The - * default control endpoint 0, an interrupt-in endpoint 3 (or the number - * configured below) and a catch-all default interrupt-in endpoint as above. - * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature. - */ -#define USB_CFG_EP3_NUMBER 3 -/* If the so-called endpoint 3 is used, it can now be configured to any other - * endpoint number (except 0) with this macro. Default if undefined is 3. - */ -/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */ -/* The above macro defines the startup condition for data toggling on the - * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1. - * Since the token is toggled BEFORE sending any data, the first packet is - * sent with the oposite value of this configuration! - */ -#define USB_CFG_IMPLEMENT_HALT 0 -/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature - * for endpoint 1 (interrupt endpoint). Although you may not need this feature, - * it is required by the standard. We have made it a config option because it - * bloats the code considerably. - */ -#define USB_CFG_SUPPRESS_INTR_CODE 0 -/* Define this to 1 if you want to declare interrupt-in endpoints, but don't - * want to send any data over them. If this macro is defined to 1, functions - * usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if - * you need the interrupt-in endpoints in order to comply to an interface - * (e.g. HID), but never want to send any data. This option saves a couple - * of bytes in flash memory and the transmit buffers in RAM. - */ -#define USB_CFG_INTR_POLL_INTERVAL 100 -/* If you compile a version with endpoint 1 (interrupt-in), this is the poll - * interval. The value is in milliseconds and must not be less than 10 ms for - * low speed devices. - */ -#define USB_CFG_IS_SELF_POWERED 0 -/* Define this to 1 if the device has its own power supply. Set it to 0 if the - * device is powered from the USB bus. - */ -#define USB_CFG_MAX_BUS_POWER 20 -/* Set this variable to the maximum USB bus power consumption of your device. - * The value is in milliamperes. [It will be divided by two since USB - * communicates power requirements in units of 2 mA.] - */ -#define USB_CFG_IMPLEMENT_FN_WRITE 1 -/* Set this to 1 if you want usbFunctionWrite() to be called for control-out - * transfers. Set it to 0 if you don't need it and want to save a couple of - * bytes. - */ -#define USB_CFG_IMPLEMENT_FN_READ 1 -/* Set this to 1 if you need to send control replies which are generated - * "on the fly" when usbFunctionRead() is called. If you only want to send - * data from a static buffer, set it to 0 and return the data from - * usbFunctionSetup(). This saves a couple of bytes. - */ -#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0 -/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints. - * You must implement the function usbFunctionWriteOut() which receives all - * interrupt/bulk data sent to any endpoint other than 0. The endpoint number - * can be found in 'usbRxToken'. - */ -#define USB_CFG_HAVE_FLOWCONTROL 0 -/* Define this to 1 if you want flowcontrol over USB data. See the definition - * of the macros usbDisableAllRequests() and usbEnableAllRequests() in - * usbdrv.h. - */ -#define USB_CFG_LONG_TRANSFERS 0 -/* Define this to 1 if you want to send/receive blocks of more than 254 bytes - * in a single control-in or control-out transfer. Note that the capability - * for long transfers increases the driver size. - */ -/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */ -/* This macro is a hook if you want to do unconventional things. If it is - * defined, it's inserted at the beginning of received message processing. - * If you eat the received message and don't want default processing to - * proceed, do a return after doing your things. One possible application - * (besides debugging) is to flash a status LED on each packet. - */ -/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */ -/* This macro is a hook if you need to know when an USB RESET occurs. It has - * one parameter which distinguishes between the start of RESET state and its - * end. - */ -/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */ -/* This macro (if defined) is executed when a USB SET_ADDRESS request was - * received. - */ -#define USB_COUNT_SOF 0 -/* define this macro to 1 if you need the global variable "usbSofCount" which - * counts SOF packets. This feature requires that the hardware interrupt is - * connected to D- instead of D+. - */ -/* #ifdef __ASSEMBLER__ - * macro myAssemblerMacro - * in YL, TCNT0 - * sts timer0Snapshot, YL - * endm - * #endif - * #define USB_SOF_HOOK myAssemblerMacro - * This macro (if defined) is executed in the assembler module when a - * Start Of Frame condition is detected. It is recommended to define it to - * the name of an assembler macro which is defined here as well so that more - * than one assembler instruction can be used. The macro may use the register - * YL and modify SREG. If it lasts longer than a couple of cycles, USB messages - * immediately after an SOF pulse may be lost and must be retried by the host. - * What can you do with this hook? Since the SOF signal occurs exactly every - * 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in - * designs running on the internal RC oscillator. - * Please note that Start Of Frame detection works only if D- is wired to the - * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES! - */ -#define USB_CFG_CHECK_DATA_TOGGLING 0 -/* define this macro to 1 if you want to filter out duplicate data packets - * sent by the host. Duplicates occur only as a consequence of communication - * errors, when the host does not receive an ACK. Please note that you need to - * implement the filtering yourself in usbFunctionWriteOut() and - * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable - * for each control- and out-endpoint to check for duplicate packets. - */ -#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0 -/* define this macro to 1 if you want the function usbMeasureFrameLength() - * compiled in. This function can be used to calibrate the AVR's RC oscillator. - */ - -/* -------------------------- Device Description --------------------------- */ - -#define USB_CFG_VENDOR_ID 0xc0, 0x16 -/* USB vendor ID for the device, low byte first. If you have registered your - * own Vendor ID, define it here. Otherwise you use one of obdev's free shared - * VID/PID pairs. Be sure to read USBID-License.txt for rules! - */ -#define USB_CFG_DEVICE_ID 0xdf, 0x05 /* obdev's shared PID for HIDs */ -/* This is the ID of the product, low byte first. It is interpreted in the - * scope of the vendor ID. If you have registered your own VID with usb.org - * or if you have licensed a PID from somebody else, define it here. Otherwise - * you use obdev's free shared VID/PID pair. Be sure to read the rules in - * USBID-License.txt! - */ -#define USB_CFG_DEVICE_VERSION 0x00, 0x01 -/* Version number of the device: Minor number first, then major number. - */ -#define USB_CFG_VENDOR_NAME 'o', 'b', 'd', 'e', 'v', '.', 'a', 't' -#define USB_CFG_VENDOR_NAME_LEN 8 -/* These two values define the vendor name returned by the USB device. The name - * must be given as a list of characters under single quotes. The characters - * are interpreted as Unicode (UTF-16) entities. - * If you don't want a vendor name string, undefine these macros. - * ALWAYS define a vendor name containing your Internet domain name if you use - * obdev's free shared VID/PID pair. See the file USBID-License.txt for - * details. - */ -#define USB_CFG_DEVICE_NAME 'D', 'a', 't', 'a', 'S', 't', 'o', 'r', 'e' -#define USB_CFG_DEVICE_NAME_LEN 9 -/* Same as above for the device name. If you don't want a device name, undefine - * the macros. See the file USBID-License.txt before you assign a name if you - * use a shared VID/PID. - */ -/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */ -/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */ -/* Same as above for the serial number. If you don't want a serial number, - * undefine the macros. - * It may be useful to provide the serial number through other means than at - * compile time. See the section about descriptor properties below for how - * to fine tune control over USB descriptors such as the string descriptor - * for the serial number. - */ -#define USB_CFG_DEVICE_CLASS 0 -#define USB_CFG_DEVICE_SUBCLASS 0 -/* See USB specification if you want to conform to an existing device class. - * Class 0xff is "vendor specific". - */ -#define USB_CFG_INTERFACE_CLASS 3 -#define USB_CFG_INTERFACE_SUBCLASS 0 -#define USB_CFG_INTERFACE_PROTOCOL 0 -/* See USB specification if you want to conform to an existing device class or - * protocol. The following classes must be set at interface level: - * HID class is 3, no subclass and protocol required (but may be useful!) - * CDC class is 2, use subclass 2 and protocol 1 for ACM - */ -#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 22 -/* Define this to the length of the HID report descriptor, if you implement - * an HID device. Otherwise don't define it or define it to 0. - * If you use this define, you must add a PROGMEM character array named - * "usbHidReportDescriptor" to your code which contains the report descriptor. - * Don't forget to keep the array and this define in sync! - */ - -/* #define USB_PUBLIC static */ -/* Use the define above if you #include usbdrv.c instead of linking against it. - * This technique saves a couple of bytes in flash memory. - */ - -/* ------------------- Fine Control over USB Descriptors ------------------- */ -/* If you don't want to use the driver's default USB descriptors, you can - * provide our own. These can be provided as (1) fixed length static data in - * flash memory, (2) fixed length static data in RAM or (3) dynamically at - * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more - * information about this function. - * Descriptor handling is configured through the descriptor's properties. If - * no properties are defined or if they are 0, the default descriptor is used. - * Possible properties are: - * + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched - * at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is - * used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if - * you want RAM pointers. - * + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found - * in static memory is in RAM, not in flash memory. - * + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash), - * the driver must know the descriptor's length. The descriptor itself is - * found at the address of a well known identifier (see below). - * List of static descriptor names (must be declared PROGMEM if in flash): - * char usbDescriptorDevice[]; - * char usbDescriptorConfiguration[]; - * char usbDescriptorHidReport[]; - * char usbDescriptorString0[]; - * int usbDescriptorStringVendor[]; - * int usbDescriptorStringDevice[]; - * int usbDescriptorStringSerialNumber[]; - * Other descriptors can't be provided statically, they must be provided - * dynamically at runtime. - * - * Descriptor properties are or-ed or added together, e.g.: - * #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18)) - * - * The following descriptors are defined: - * USB_CFG_DESCR_PROPS_DEVICE - * USB_CFG_DESCR_PROPS_CONFIGURATION - * USB_CFG_DESCR_PROPS_STRINGS - * USB_CFG_DESCR_PROPS_STRING_0 - * USB_CFG_DESCR_PROPS_STRING_VENDOR - * USB_CFG_DESCR_PROPS_STRING_PRODUCT - * USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER - * USB_CFG_DESCR_PROPS_HID - * USB_CFG_DESCR_PROPS_HID_REPORT - * USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver) - * - * Note about string descriptors: String descriptors are not just strings, they - * are Unicode strings prefixed with a 2 byte header. Example: - * int serialNumberDescriptor[] = { - * USB_STRING_DESCRIPTOR_HEADER(6), - * 'S', 'e', 'r', 'i', 'a', 'l' - * }; - */ - -#define USB_CFG_DESCR_PROPS_DEVICE 0 -#define USB_CFG_DESCR_PROPS_CONFIGURATION 0 -#define USB_CFG_DESCR_PROPS_STRINGS 0 -#define USB_CFG_DESCR_PROPS_STRING_0 0 -#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0 -#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0 -#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0 -#define USB_CFG_DESCR_PROPS_HID 0 -#define USB_CFG_DESCR_PROPS_HID_REPORT 0 -#define USB_CFG_DESCR_PROPS_UNKNOWN 0 - -/* ----------------------- Optional MCU Description ------------------------ */ - -/* The following configurations have working defaults in usbdrv.h. You - * usually don't need to set them explicitly. Only if you want to run - * the driver on a device which is not yet supported or with a compiler - * which is not fully supported (such as IAR C) or if you use a differnt - * interrupt than INT0, you may have to define some of these. - */ -/* #define USB_INTR_CFG MCUCR */ -/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */ -/* #define USB_INTR_CFG_CLR 0 */ -/* #define USB_INTR_ENABLE GIMSK */ -/* #define USB_INTR_ENABLE_BIT INT0 */ -/* #define USB_INTR_PENDING GIFR */ -/* #define USB_INTR_PENDING_BIT INTF0 */ -/* #define USB_INTR_VECTOR SIG_INTERRUPT0 */ - -#endif /* __usbconfig_h_included__ */ diff --git a/tools/avrusb/examples/hid-data/firmware/usbdrv/Changelog.txt b/tools/avrusb/examples/hid-data/firmware/usbdrv/Changelog.txt deleted file mode 100644 index c07bca9..0000000 --- a/tools/avrusb/examples/hid-data/firmware/usbdrv/Changelog.txt +++ /dev/null @@ -1,270 +0,0 @@ -This file documents changes in the firmware-only USB driver for atmel's AVR -microcontrollers. New entries are always appended to the end of the file. -Scroll down to the bottom to see the most recent changes. - -2005-04-01: - - Implemented endpoint 1 as interrupt-in endpoint. - - Moved all configuration options to usbconfig.h which is not part of the - driver. - - Changed interface for usbVendorSetup(). - - Fixed compatibility with ATMega8 device. - - Various minor optimizations. - -2005-04-11: - - Changed interface to application: Use usbFunctionSetup(), usbFunctionRead() - and usbFunctionWrite() now. Added configuration options to choose which - of these functions to compile in. - - Assembler module delivers receive data non-inverted now. - - Made register and bit names compatible with more AVR devices. - -2005-05-03: - - Allow address of usbRxBuf on any memory page as long as the buffer does - not cross 256 byte page boundaries. - - Better device compatibility: works with Mega88 now. - - Code optimization in debugging module. - - Documentation updates. - -2006-01-02: - - Added (free) default Vendor- and Product-IDs bought from voti.nl. - - Added USBID-License.txt file which defines the rules for using the free - shared VID/PID pair. - - Added Readme.txt to the usbdrv directory which clarifies administrative - issues. - -2006-01-25: - - Added "configured state" to become more standards compliant. - - Added "HALT" state for interrupt endpoint. - - Driver passes the "USB Command Verifier" test from usb.org now. - - Made "serial number" a configuration option. - - Minor optimizations, we now recommend compiler option "-Os" for best - results. - - Added a version number to usbdrv.h - -2006-02-03: - - New configuration variable USB_BUFFER_SECTION for the memory section where - the USB rx buffer will go. This defaults to ".bss" if not defined. Since - this buffer MUST NOT cross 256 byte pages (not even touch a page at the - end), the user may want to pass a linker option similar to - "-Wl,--section-start=.mybuffer=0x800060". - - Provide structure for usbRequest_t. - - New defines for USB constants. - - Prepared for HID implementations. - - Increased data size limit for interrupt transfers to 8 bytes. - - New macro usbInterruptIsReady() to query interrupt buffer state. - -2006-02-18: - - Ensure that the data token which is sent as an ack to an OUT transfer is - always zero sized. This fixes a bug where the host reports an error after - sending an out transfer to the device, although all data arrived at the - device. - - Updated docs in usbdrv.h to reflect changed API in usbFunctionWrite(). - -* Release 2006-02-20 - - - Give a compiler warning when compiling with debugging turned on. - - Added Oleg Semyonov's changes for IAR-cc compatibility. - - Added new (optional) functions usbDeviceConnect() and usbDeviceDisconnect() - (also thanks to Oleg!). - - Rearranged tests in usbPoll() to save a couple of instructions in the most - likely case that no actions are pending. - - We need a delay between the SET ADDRESS request until the new address - becomes active. This delay was handled in usbPoll() until now. Since the - spec says that the delay must not exceed 2ms, previous versions required - aggressive polling during the enumeration phase. We have now moved the - handling of the delay into the interrupt routine. - - We must not reply with NAK to a SETUP transaction. We can only achieve this - by making sure that the rx buffer is empty when SETUP tokens are expected. - We therefore don't pass zero sized data packets from the status phase of - a transfer to usbPoll(). This change MAY cause troubles if you rely on - receiving a less than 8 bytes long packet in usbFunctionWrite() to - identify the end of a transfer. usbFunctionWrite() will NEVER be called - with a zero length. - -* Release 2006-03-14 - - - Improved IAR C support: tiny memory model, more devices - - Added template usbconfig.h file under the name usbconfig-prototype.h - -* Release 2006-03-26 - - - Added provision for one more interrupt-in endpoint (endpoint 3). - - Added provision for one interrupt-out endpoint (endpoint 1). - - Added flowcontrol macros for USB. - - Added provision for custom configuration descriptor. - - Allow ANY two port bits for D+ and D-. - - Merged (optional) receive endpoint number into global usbRxToken variable. - - Use USB_CFG_IOPORTNAME instead of USB_CFG_IOPORT. We now construct the - variable name from the single port letter instead of computing the address - of related ports from the output-port address. - -* Release 2006-06-26 - - - Updated documentation in usbdrv.h and usbconfig-prototype.h to reflect the - new features. - - Removed "#warning" directives because IAR does not understand them. Use - unused static variables instead to generate a warning. - - Do not include when compiling with IAR. - - Introduced USB_CFG_DESCR_PROPS_* in usbconfig.h to configure how each - USB descriptor should be handled. It is now possible to provide descriptor - data in Flash, RAM or dynamically at runtime. - - STALL is now a status in usbTxLen* instead of a message. We can now conform - to the spec and leave the stall status pending until it is cleared. - - Made usbTxPacketCnt1 and usbTxPacketCnt3 public. This allows the - application code to reset data toggling on interrupt pipes. - -* Release 2006-07-18 - - - Added an #if !defined __ASSEMBLER__ to the warning in usbdrv.h. This fixes - an assembler error. - - usbDeviceDisconnect() takes pull-up resistor to high impedance now. - -* Release 2007-02-01 - - - Merged in some code size improvements from usbtiny (thanks to Dick - Streefland for these optimizations!) - - Special alignment requirement for usbRxBuf not required any more. Thanks - again to Dick Streefland for this hint! - - Reverted to "#warning" instead of unused static variables -- new versions - of IAR CC should handle this directive. - - Changed Open Source license to GNU GPL v2 in order to make linking against - other free libraries easier. We no longer require publication of the - circuit diagrams, but we STRONGLY encourage it. If you improve the driver - itself, PLEASE grant us a royalty free license to your changes for our - commercial license. - -* Release 2007-03-29 - - - New configuration option "USB_PUBLIC" in usbconfig.h. - - Set USB version number to 1.10 instead of 1.01. - - Code used USB_CFG_DESCR_PROPS_STRING_DEVICE and - USB_CFG_DESCR_PROPS_STRING_PRODUCT inconsistently. Changed all occurrences - to USB_CFG_DESCR_PROPS_STRING_PRODUCT. - - New assembler module for 16.5 MHz RC oscillator clock with PLL in receiver - code. - - New assembler module for 16 MHz crystal. - - usbdrvasm.S contains common code only, clock-specific parts have been moved - to usbdrvasm12.S, usbdrvasm16.S and usbdrvasm165.S respectively. - -* Release 2007-06-25 - - - 16 MHz module: Do SE0 check in stuffed bits as well. - -* Release 2007-07-07 - - - Define hi8(x) for IAR compiler to limit result to 8 bits. This is necessary - for negative values. - - Added 15 MHz module contributed by V. Bosch. - - Interrupt vector name can now be configured. This is useful if somebody - wants to use a different hardware interrupt than INT0. - -* Release 2007-08-07 - - - Moved handleIn3 routine in usbdrvasm16.S so that relative jump range is - not exceeded. - - More config options: USB_RX_USER_HOOK(), USB_INITIAL_DATATOKEN, - USB_COUNT_SOF - - USB_INTR_PENDING can now be a memory address, not just I/O - -* Release 2007-09-19 - - - Split out common parts of assembler modules into separate include file - - Made endpoint numbers configurable so that given interface definitions - can be matched. See USB_CFG_EP3_NUMBER in usbconfig-prototype.h. - - Store endpoint number for interrupt/bulk-out so that usbFunctionWriteOut() - can handle any number of endpoints. - - Define usbDeviceConnect() and usbDeviceDisconnect() even if no - USB_CFG_PULLUP_IOPORTNAME is defined. Directly set D+ and D- to 0 in this - case. - -* Release 2007-12-01 - - - Optimize usbDeviceConnect() and usbDeviceDisconnect() for less code size - when USB_CFG_PULLUP_IOPORTNAME is not defined. - -* Release 2007-12-13 - - - Renamed all include-only assembler modules from *.S to *.inc so that - people don't add them to their project sources. - - Distribute leap bits in tx loop more evenly for 16 MHz module. - - Use "macro" and "endm" instead of ".macro" and ".endm" for IAR - - Avoid compiler warnings for constant expr range by casting some values in - USB descriptors. - -* Release 2008-01-21 - - - Fixed bug in 15 and 16 MHz module where the new address set with - SET_ADDRESS was already accepted at the next NAK or ACK we send, not at - the next data packet we send. This caused problems when the host polled - too fast. Thanks to Alexander Neumann for his help and patience debugging - this issue! - -* Release 2008-02-05 - - - Fixed bug in 16.5 MHz module where a register was used in the interrupt - handler before it was pushed. This bug was introduced with version - 2007-09-19 when common parts were moved to a separate file. - - Optimized CRC routine (thanks to Reimar Doeffinger). - -* Release 2008-02-16 - - - Removed outdated IAR compatibility stuff (code sections). - - Added hook macros for USB_RESET_HOOK() and USB_SET_ADDRESS_HOOK(). - - Added optional routine usbMeasureFrameLength() for calibration of the - internal RC oscillator. - -* Release 2008-02-28 - - - USB_INITIAL_DATATOKEN defaults to USBPID_DATA1 now, which means that we - start with sending USBPID_DATA0. - - Changed defaults in usbconfig-prototype.h - - Added free USB VID/PID pair for MIDI class devices - - Restructured AVR-USB as separate package, not part of PowerSwitch any more. - -* Release 2008-04-18 - - - Restructured usbdrv.c so that it is easier to read and understand. - - Better code optimization with gcc 4. - - If a second interrupt in endpoint is enabled, also add it to config - descriptor. - - Added config option for long transfers (above 254 bytes), see - USB_CFG_LONG_TRANSFERS in usbconfig.h. - - Added 20 MHz module contributed by Jeroen Benschop. - -* Release 2008-05-13 - - - Fixed bug in libs-host/hiddata.c function usbhidGetReport(): length - was not incremented, pointer to length was incremented instead. - - Added code to command line tool(s) which claims an interface. This code - is disabled by default, but may be necessary on newer Linux kernels. - - Added usbconfig.h option "USB_CFG_CHECK_DATA_TOGGLING". - - New header "usbportability.h" prepares ports to other development - environments. - - Long transfers (above 254 bytes) did not work when usbFunctionRead() was - used to supply the data. Fixed this bug. [Thanks to Alexander Neumann!] - - In hiddata.c (example code for sending/receiving data over HID), use - USB_RECIP_DEVICE instead of USB_RECIP_INTERFACE for control transfers so - that we need not claim the interface. - - in usbPoll() loop 20 times polling for RESET state instead of 10 times. - This accounts for the higher clock rates we now support. - - Added a module for 12.8 MHz RC oscillator with PLL in receiver loop. - - Added hook to SOF code so that oscillator can be tuned to USB frame clock. - - Added timeout to waitForJ loop. Helps preventing unexpected hangs. - - Added example code for oscillator tuning to libs-device (thanks to - Henrik Haftmann for the idea to this routine). - - Implemented option USB_CFG_SUPPRESS_INTR_CODE. - -* Release 2008-10-22 - - - Fixed libs-device/osctune.h: OSCCAL is memory address on ATMega88 and - similar, not offset of 0x20 needs to be added. - - Allow distribution under GPLv3 for those who have to link against other - code distributed under GPLv3. - -* Release 2008-11-26 - - - Removed libusb-win32 dependency for hid-data example in Makefile.windows. - It was never required and confused many people. - - Added extern uchar usbRxToken to usbdrv.h. - - Integrated a module with CRC checks at 18 MHz by Lukas Schrittwieser. - -* Release 2009-03-23 diff --git a/tools/avrusb/examples/hid-data/firmware/usbdrv/CommercialLicense.txt b/tools/avrusb/examples/hid-data/firmware/usbdrv/CommercialLicense.txt deleted file mode 100644 index 6d8bf39..0000000 --- a/tools/avrusb/examples/hid-data/firmware/usbdrv/CommercialLicense.txt +++ /dev/null @@ -1,156 +0,0 @@ -AVR-USB Driver Software License Agreement -Version 2008-10-07 - -THIS LICENSE AGREEMENT GRANTS YOU CERTAIN RIGHTS IN A SOFTWARE. YOU CAN -ENTER INTO THIS AGREEMENT AND ACQUIRE THE RIGHTS OUTLINED BELOW BY PAYING -THE AMOUNT ACCORDING TO SECTION 4 ("PAYMENT") TO OBJECTIVE DEVELOPMENT. - - -1 DEFINITIONS - -1.1 "OBJECTIVE DEVELOPMENT" shall mean OBJECTIVE DEVELOPMENT Software GmbH, -Grosse Schiffgasse 1A/7, 1020 Wien, AUSTRIA. - -1.2 "You" shall mean the Licensee. - -1.3 "AVR-USB" shall mean all files included in the package distributed under -the name "avrusb" by OBJECTIVE DEVELOPMENT (http://www.obdev.at/avrusb/) -unless otherwise noted. This includes the firmware-only USB device -implementation for Atmel AVR microcontrollers, some simple device examples -and host side software examples and libraries. - - -2 LICENSE GRANTS - -2.1 Source Code. OBJECTIVE DEVELOPMENT shall furnish you with the source -code of AVR-USB. - -2.2 Distribution and Use. OBJECTIVE DEVELOPMENT grants you the -non-exclusive right to use, copy and distribute AVR-USB with your hardware -product(s), restricted by the limitations in section 3 below. - -2.3 Modifications. OBJECTIVE DEVELOPMENT grants you the right to modify -the source code and your copy of AVR-USB according to your needs. - -2.4 USB IDs. OBJECTIVE DEVELOPMENT grants you the exclusive rights to use -USB Product ID(s) sent to you in e-mail after receiving your payment in -conjunction with USB Vendor ID 5824. OBJECTIVE DEVELOPMENT has acquired an -exclusive license for this pair of USB identifiers from Wouter van Ooijen -(www.voti.nl), who has licensed the VID from the USB Implementers Forum, -Inc. (www.usb.org). - - -3 LICENSE RESTRICTIONS - -3.1 Number of Units. Only one of the following three definitions is -applicable. Which one is determined by the amount you pay to OBJECTIVE -DEVELOPMENT, see section 4 ("Payment") below. - -Hobby License: You may use AVR-USB according to section 2 above in no more -than 5 hardware units. These units must not be sold for profit. - -Entry Level License: You may use AVR-USB according to section 2 above in no -more than 150 hardware units. - -Professional License: You may use AVR-USB according to section 2 above in -any number of hardware units, except for large scale production ("unlimited -fair use"). Quantities below 10,000 units are not considered large scale -production. If your reach quantities which are obviously large scale -production, you must pay a license fee of 0.10 EUR per unit for all units -above 10,000. - -3.2 Rental. You may not rent, lease, or lend AVR-USB or otherwise encumber -any copy of AVR-USB, or any of the rights granted herein. - -3.3 Transfer. You may not transfer your rights under this Agreement to -another party without OBJECTIVE DEVELOPMENT's prior written consent. If -such consent is obtained, you may permanently transfer this License to -another party. The recipient of such transfer must agree to all terms and -conditions of this Agreement. - -3.4 Reservation of Rights. OBJECTIVE DEVELOPMENT retains all rights not -expressly granted. - -3.5 Non-Exclusive Rights. Your license rights under this Agreement are -non-exclusive. - -3.6 Third Party Rights. This Agreement cannot grant you rights controlled -by third parties. In particular, you are not allowed to use the USB logo or -other trademarks owned by the USB Implementers Forum, Inc. without their -consent. Since such consent depends on USB certification, it should be -noted that AVR-USB will not pass certification because it does not -implement checksum verification and the microcontroller ports do not meet -the electrical specifications. - - -4 PAYMENT - -The payment amount depends on the variation of this agreement (according to -section 3.1) into which you want to enter. Concrete prices are listed on -OBJECTIVE DEVELOPMENT's web site, usually at -http://www.obdev.at/avrusb/license.html. You agree to pay the amount listed -there to OBJECTIVE DEVELOPMENT or OBJECTIVE DEVELOPMENT's payment processor -or reseller. - - -5 COPYRIGHT AND OWNERSHIP - -AVR-USB is protected by copyright laws and international copyright -treaties, as well as other intellectual property laws and treaties. AVR-USB -is licensed, not sold. - - -6 TERM AND TERMINATION - -6.1 Term. This Agreement shall continue indefinitely. However, OBJECTIVE -DEVELOPMENT may terminate this Agreement and revoke the granted license and -USB-IDs if you fail to comply with any of its terms and conditions. - -6.2 Survival of Terms. All provisions regarding secrecy, confidentiality -and limitation of liability shall survive termination of this agreement. - - -7 DISCLAIMER OF WARRANTY AND LIABILITY - -LIMITED WARRANTY. AVR-USB IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, OBJECTIVE -DEVELOPMENT AND ITS SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES, EITHER -EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND -NON-INFRINGEMENT, WITH REGARD TO AVR-USB, AND THE PROVISION OF OR FAILURE -TO PROVIDE SUPPORT SERVICES. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL -RIGHTS. YOU MAY HAVE OTHERS, WHICH VARY FROM STATE/JURISDICTION TO -STATE/JURISDICTION. - -LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, -IN NO EVENT SHALL OBJECTIVE DEVELOPMENT OR ITS SUPPLIERS BE LIABLE FOR ANY -SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER -(INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, -BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY -LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE AVR-USB OR THE -PROVISION OF OR FAILURE TO PROVIDE SUPPORT SERVICES, EVEN IF OBJECTIVE -DEVELOPMENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY -CASE, OBJECTIVE DEVELOPMENT'S ENTIRE LIABILITY UNDER ANY PROVISION OF THIS -AGREEMENT SHALL BE LIMITED TO THE AMOUNT ACTUALLY PAID BY YOU FOR AVR-USB. - - -8 MISCELLANEOUS TERMS - -8.1 Marketing. OBJECTIVE DEVELOPMENT has the right to mention for marketing -purposes that you entered into this agreement. - -8.2 Entire Agreement. This document represents the entire agreement between -OBJECTIVE DEVELOPMENT and you. It may only be modified in writing signed by -an authorized representative of both, OBJECTIVE DEVELOPMENT and you. - -8.3 Severability. In case a provision of these terms and conditions should -be or become partly or entirely invalid, ineffective, or not executable, -the validity of all other provisions shall not be affected. - -8.4 Applicable Law. This agreement is governed by the laws of the Republic -of Austria. - -8.5 Responsible Courts. The responsible courts in Vienna/Austria will have -exclusive jurisdiction regarding all disputes in connection with this -agreement. - diff --git a/tools/avrusb/examples/hid-data/firmware/usbdrv/License.txt b/tools/avrusb/examples/hid-data/firmware/usbdrv/License.txt deleted file mode 100644 index e9b2752..0000000 --- a/tools/avrusb/examples/hid-data/firmware/usbdrv/License.txt +++ /dev/null @@ -1,361 +0,0 @@ -OBJECTIVE DEVELOPMENT GmbH's AVR-USB driver software is distributed under the -terms and conditions of the GNU GPL version 2 or the GNU GPL version 3. It is -your choice whether you apply the terms of version 2 or version 3. The full -text of GPLv2 is included below. In addition to the requirements in the GPL, -we STRONGLY ENCOURAGE you to do the following: - -(1) Publish your entire project on a web site and drop us a note with the URL. -Use the form at http://www.obdev.at/avrusb/feedback.html for your submission. - -(2) Adhere to minimum publication standards. Please include AT LEAST: - - a circuit diagram in PDF, PNG or GIF format - - full source code for the host software - - a Readme.txt file in ASCII format which describes the purpose of the - project and what can be found in which directories and which files - - a reference to http://www.obdev.at/avrusb/ - -(3) If you improve the driver firmware itself, please give us a free license -to your modifications for our commercial license offerings. - - - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/tools/avrusb/examples/hid-data/firmware/usbdrv/Readme.txt b/tools/avrusb/examples/hid-data/firmware/usbdrv/Readme.txt deleted file mode 100644 index a7aad3e..0000000 --- a/tools/avrusb/examples/hid-data/firmware/usbdrv/Readme.txt +++ /dev/null @@ -1,158 +0,0 @@ -This is the Readme file to Objective Development's firmware-only USB driver -for Atmel AVR microcontrollers. For more information please visit -http://www.obdev.at/avrusb/ - -This directory contains the USB firmware only. Copy it as-is to your own -project and add all .c and .S files to your project (these files are marked -with an asterisk in the list below). Then copy usbconfig-prototype.h as -usbconfig.h to your project and edit it according to your configuration. - - -TECHNICAL DOCUMENTATION -======================= -The technical documentation (API) for the firmware driver is contained in the -file "usbdrv.h". Please read all of it carefully! Configuration options are -documented in "usbconfig-prototype.h". - -The driver consists of the following files: - Readme.txt ............. The file you are currently reading. - Changelog.txt .......... Release notes for all versions of the driver. - usbdrv.h ............... Driver interface definitions and technical docs. -* usbdrv.c ............... High level language part of the driver. Link this - module to your code! -* usbdrvasm.S ............ Assembler part of the driver. This module is mostly - a stub and includes one of the usbdrvasm*.S files - depending on processor clock. Link this module to - your code! - usbdrvasm*.inc ......... Assembler routines for particular clock frequencies. - Included by usbdrvasm.S, don't link it directly! - asmcommon.inc .......... Common assembler routines. Included by - usbdrvasm*.inc, don't link it directly! - usbconfig-prototype.h .. Prototype for your own usbdrv.h file. -* oddebug.c .............. Debug functions. Only used when DEBUG_LEVEL is - defined to a value greater than 0. Link this module - to your code! - oddebug.h .............. Interface definitions of the debug module. - usbportability.h ....... Header with compiler-dependent stuff. - usbdrvasm.asm .......... Compatibility stub for IAR-C-compiler. Use this - module instead of usbdrvasm.S when you assembler - with IAR's tools. - License.txt ............ Open Source license for this driver. - CommercialLicense.txt .. Optional commercial license for this driver. - USBID-License.txt ...... Terms and conditions for using particular USB ID - values for particular purposes. - -(*) ... These files should be linked to your project. - - -CPU CORE CLOCK FREQUENCY -======================== -We supply assembler modules for clock frequencies of 12 MHz, 12.8 MHz, 15 MHz, -16 MHz, 16.5 MHz 18 MHz and 20 MHz. Other clock rates are not supported. The -actual clock rate must be configured in usbdrv.h unless you use the default -12 MHz. - -12 MHz Clock -This is the traditional clock rate of AVR-USB because it's the lowest clock -rate where the timing constraints of the USB spec can be met. - -15 MHz Clock -Similar to 12 MHz, but some NOPs inserted. On the other hand, the higher clock -rate allows for some loops which make the resulting code size somewhat smaller -than the 12 MHz version. - -16 MHz Clock -This clock rate has been added for users of the Arduino board and other -ready-made boards which come with a fixed 16 MHz crystal. It's also an option -if you need the slightly higher clock rate for performance reasons. Since -16 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code -is somewhat tricky and has to insert a leap cycle every third byte. - -12.8 MHz and 16.5 MHz Clock -The assembler modules for these clock rates differ from the other modules -because they have been built for an RC oscillator with only 1% precision. The -receiver code inserts leap cycles to compensate for clock deviations. 1% is -also the precision which can be achieved by calibrating the internal RC -oscillator of the AVR. Please note that only AVRs with internal 64 MHz PLL -oscillator can reach 16.5 MHz with the RC oscillator. This includes the very -popular ATTiny25, ATTiny45, ATTiny85 series as well as the ATTiny26. Almost -all AVRs can reach 12.8 MHz, although this is outside the specified range. - -See the EasyLogger example at http://www.obdev.at/avrusb/easylogger.html for -code which calibrates the RC oscillator based on the USB frame clock. - -18 MHz Clock -This module is closer to the USB specification because it performs an on the -fly CRC check for incoming packets. Packets with invalid checksum are -discarded as required by the spec. If you also implement checks for data -PID toggling on application level (see option USB_CFG_CHECK_DATA_TOGGLING -in usbconfig.h for more info), this ensures data integrity. Due to the CRC -tables and alignment requirements, this code is bigger than modules for other -clock rates. To activate this module, you must define USB_CFG_CHECK_CRC to 1 -and USB_CFG_CLOCK_KHZ to 18000 in usbconfig.h. - -20 MHz Clock -This module is for people who won't do it with less than the maximum. Since -20 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code -uses similar tricks as the 16 MHz module to insert leap cycles. - - -USB IDENTIFIERS -=============== -Every USB device needs a vendor- and a product-identifier (VID and PID). VIDs -are obtained from usb.org for a price of 1,500 USD. Once you have a VID, you -can assign PIDs at will. - -Since an entry level cost of 1,500 USD is too high for most small companies -and hobbyists, we provide some VID/PID pairs for free. See the file -USBID-License.txt for details. - -Objective Development also has some license offerings which include product -IDs. See http://www.obdev.at/avrusb/ for details. - - -DEVELOPMENT SYSTEM -================== -This driver has been developed and optimized for the GNU compiler version 3 -(gcc 3). It does work well with gcc 4, but with bigger code size. We recommend -that you use the GNU compiler suite because it is freely available. AVR-USB -has also been ported to the IAR compiler and assembler. It has been tested -with IAR 4.10B/W32 and 4.12A/W32 on an ATmega8 with the "small" and "tiny" -memory model. Not every release is tested with IAR CC and the driver may -therefore fail to compile with IAR. Please note that gcc is more efficient for -usbdrv.c because this module has been deliberately optimized for gcc. - - -USING AVR-USB FOR FREE -====================== -The AVR firmware driver is published under the GNU General Public License -Version 2 (GPL2) and the GNU General Public License Version 3 (GPL3). It is -your choice whether you apply the terms of version 2 or version 3. - -If you decide for the free GPL2 or GPL3, we STRONGLY ENCOURAGE you to do the -following things IN ADDITION to the obligations from the GPL: - -(1) Publish your entire project on a web site and drop us a note with the URL. -Use the form at http://www.obdev.at/avrusb/feedback.html for your submission. -If you don't have a web site, you can publish the project in obdev's -documentation wiki at -http://www.obdev.at/goto.php?t=avrusb-wiki&p=hosted-projects. - -(2) Adhere to minimum publication standards. Please include AT LEAST: - - a circuit diagram in PDF, PNG or GIF format - - full source code for the host software - - a Readme.txt file in ASCII format which describes the purpose of the - project and what can be found in which directories and which files - - a reference to http://www.obdev.at/avrusb/ - -(3) If you improve the driver firmware itself, please give us a free license -to your modifications for our commercial license offerings. - - -COMMERCIAL LICENSES FOR AVR-USB -=============================== -If you don't want to publish your source code under the terms of the GPL, -you can simply pay money for AVR-USB. As an additional benefit you get -USB PIDs for free, licensed exclusively to you. See the file -"CommercialLicense.txt" for details. - diff --git a/tools/avrusb/examples/hid-data/firmware/usbdrv/USBID-License.txt b/tools/avrusb/examples/hid-data/firmware/usbdrv/USBID-License.txt deleted file mode 100644 index 984c9ee..0000000 --- a/tools/avrusb/examples/hid-data/firmware/usbdrv/USBID-License.txt +++ /dev/null @@ -1,146 +0,0 @@ -Royalty-Free Non-Exclusive License USB Product-ID -================================================= - -Version 2008-04-07 - -OBJECTIVE DEVELOPMENT Software GmbH hereby grants you the non-exclusive -right to use three USB.org vendor-ID (VID) / product-ID (PID) pairs with -products based on Objective Development's firmware-only USB driver for -Atmel AVR microcontrollers: - - * VID = 5824 (=0x16c0) / PID = 1500 (=0x5dc) for devices implementing no - USB device class (vendor-class devices with USB class = 0xff). Devices - using this pair will be referred to as "VENDOR CLASS" devices. - - * VID = 5824 (=0x16c0) / PID = 1503 (=0x5df) for HID class devices - (excluding mice and keyboards). Devices using this pair will be referred - to as "HID CLASS" devices. - - * VID = 5824 (=0x16c0) / PID = 1505 (=0x5e1) for CDC class modem devices - Devices using this pair will be referred to as "CDC-ACM CLASS" devices. - - * VID = 5824 (=0x16c0) / PID = 1508 (=0x5e4) for MIDI class devices - Devices using this pair will be referred to as "MIDI CLASS" devices. - -Since the granted right is non-exclusive, the same VID/PID pairs may be -used by many companies and individuals for different products. To avoid -conflicts, your device and host driver software MUST adhere to the rules -outlined below. - -OBJECTIVE DEVELOPMENT Software GmbH has licensed these VID/PID pairs from -Wouter van Ooijen (see www.voti.nl), who has licensed the VID from the USB -Implementers Forum, Inc. (see www.usb.org). The VID is registered for the -company name "Van Ooijen Technische Informatica". - - -RULES AND RESTRICTIONS -====================== - -(1) The USB device MUST provide a textual representation of the -manufacturer and product identification. The manufacturer identification -MUST be available at least in USB language 0x0409 (English/US). - -(2) The textual manufacturer identification MUST contain either an Internet -domain name (e.g. "mycompany.com") registered and owned by you, or an -e-mail address under your control (e.g. "myname@gmx.net"). You can embed -the domain name or e-mail address in any string you like, e.g. "Objective -Development http://www.obdev.at/avrusb/". - -(3) You are responsible for retaining ownership of the domain or e-mail -address for as long as any of your products are in use. - -(4) You may choose any string for the textual product identification, as -long as this string is unique within the scope of your textual manufacturer -identification. - -(5) Matching of device-specific drivers MUST be based on the textual -manufacturer and product identification in addition to the usual VID/PID -matching. This means that operating system features which are based on -VID/PID matching only (e.g. Windows kernel level drivers, automatic actions -when the device is plugged in etc) MUST NOT be used. The driver matching -MUST be a comparison of the entire strings, NOT a sub-string match. For -CDC-ACM CLASS and MIDI CLASS devices, a generic class driver should be used -and the matching is based on the USB device class. - -(6) The extent to which VID/PID matching is allowed for non device-specific -drivers or features depends on the operating system and particular VID/PID -pair used: - - * Mac OS X, Linux, FreeBSD and other Unixes: No VID/PID matching is - required and hence no VID/PID-only matching is allowed at all. - - * Windows: The operating system performs VID/PID matching for the kernel - level driver. You are REQUIRED to use libusb-win32 (see - http://libusb-win32.sourceforge.net/) as the kernel level driver for - VENDOR CLASS devices. HID CLASS devices all use the generic HID class - driver shipped with Windows, except mice and keyboards. You therefore - MUST NOT use any of the shared VID/PID pairs for mice or keyboards. - CDC-ACM CLASS devices require a ".inf" file which matches on the VID/PID - pair. This ".inf" file MUST load the "usbser" driver to configure the - device as modem (COM-port). - -(7) OBJECTIVE DEVELOPMENT Software GmbH disclaims all liability for any -problems which are caused by the shared use of these VID/PID pairs. You -have been warned that the sharing of VID/PID pairs may cause problems. If -you want to avoid them, get your own VID/PID pair for exclusive use. - - -HOW TO IMPLEMENT THESE RULES -============================ - -The following rules are for VENDOR CLASS and HID CLASS devices. CDC-ACM -CLASS and MIDI CLASS devices use the operating system's class driver and -don't need a custom driver. - -The host driver MUST iterate over all devices with the given VID/PID -numbers in their device descriptors and query the string representation for -the manufacturer name in USB language 0x0409 (English/US). It MUST compare -the ENTIRE string with your textual manufacturer identification chosen in -(2) above. A substring search for your domain or e-mail address is NOT -acceptable. The driver MUST NOT touch the device (other than querying the -descriptors) unless the strings match. - -For all USB devices with matching VID/PID and textual manufacturer -identification, the host driver must query the textual product -identification and string-compare it with the name of the product it can -control. It may only initialize the device if the product matches exactly. - -Objective Development provides examples for these matching rules with the -"PowerSwitch" project (using libusb) and with the "Automator" project -(using Windows calls on Windows and libusb on Unix). - - -Technical Notes: -================ - -Sharing the same VID/PID pair among devices is possible as long as ALL -drivers which match the VID/PID also perform matching on the textual -identification strings. This is easy on all operating systems except -Windows, since Windows establishes a static connection between the VID/PID -pair and a kernel level driver. All devices with the same VID/PID pair must -therefore use THE SAME kernel level driver. - -We therefore demand that you use libusb-win32 for VENDOR CLASS devices. -This is a generic kernel level driver which allows all types of USB access -for user space applications. This is only a partial solution of the -problem, though, because different device drivers may come with different -versions of libusb-win32 and they may not work with the libusb version of -the respective other driver. You are therefore encouraged to test your -driver against a broad range of libusb-win32 versions. Do not use new -features in new versions, or check for their existence before you use them. -When a new libusb-win32 becomes available, make sure that your driver is -compatible with it. - -For HID CLASS devices it is necessary that all those devices bind to the -same kernel driver: Microsoft's generic USB HID driver. This is true for -all HID devices except those with a specialized driver. Currently, the only -HIDs with specialized drivers are mice and keyboards. You therefore MUST -NOT use a shared VID/PID with mouse and keyboard devices. - -Sharing the same VID/PID among different products is unusual and probably -violates the USB specification. If you do it, you do it at your own risk. - -To avoid possible incompatibilities, we highly recommend that you get your -own VID/PID pair if you intend to sell your product. Objective -Development's commercial licenses for AVR-USB include a PID for -unrestricted exclusive use. diff --git a/tools/avrusb/examples/hid-data/firmware/usbdrv/asmcommon.inc b/tools/avrusb/examples/hid-data/firmware/usbdrv/asmcommon.inc deleted file mode 100644 index 457de3b..0000000 --- a/tools/avrusb/examples/hid-data/firmware/usbdrv/asmcommon.inc +++ /dev/null @@ -1,188 +0,0 @@ -/* Name: asmcommon.inc - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2007-11-05 - * Tabsize: 4 - * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * Revision: $Id$ - */ - -/* Do not link this file! Link usbdrvasm.S instead, which includes the - * appropriate implementation! - */ - -/* -General Description: -This file contains assembler code which is shared among the USB driver -implementations for different CPU cocks. Since the code must be inserted -in the middle of the module, it's split out into this file and #included. - -Jump destinations called from outside: - sofError: Called when no start sequence was found. - se0: Called when a package has been successfully received. - overflow: Called when receive buffer overflows. - doReturn: Called after sending data. - -Outside jump destinations used by this module: - waitForJ: Called to receive an already arriving packet. - sendAckAndReti: - sendNakAndReti: - sendCntAndReti: - usbSendAndReti: - -The following macros must be defined before this file is included: - .macro POP_STANDARD - .endm - .macro POP_RETI - .endm -*/ - -#define token x1 - -overflow: - ldi x2, 1< 0 - -#warning "Never compile production devices with debugging enabled" - -static void uartPutc(char c) -{ - while(!(ODDBG_USR & (1 << ODDBG_UDRE))); /* wait for data register empty */ - ODDBG_UDR = c; -} - -static uchar hexAscii(uchar h) -{ - h &= 0xf; - if(h >= 10) - h += 'a' - (uchar)10 - '0'; - h += '0'; - return h; -} - -static void printHex(uchar c) -{ - uartPutc(hexAscii(c >> 4)); - uartPutc(hexAscii(c)); -} - -void odDebug(uchar prefix, uchar *data, uchar len) -{ - printHex(prefix); - uartPutc(':'); - while(len--){ - uartPutc(' '); - printHex(*data++); - } - uartPutc('\r'); - uartPutc('\n'); -} - -#endif diff --git a/tools/avrusb/examples/hid-data/firmware/usbdrv/oddebug.h b/tools/avrusb/examples/hid-data/firmware/usbdrv/oddebug.h deleted file mode 100644 index d61309d..0000000 --- a/tools/avrusb/examples/hid-data/firmware/usbdrv/oddebug.h +++ /dev/null @@ -1,123 +0,0 @@ -/* Name: oddebug.h - * Project: AVR library - * Author: Christian Starkjohann - * Creation Date: 2005-01-16 - * Tabsize: 4 - * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: oddebug.h 692 2008-11-07 15:07:40Z cs $ - */ - -#ifndef __oddebug_h_included__ -#define __oddebug_h_included__ - -/* -General Description: -This module implements a function for debug logs on the serial line of the -AVR microcontroller. Debugging can be configured with the define -'DEBUG_LEVEL'. If this macro is not defined or defined to 0, all debugging -calls are no-ops. If it is 1, DBG1 logs will appear, but not DBG2. If it is -2, DBG1 and DBG2 logs will be printed. - -A debug log consists of a label ('prefix') to indicate which debug log created -the output and a memory block to dump in hex ('data' and 'len'). -*/ - - -#ifndef F_CPU -# define F_CPU 12000000 /* 12 MHz */ -#endif - -/* make sure we have the UART defines: */ -#include "usbportability.h" - -#ifndef uchar -# define uchar unsigned char -#endif - -#if DEBUG_LEVEL > 0 && !(defined TXEN || defined TXEN0) /* no UART in device */ -# warning "Debugging disabled because device has no UART" -# undef DEBUG_LEVEL -#endif - -#ifndef DEBUG_LEVEL -# define DEBUG_LEVEL 0 -#endif - -/* ------------------------------------------------------------------------- */ - -#if DEBUG_LEVEL > 0 -# define DBG1(prefix, data, len) odDebug(prefix, data, len) -#else -# define DBG1(prefix, data, len) -#endif - -#if DEBUG_LEVEL > 1 -# define DBG2(prefix, data, len) odDebug(prefix, data, len) -#else -# define DBG2(prefix, data, len) -#endif - -/* ------------------------------------------------------------------------- */ - -#if DEBUG_LEVEL > 0 -extern void odDebug(uchar prefix, uchar *data, uchar len); - -/* Try to find our control registers; ATMEL likes to rename these */ - -#if defined UBRR -# define ODDBG_UBRR UBRR -#elif defined UBRRL -# define ODDBG_UBRR UBRRL -#elif defined UBRR0 -# define ODDBG_UBRR UBRR0 -#elif defined UBRR0L -# define ODDBG_UBRR UBRR0L -#endif - -#if defined UCR -# define ODDBG_UCR UCR -#elif defined UCSRB -# define ODDBG_UCR UCSRB -#elif defined UCSR0B -# define ODDBG_UCR UCSR0B -#endif - -#if defined TXEN -# define ODDBG_TXEN TXEN -#else -# define ODDBG_TXEN TXEN0 -#endif - -#if defined USR -# define ODDBG_USR USR -#elif defined UCSRA -# define ODDBG_USR UCSRA -#elif defined UCSR0A -# define ODDBG_USR UCSR0A -#endif - -#if defined UDRE -# define ODDBG_UDRE UDRE -#else -# define ODDBG_UDRE UDRE0 -#endif - -#if defined UDR -# define ODDBG_UDR UDR -#elif defined UDR0 -# define ODDBG_UDR UDR0 -#endif - -static inline void odDebugInit(void) -{ - ODDBG_UCR |= (1<len & 0x10){ /* packet buffer was empty */ - txStatus->buffer[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* toggle token */ - }else{ - txStatus->len = USBPID_NAK; /* avoid sending outdated (overwritten) interrupt data */ - } - p = txStatus->buffer + 1; - i = len; - do{ /* if len == 0, we still copy 1 byte, but that's no problem */ - *p++ = *data++; - }while(--i > 0); /* loop control at the end is 2 bytes shorter than at beginning */ - usbCrc16Append(&txStatus->buffer[1], len); - txStatus->len = len + 4; /* len must be given including sync byte */ - DBG2(0x21 + (((int)txStatus >> 3) & 3), txStatus->buffer, len + 3); -} - -USB_PUBLIC void usbSetInterrupt(uchar *data, uchar len) -{ - usbGenericSetInterrupt(data, len, &usbTxStatus1); -} -#endif - -#if USB_CFG_HAVE_INTRIN_ENDPOINT3 -USB_PUBLIC void usbSetInterrupt3(uchar *data, uchar len) -{ - usbGenericSetInterrupt(data, len, &usbTxStatus3); -} -#endif -#endif /* USB_CFG_SUPPRESS_INTR_CODE */ - -/* ------------------ utilities for code following below ------------------- */ - -/* Use defines for the switch statement so that we can choose between an - * if()else if() and a switch/case based implementation. switch() is more - * efficient for a LARGE set of sequential choices, if() is better in all other - * cases. - */ -#if USB_CFG_USE_SWITCH_STATEMENT -# define SWITCH_START(cmd) switch(cmd){{ -# define SWITCH_CASE(value) }break; case (value):{ -# define SWITCH_CASE2(v1,v2) }break; case (v1): case(v2):{ -# define SWITCH_CASE3(v1,v2,v3) }break; case (v1): case(v2): case(v3):{ -# define SWITCH_DEFAULT }break; default:{ -# define SWITCH_END }} -#else -# define SWITCH_START(cmd) {uchar _cmd = cmd; if(0){ -# define SWITCH_CASE(value) }else if(_cmd == (value)){ -# define SWITCH_CASE2(v1,v2) }else if(_cmd == (v1) || _cmd == (v2)){ -# define SWITCH_CASE3(v1,v2,v3) }else if(_cmd == (v1) || _cmd == (v2) || (_cmd == v3)){ -# define SWITCH_DEFAULT }else{ -# define SWITCH_END }} -#endif - -#ifndef USB_RX_USER_HOOK -#define USB_RX_USER_HOOK(data, len) -#endif -#ifndef USB_SET_ADDRESS_HOOK -#define USB_SET_ADDRESS_HOOK() -#endif - -/* ------------------------------------------------------------------------- */ - -/* We use if() instead of #if in the macro below because #if can't be used - * in macros and the compiler optimizes constant conditions anyway. - * This may cause problems with undefined symbols if compiled without - * optimizing! - */ -#define GET_DESCRIPTOR(cfgProp, staticName) \ - if(cfgProp){ \ - if((cfgProp) & USB_PROP_IS_RAM) \ - flags = 0; \ - if((cfgProp) & USB_PROP_IS_DYNAMIC){ \ - len = usbFunctionDescriptor(rq); \ - }else{ \ - len = USB_PROP_LENGTH(cfgProp); \ - usbMsgPtr = (uchar *)(staticName); \ - } \ - } - -/* usbDriverDescriptor() is similar to usbFunctionDescriptor(), but used - * internally for all types of descriptors. - */ -static inline usbMsgLen_t usbDriverDescriptor(usbRequest_t *rq) -{ -usbMsgLen_t len = 0; -uchar flags = USB_FLG_MSGPTR_IS_ROM; - - SWITCH_START(rq->wValue.bytes[1]) - SWITCH_CASE(USBDESCR_DEVICE) /* 1 */ - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_DEVICE, usbDescriptorDevice) - SWITCH_CASE(USBDESCR_CONFIG) /* 2 */ - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_CONFIGURATION, usbDescriptorConfiguration) - SWITCH_CASE(USBDESCR_STRING) /* 3 */ -#if USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC - if(USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_RAM) - flags = 0; - len = usbFunctionDescriptor(rq); -#else /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */ - SWITCH_START(rq->wValue.bytes[0]) - SWITCH_CASE(0) - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_0, usbDescriptorString0) - SWITCH_CASE(1) - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_VENDOR, usbDescriptorStringVendor) - SWITCH_CASE(2) - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_PRODUCT, usbDescriptorStringDevice) - SWITCH_CASE(3) - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER, usbDescriptorStringSerialNumber) - SWITCH_DEFAULT - if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){ - len = usbFunctionDescriptor(rq); - } - SWITCH_END -#endif /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */ -#if USB_CFG_DESCR_PROPS_HID_REPORT /* only support HID descriptors if enabled */ - SWITCH_CASE(USBDESCR_HID) /* 0x21 */ - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID, usbDescriptorConfiguration + 18) - SWITCH_CASE(USBDESCR_HID_REPORT)/* 0x22 */ - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID_REPORT, usbDescriptorHidReport) -#endif - SWITCH_DEFAULT - if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){ - len = usbFunctionDescriptor(rq); - } - SWITCH_END - usbMsgFlags = flags; - return len; -} - -/* ------------------------------------------------------------------------- */ - -/* usbDriverSetup() is similar to usbFunctionSetup(), but it's used for - * standard requests instead of class and custom requests. - */ -static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq) -{ -uchar len = 0, *dataPtr = usbTxBuf + 9; /* there are 2 bytes free space at the end of the buffer */ -uchar value = rq->wValue.bytes[0]; -#if USB_CFG_IMPLEMENT_HALT -uchar index = rq->wIndex.bytes[0]; -#endif - - dataPtr[0] = 0; /* default reply common to USBRQ_GET_STATUS and USBRQ_GET_INTERFACE */ - SWITCH_START(rq->bRequest) - SWITCH_CASE(USBRQ_GET_STATUS) /* 0 */ - uchar recipient = rq->bmRequestType & USBRQ_RCPT_MASK; /* assign arith ops to variables to enforce byte size */ - if(USB_CFG_IS_SELF_POWERED && recipient == USBRQ_RCPT_DEVICE) - dataPtr[0] = USB_CFG_IS_SELF_POWERED; -#if USB_CFG_IMPLEMENT_HALT - if(recipient == USBRQ_RCPT_ENDPOINT && index == 0x81) /* request status for endpoint 1 */ - dataPtr[0] = usbTxLen1 == USBPID_STALL; -#endif - dataPtr[1] = 0; - len = 2; -#if USB_CFG_IMPLEMENT_HALT - SWITCH_CASE2(USBRQ_CLEAR_FEATURE, USBRQ_SET_FEATURE) /* 1, 3 */ - if(value == 0 && index == 0x81){ /* feature 0 == HALT for endpoint == 1 */ - usbTxLen1 = rq->bRequest == USBRQ_CLEAR_FEATURE ? USBPID_NAK : USBPID_STALL; - usbResetDataToggling(); - } -#endif - SWITCH_CASE(USBRQ_SET_ADDRESS) /* 5 */ - usbNewDeviceAddr = value; - USB_SET_ADDRESS_HOOK(); - SWITCH_CASE(USBRQ_GET_DESCRIPTOR) /* 6 */ - len = usbDriverDescriptor(rq); - goto skipMsgPtrAssignment; - SWITCH_CASE(USBRQ_GET_CONFIGURATION) /* 8 */ - dataPtr = &usbConfiguration; /* send current configuration value */ - len = 1; - SWITCH_CASE(USBRQ_SET_CONFIGURATION) /* 9 */ - usbConfiguration = value; - usbResetStall(); - SWITCH_CASE(USBRQ_GET_INTERFACE) /* 10 */ - len = 1; -#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE - SWITCH_CASE(USBRQ_SET_INTERFACE) /* 11 */ - usbResetDataToggling(); - usbResetStall(); -#endif - SWITCH_DEFAULT /* 7=SET_DESCRIPTOR, 12=SYNC_FRAME */ - /* Should we add an optional hook here? */ - SWITCH_END - usbMsgPtr = dataPtr; -skipMsgPtrAssignment: - return len; -} - -/* ------------------------------------------------------------------------- */ - -/* usbProcessRx() is called for every message received by the interrupt - * routine. It distinguishes between SETUP and DATA packets and processes - * them accordingly. - */ -static inline void usbProcessRx(uchar *data, uchar len) -{ -usbRequest_t *rq = (void *)data; - -/* usbRxToken can be: - * 0x2d 00101101 (USBPID_SETUP for setup data) - * 0xe1 11100001 (USBPID_OUT: data phase of setup transfer) - * 0...0x0f for OUT on endpoint X - */ - DBG2(0x10 + (usbRxToken & 0xf), data, len + 2); /* SETUP=1d, SETUP-DATA=11, OUTx=1x */ - USB_RX_USER_HOOK(data, len) -#if USB_CFG_IMPLEMENT_FN_WRITEOUT - if(usbRxToken < 0x10){ /* OUT to endpoint != 0: endpoint number in usbRxToken */ - usbFunctionWriteOut(data, len); - return; - } -#endif - if(usbRxToken == (uchar)USBPID_SETUP){ - if(len != 8) /* Setup size must be always 8 bytes. Ignore otherwise. */ - return; - usbMsgLen_t replyLen; - usbTxBuf[0] = USBPID_DATA0; /* initialize data toggling */ - usbTxLen = USBPID_NAK; /* abort pending transmit */ - usbMsgFlags = 0; - uchar type = rq->bmRequestType & USBRQ_TYPE_MASK; - if(type != USBRQ_TYPE_STANDARD){ /* standard requests are handled by driver */ - replyLen = usbFunctionSetup(data); - }else{ - replyLen = usbDriverSetup(rq); - } -#if USB_CFG_IMPLEMENT_FN_READ || USB_CFG_IMPLEMENT_FN_WRITE - if(replyLen == USB_NO_MSG){ /* use user-supplied read/write function */ - /* do some conditioning on replyLen, but on IN transfers only */ - if((rq->bmRequestType & USBRQ_DIR_MASK) != USBRQ_DIR_HOST_TO_DEVICE){ - if(sizeof(replyLen) < sizeof(rq->wLength.word)){ /* help compiler with optimizing */ - replyLen = rq->wLength.bytes[0]; - }else{ - replyLen = rq->wLength.word; - } - } - usbMsgFlags = USB_FLG_USE_USER_RW; - }else /* The 'else' prevents that we limit a replyLen of USB_NO_MSG to the maximum transfer len. */ -#endif - if(sizeof(replyLen) < sizeof(rq->wLength.word)){ /* help compiler with optimizing */ - if(!rq->wLength.bytes[1] && replyLen > rq->wLength.bytes[0]) /* limit length to max */ - replyLen = rq->wLength.bytes[0]; - }else{ - if(replyLen > rq->wLength.word) /* limit length to max */ - replyLen = rq->wLength.word; - } - usbMsgLen = replyLen; - }else{ /* usbRxToken must be USBPID_OUT, which means data phase of setup (control-out) */ -#if USB_CFG_IMPLEMENT_FN_WRITE - if(usbMsgFlags & USB_FLG_USE_USER_RW){ - uchar rval = usbFunctionWrite(data, len); - if(rval == 0xff){ /* an error occurred */ - usbTxLen = USBPID_STALL; - }else if(rval != 0){ /* This was the final package */ - usbMsgLen = 0; /* answer with a zero-sized data packet */ - } - } -#endif - } -} - -/* ------------------------------------------------------------------------- */ - -/* This function is similar to usbFunctionRead(), but it's also called for - * data handled automatically by the driver (e.g. descriptor reads). - */ -static uchar usbDeviceRead(uchar *data, uchar len) -{ - if(len > 0){ /* don't bother app with 0 sized reads */ -#if USB_CFG_IMPLEMENT_FN_READ - if(usbMsgFlags & USB_FLG_USE_USER_RW){ - len = usbFunctionRead(data, len); - }else -#endif - { - uchar i = len, *r = usbMsgPtr; - if(usbMsgFlags & USB_FLG_MSGPTR_IS_ROM){ /* ROM data */ - do{ - uchar c = USB_READ_FLASH(r); /* assign to char size variable to enforce byte ops */ - *data++ = c; - r++; - }while(--i); - }else{ /* RAM data */ - do{ - *data++ = *r++; - }while(--i); - } - usbMsgPtr = r; - } - } - return len; -} - -/* ------------------------------------------------------------------------- */ - -/* usbBuildTxBlock() is called when we have data to transmit and the - * interrupt routine's transmit buffer is empty. - */ -static inline void usbBuildTxBlock(void) -{ -usbMsgLen_t wantLen; -uchar len; - - wantLen = usbMsgLen; - if(wantLen > 8) - wantLen = 8; - usbMsgLen -= wantLen; - usbTxBuf[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* DATA toggling */ - len = usbDeviceRead(usbTxBuf + 1, wantLen); - if(len <= 8){ /* valid data packet */ - usbCrc16Append(&usbTxBuf[1], len); - len += 4; /* length including sync byte */ - if(len < 12) /* a partial package identifies end of message */ - usbMsgLen = USB_NO_MSG; - }else{ - len = USBPID_STALL; /* stall the endpoint */ - usbMsgLen = USB_NO_MSG; - } - usbTxLen = len; - DBG2(0x20, usbTxBuf, len-1); -} - -/* ------------------------------------------------------------------------- */ - -static inline void usbHandleResetHook(uchar notResetState) -{ -#ifdef USB_RESET_HOOK -static uchar wasReset; -uchar isReset = !notResetState; - - if(wasReset != isReset){ - USB_RESET_HOOK(isReset); - wasReset = isReset; - } -#endif -} - -/* ------------------------------------------------------------------------- */ - -USB_PUBLIC void usbPoll(void) -{ -schar len; -uchar i; - - len = usbRxLen - 3; - if(len >= 0){ -/* We could check CRC16 here -- but ACK has already been sent anyway. If you - * need data integrity checks with this driver, check the CRC in your app - * code and report errors back to the host. Since the ACK was already sent, - * retries must be handled on application level. - * unsigned crc = usbCrc16(buffer + 1, usbRxLen - 3); - */ - usbProcessRx(usbRxBuf + USB_BUFSIZE + 1 - usbInputBufOffset, len); -#if USB_CFG_HAVE_FLOWCONTROL - if(usbRxLen > 0) /* only mark as available if not inactivated */ - usbRxLen = 0; -#else - usbRxLen = 0; /* mark rx buffer as available */ -#endif - } - if(usbTxLen & 0x10){ /* transmit system idle */ - if(usbMsgLen != USB_NO_MSG){ /* transmit data pending? */ - usbBuildTxBlock(); - } - } - for(i = 20; i > 0; i--){ - uchar usbLineStatus = USBIN & USBMASK; - if(usbLineStatus != 0) /* SE0 has ended */ - goto isNotReset; - } - /* RESET condition, called multiple times during reset */ - usbNewDeviceAddr = 0; - usbDeviceAddr = 0; - usbResetStall(); - DBG1(0xff, 0, 0); -isNotReset: - usbHandleResetHook(i); -} - -/* ------------------------------------------------------------------------- */ - -USB_PUBLIC void usbInit(void) -{ -#if USB_INTR_CFG_SET != 0 - USB_INTR_CFG |= USB_INTR_CFG_SET; -#endif -#if USB_INTR_CFG_CLR != 0 - USB_INTR_CFG &= ~(USB_INTR_CFG_CLR); -#endif - USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT); - usbResetDataToggling(); -#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE - usbTxLen1 = USBPID_NAK; -#if USB_CFG_HAVE_INTRIN_ENDPOINT3 - usbTxLen3 = USBPID_NAK; -#endif -#endif -} - -/* ------------------------------------------------------------------------- */ diff --git a/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrv.h b/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrv.h deleted file mode 100644 index c5cefe9..0000000 --- a/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrv.h +++ /dev/null @@ -1,733 +0,0 @@ -/* Name: usbdrv.h - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2004-12-29 - * Tabsize: 4 - * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: usbdrv.h 738 2009-03-23 11:13:24Z cs $ - */ - -#ifndef __usbdrv_h_included__ -#define __usbdrv_h_included__ -#include "usbconfig.h" -#include "usbportability.h" - -/* -Hardware Prerequisites: -======================= -USB lines D+ and D- MUST be wired to the same I/O port. We recommend that D+ -triggers the interrupt (best achieved by using INT0 for D+), but it is also -possible to trigger the interrupt from D-. If D- is used, interrupts are also -triggered by SOF packets. D- requires a pull-up of 1.5k to +3.5V (and the -device must be powered at 3.5V) to identify as low-speed USB device. A -pull-down or pull-up of 1M SHOULD be connected from D+ to +3.5V to prevent -interference when no USB master is connected. If you use Zener diodes to limit -the voltage on D+ and D-, you MUST use a pull-down resistor, not a pull-up. -We use D+ as interrupt source and not D- because it does not trigger on -keep-alive and RESET states. If you want to count keep-alive events with -USB_COUNT_SOF, you MUST use D- as an interrupt source. - -As a compile time option, the 1.5k pull-up resistor on D- can be made -switchable to allow the device to disconnect at will. See the definition of -usbDeviceConnect() and usbDeviceDisconnect() further down in this file. - -Please adapt the values in usbconfig.h according to your hardware! - -The device MUST be clocked at exactly 12 MHz, 15 MHz, 16 MHz or 20 MHz -or at 12.8 MHz resp. 16.5 MHz +/- 1%. See usbconfig-prototype.h for details. - - -Limitations: -============ -Robustness with respect to communication errors: -The driver assumes error-free communication. It DOES check for errors in -the PID, but does NOT check bit stuffing errors, SE0 in middle of a byte, -token CRC (5 bit) and data CRC (16 bit). CRC checks can not be performed due -to timing constraints: We must start sending a reply within 7 bit times. -Bit stuffing and misplaced SE0 would have to be checked in real-time, but CPU -performance does not permit that. The driver does not check Data0/Data1 -toggling, but application software can implement the check. - -Input characteristics: -Since no differential receiver circuit is used, electrical interference -robustness may suffer. The driver samples only one of the data lines with -an ordinary I/O pin's input characteristics. However, since this is only a -low speed USB implementation and the specification allows for 8 times the -bit rate over the same hardware, we should be on the safe side. Even the spec -requires detection of asymmetric states at high bit rate for SE0 detection. - -Number of endpoints: -The driver supports the following endpoints: - -- Endpoint 0, the default control endpoint. -- Any number of interrupt- or bulk-out endpoints. The data is sent to - usbFunctionWriteOut() and USB_CFG_IMPLEMENT_FN_WRITEOUT must be defined - to 1 to activate this feature. The endpoint number can be found in the - global variable 'usbRxToken'. -- One default interrupt- or bulk-in endpoint. This endpoint is used for - interrupt- or bulk-in transfers which are not handled by any other endpoint. - You must define USB_CFG_HAVE_INTRIN_ENDPOINT in order to activate this - feature and call usbSetInterrupt() to send interrupt/bulk data. -- One additional interrupt- or bulk-in endpoint. This was endpoint 3 in - previous versions of this driver but can now be configured to any endpoint - number. You must define USB_CFG_HAVE_INTRIN_ENDPOINT3 in order to activate - this feature and call usbSetInterrupt3() to send interrupt/bulk data. The - endpoint number can be set with USB_CFG_EP3_NUMBER. - -Please note that the USB standard forbids bulk endpoints for low speed devices! -Most operating systems allow them anyway, but the AVR will spend 90% of the CPU -time in the USB interrupt polling for bulk data. - -Maximum data payload: -Data payload of control in and out transfers may be up to 254 bytes. In order -to accept payload data of out transfers, you need to implement -'usbFunctionWrite()'. - -USB Suspend Mode supply current: -The USB standard limits power consumption to 500uA when the bus is in suspend -mode. This is not a problem for self-powered devices since they don't need -bus power anyway. Bus-powered devices can achieve this only by putting the -CPU in sleep mode. The driver does not implement suspend handling by itself. -However, the application may implement activity monitoring and wakeup from -sleep. The host sends regular SE0 states on the bus to keep it active. These -SE0 states can be detected by using D- as the interrupt source. Define -USB_COUNT_SOF to 1 and use the global variable usbSofCount to check for bus -activity. - -Operation without an USB master: -The driver behaves neutral without connection to an USB master if D- reads -as 1. To avoid spurious interrupts, we recommend a high impedance (e.g. 1M) -pull-down or pull-up resistor on D+ (interrupt). If Zener diodes are used, -use a pull-down. If D- becomes statically 0, the driver may block in the -interrupt routine. - -Interrupt latency: -The application must ensure that the USB interrupt is not disabled for more -than 25 cycles (this is for 12 MHz, faster clocks allow longer latency). -This implies that all interrupt routines must either be declared as "INTERRUPT" -instead of "SIGNAL" (see "avr/signal.h") or that they are written in assembler -with "sei" as the first instruction. - -Maximum interrupt duration / CPU cycle consumption: -The driver handles all USB communication during the interrupt service -routine. The routine will not return before an entire USB message is received -and the reply is sent. This may be up to ca. 1200 cycles @ 12 MHz (= 100us) if -the host conforms to the standard. The driver will consume CPU cycles for all -USB messages, even if they address another (low-speed) device on the same bus. - -*/ - -/* ------------------------------------------------------------------------- */ -/* --------------------------- Module Interface ---------------------------- */ -/* ------------------------------------------------------------------------- */ - -#define USBDRV_VERSION 20090323 -/* This define uniquely identifies a driver version. It is a decimal number - * constructed from the driver's release date in the form YYYYMMDD. If the - * driver's behavior or interface changes, you can use this constant to - * distinguish versions. If it is not defined, the driver's release date is - * older than 2006-01-25. - */ - - -#ifndef USB_PUBLIC -#define USB_PUBLIC -#endif -/* USB_PUBLIC is used as declaration attribute for all functions exported by - * the USB driver. The default is no attribute (see above). You may define it - * to static either in usbconfig.h or from the command line if you include - * usbdrv.c instead of linking against it. Including the C module of the driver - * directly in your code saves a couple of bytes in flash memory. - */ - -#ifndef __ASSEMBLER__ -#ifndef uchar -#define uchar unsigned char -#endif -#ifndef schar -#define schar signed char -#endif -/* shortcuts for well defined 8 bit integer types */ - -#if USB_CFG_LONG_TRANSFERS /* if more than 254 bytes transfer size required */ -# define usbMsgLen_t unsigned -#else -# define usbMsgLen_t uchar -#endif -/* usbMsgLen_t is the data type used for transfer lengths. By default, it is - * defined to uchar, allowing a maximum of 254 bytes (255 is reserved for - * USB_NO_MSG below). If the usbconfig.h defines USB_CFG_LONG_TRANSFERS to 1, - * a 16 bit data type is used, allowing up to 16384 bytes (the rest is used - * for flags in the descriptor configuration). - */ -#define USB_NO_MSG ((usbMsgLen_t)-1) /* constant meaning "no message" */ - -struct usbRequest; /* forward declaration */ - -USB_PUBLIC void usbInit(void); -/* This function must be called before interrupts are enabled and the main - * loop is entered. - */ -USB_PUBLIC void usbPoll(void); -/* This function must be called at regular intervals from the main loop. - * Maximum delay between calls is somewhat less than 50ms (USB timeout for - * accepting a Setup message). Otherwise the device will not be recognized. - * Please note that debug outputs through the UART take ~ 0.5ms per byte - * at 19200 bps. - */ -extern uchar *usbMsgPtr; -/* This variable may be used to pass transmit data to the driver from the - * implementation of usbFunctionWrite(). It is also used internally by the - * driver for standard control requests. - */ -USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]); -/* This function is called when the driver receives a SETUP transaction from - * the host which is not answered by the driver itself (in practice: class and - * vendor requests). All control transfers start with a SETUP transaction where - * the host communicates the parameters of the following (optional) data - * transfer. The SETUP data is available in the 'data' parameter which can - * (and should) be casted to 'usbRequest_t *' for a more user-friendly access - * to parameters. - * - * If the SETUP indicates a control-in transfer, you should provide the - * requested data to the driver. There are two ways to transfer this data: - * (1) Set the global pointer 'usbMsgPtr' to the base of the static RAM data - * block and return the length of the data in 'usbFunctionSetup()'. The driver - * will handle the rest. Or (2) return USB_NO_MSG in 'usbFunctionSetup()'. The - * driver will then call 'usbFunctionRead()' when data is needed. See the - * documentation for usbFunctionRead() for details. - * - * If the SETUP indicates a control-out transfer, the only way to receive the - * data from the host is through the 'usbFunctionWrite()' call. If you - * implement this function, you must return USB_NO_MSG in 'usbFunctionSetup()' - * to indicate that 'usbFunctionWrite()' should be used. See the documentation - * of this function for more information. If you just want to ignore the data - * sent by the host, return 0 in 'usbFunctionSetup()'. - * - * Note that calls to the functions usbFunctionRead() and usbFunctionWrite() - * are only done if enabled by the configuration in usbconfig.h. - */ -USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq); -/* You need to implement this function ONLY if you provide USB descriptors at - * runtime (which is an expert feature). It is very similar to - * usbFunctionSetup() above, but it is called only to request USB descriptor - * data. See the documentation of usbFunctionSetup() above for more info. - */ -#if USB_CFG_HAVE_INTRIN_ENDPOINT -USB_PUBLIC void usbSetInterrupt(uchar *data, uchar len); -/* This function sets the message which will be sent during the next interrupt - * IN transfer. The message is copied to an internal buffer and must not exceed - * a length of 8 bytes. The message may be 0 bytes long just to indicate the - * interrupt status to the host. - * If you need to transfer more bytes, use a control read after the interrupt. - */ -#define usbInterruptIsReady() (usbTxLen1 & 0x10) -/* This macro indicates whether the last interrupt message has already been - * sent. If you set a new interrupt message before the old was sent, the - * message already buffered will be lost. - */ -#if USB_CFG_HAVE_INTRIN_ENDPOINT3 -USB_PUBLIC void usbSetInterrupt3(uchar *data, uchar len); -#define usbInterruptIsReady3() (usbTxLen3 & 0x10) -/* Same as above for endpoint 3 */ -#endif -#endif /* USB_CFG_HAVE_INTRIN_ENDPOINT */ -#if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH /* simplified interface for backward compatibility */ -#define usbHidReportDescriptor usbDescriptorHidReport -/* should be declared as: PROGMEM char usbHidReportDescriptor[]; */ -/* If you implement an HID device, you need to provide a report descriptor. - * The HID report descriptor syntax is a bit complex. If you understand how - * report descriptors are constructed, we recommend that you use the HID - * Descriptor Tool from usb.org, see http://www.usb.org/developers/hidpage/. - * Otherwise you should probably start with a working example. - */ -#endif /* USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH */ -#if USB_CFG_IMPLEMENT_FN_WRITE -USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len); -/* This function is called by the driver to provide a control transfer's - * payload data (control-out). It is called in chunks of up to 8 bytes. The - * total count provided in the current control transfer can be obtained from - * the 'length' property in the setup data. If an error occurred during - * processing, return 0xff (== -1). The driver will answer the entire transfer - * with a STALL token in this case. If you have received the entire payload - * successfully, return 1. If you expect more data, return 0. If you don't - * know whether the host will send more data (you should know, the total is - * provided in the usbFunctionSetup() call!), return 1. - * NOTE: If you return 0xff for STALL, 'usbFunctionWrite()' may still be called - * for the remaining data. You must continue to return 0xff for STALL in these - * calls. - * In order to get usbFunctionWrite() called, define USB_CFG_IMPLEMENT_FN_WRITE - * to 1 in usbconfig.h and return 0xff in usbFunctionSetup().. - */ -#endif /* USB_CFG_IMPLEMENT_FN_WRITE */ -#if USB_CFG_IMPLEMENT_FN_READ -USB_PUBLIC uchar usbFunctionRead(uchar *data, uchar len); -/* This function is called by the driver to ask the application for a control - * transfer's payload data (control-in). It is called in chunks of up to 8 - * bytes each. You should copy the data to the location given by 'data' and - * return the actual number of bytes copied. If you return less than requested, - * the control-in transfer is terminated. If you return 0xff, the driver aborts - * the transfer with a STALL token. - * In order to get usbFunctionRead() called, define USB_CFG_IMPLEMENT_FN_READ - * to 1 in usbconfig.h and return 0xff in usbFunctionSetup().. - */ -#endif /* USB_CFG_IMPLEMENT_FN_READ */ - -extern uchar usbRxToken; /* may be used in usbFunctionWriteOut() below */ -#if USB_CFG_IMPLEMENT_FN_WRITEOUT -USB_PUBLIC void usbFunctionWriteOut(uchar *data, uchar len); -/* This function is called by the driver when data is received on an interrupt- - * or bulk-out endpoint. The endpoint number can be found in the global - * variable usbRxToken. You must define USB_CFG_IMPLEMENT_FN_WRITEOUT to 1 in - * usbconfig.h to get this function called. - */ -#endif /* USB_CFG_IMPLEMENT_FN_WRITEOUT */ -#ifdef USB_CFG_PULLUP_IOPORTNAME -#define usbDeviceConnect() ((USB_PULLUP_DDR |= (1<device, 1=device->host - * t ..... type: 0=standard, 1=class, 2=vendor, 3=reserved - * r ..... recipient: 0=device, 1=interface, 2=endpoint, 3=other - */ - -/* USB setup recipient values */ -#define USBRQ_RCPT_MASK 0x1f -#define USBRQ_RCPT_DEVICE 0 -#define USBRQ_RCPT_INTERFACE 1 -#define USBRQ_RCPT_ENDPOINT 2 - -/* USB request type values */ -#define USBRQ_TYPE_MASK 0x60 -#define USBRQ_TYPE_STANDARD (0<<5) -#define USBRQ_TYPE_CLASS (1<<5) -#define USBRQ_TYPE_VENDOR (2<<5) - -/* USB direction values: */ -#define USBRQ_DIR_MASK 0x80 -#define USBRQ_DIR_HOST_TO_DEVICE (0<<7) -#define USBRQ_DIR_DEVICE_TO_HOST (1<<7) - -/* USB Standard Requests */ -#define USBRQ_GET_STATUS 0 -#define USBRQ_CLEAR_FEATURE 1 -#define USBRQ_SET_FEATURE 3 -#define USBRQ_SET_ADDRESS 5 -#define USBRQ_GET_DESCRIPTOR 6 -#define USBRQ_SET_DESCRIPTOR 7 -#define USBRQ_GET_CONFIGURATION 8 -#define USBRQ_SET_CONFIGURATION 9 -#define USBRQ_GET_INTERFACE 10 -#define USBRQ_SET_INTERFACE 11 -#define USBRQ_SYNCH_FRAME 12 - -/* USB descriptor constants */ -#define USBDESCR_DEVICE 1 -#define USBDESCR_CONFIG 2 -#define USBDESCR_STRING 3 -#define USBDESCR_INTERFACE 4 -#define USBDESCR_ENDPOINT 5 -#define USBDESCR_HID 0x21 -#define USBDESCR_HID_REPORT 0x22 -#define USBDESCR_HID_PHYS 0x23 - -#define USBATTR_BUSPOWER 0x80 -#define USBATTR_SELFPOWER 0x40 -#define USBATTR_REMOTEWAKE 0x20 - -/* USB HID Requests */ -#define USBRQ_HID_GET_REPORT 0x01 -#define USBRQ_HID_GET_IDLE 0x02 -#define USBRQ_HID_GET_PROTOCOL 0x03 -#define USBRQ_HID_SET_REPORT 0x09 -#define USBRQ_HID_SET_IDLE 0x0a -#define USBRQ_HID_SET_PROTOCOL 0x0b - -/* ------------------------------------------------------------------------- */ - -#endif /* __usbdrv_h_included__ */ diff --git a/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm.S b/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm.S deleted file mode 100644 index 52c3d98..0000000 --- a/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm.S +++ /dev/null @@ -1,305 +0,0 @@ -/* Name: usbdrvasm.S - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2007-06-13 - * Tabsize: 4 - * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * Revision: $Id: usbdrvasm.S 722 2009-03-16 19:03:57Z cs $ - */ - -/* -General Description: -This module is the assembler part of the USB driver. This file contains -general code (preprocessor acrobatics and CRC computation) and then includes -the file appropriate for the given clock rate. -*/ - -#define __SFR_OFFSET 0 /* used by avr-libc's register definitions */ -#include "usbportability.h" -#include "usbdrv.h" /* for common defs */ - -/* register names */ -#define x1 r16 -#define x2 r17 -#define shift r18 -#define cnt r19 -#define x3 r20 -#define x4 r21 -#define x5 r22 -#define bitcnt x5 -#define phase x4 -#define leap x4 - -/* Some assembler dependent definitions and declarations: */ - -#ifdef __IAR_SYSTEMS_ASM__ - extern usbRxBuf, usbDeviceAddr, usbNewDeviceAddr, usbInputBufOffset - extern usbCurrentTok, usbRxLen, usbRxToken, usbTxLen - extern usbTxBuf, usbTxStatus1, usbTxStatus3 -# if USB_COUNT_SOF - extern usbSofCount -# endif - public usbCrc16 - public usbCrc16Append - - COMMON INTVEC -# ifndef USB_INTR_VECTOR - ORG INT0_vect -# else /* USB_INTR_VECTOR */ - ORG USB_INTR_VECTOR -# undef USB_INTR_VECTOR -# endif /* USB_INTR_VECTOR */ -# define USB_INTR_VECTOR usbInterruptHandler - rjmp USB_INTR_VECTOR - RSEG CODE - -#else /* __IAR_SYSTEMS_ASM__ */ - -# ifndef USB_INTR_VECTOR /* default to hardware interrupt INT0 */ -# define USB_INTR_VECTOR SIG_INTERRUPT0 -# endif - .text - .global USB_INTR_VECTOR - .type USB_INTR_VECTOR, @function - .global usbCrc16 - .global usbCrc16Append -#endif /* __IAR_SYSTEMS_ASM__ */ - - -#if USB_INTR_PENDING < 0x40 /* This is an I/O address, use in and out */ -# define USB_LOAD_PENDING(reg) in reg, USB_INTR_PENDING -# define USB_STORE_PENDING(reg) out USB_INTR_PENDING, reg -#else /* It's a memory address, use lds and sts */ -# define USB_LOAD_PENDING(reg) lds reg, USB_INTR_PENDING -# define USB_STORE_PENDING(reg) sts USB_INTR_PENDING, reg -#endif - -#define usbTxLen1 usbTxStatus1 -#define usbTxBuf1 (usbTxStatus1 + 1) -#define usbTxLen3 usbTxStatus3 -#define usbTxBuf3 (usbTxStatus3 + 1) - - -;---------------------------------------------------------------------------- -; Utility functions -;---------------------------------------------------------------------------- - -#ifdef __IAR_SYSTEMS_ASM__ -/* Register assignments for usbCrc16 on IAR cc */ -/* Calling conventions on IAR: - * First parameter passed in r16/r17, second in r18/r19 and so on. - * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer) - * Result is passed in r16/r17 - * In case of the "tiny" memory model, pointers are only 8 bit with no - * padding. We therefore pass argument 1 as "16 bit unsigned". - */ -RTMODEL "__rt_version", "3" -/* The line above will generate an error if cc calling conventions change. - * The value "3" above is valid for IAR 4.10B/W32 - */ -# define argLen r18 /* argument 2 */ -# define argPtrL r16 /* argument 1 */ -# define argPtrH r17 /* argument 1 */ - -# define resCrcL r16 /* result */ -# define resCrcH r17 /* result */ - -# define ptrL ZL -# define ptrH ZH -# define ptr Z -# define byte r22 -# define bitCnt r19 -# define polyL r20 -# define polyH r21 -# define scratch r23 - -#else /* __IAR_SYSTEMS_ASM__ */ -/* Register assignments for usbCrc16 on gcc */ -/* Calling conventions on gcc: - * First parameter passed in r24/r25, second in r22/23 and so on. - * Callee must preserve r1-r17, r28/r29 - * Result is passed in r24/r25 - */ -# define argLen r22 /* argument 2 */ -# define argPtrL r24 /* argument 1 */ -# define argPtrH r25 /* argument 1 */ - -# define resCrcL r24 /* result */ -# define resCrcH r25 /* result */ - -# define ptrL XL -# define ptrH XH -# define ptr x -# define byte r18 -# define bitCnt r19 -# define polyL r20 -# define polyH r21 -# define scratch r23 - -#endif - -; extern unsigned usbCrc16(unsigned char *data, unsigned char len); -; data: r24/25 -; len: r22 -; temp variables: -; r18: data byte -; r19: bit counter -; r20/21: polynomial -; r23: scratch -; r24/25: crc-sum -; r26/27=X: ptr -usbCrc16: - mov ptrL, argPtrL - mov ptrH, argPtrH - ldi resCrcL, 0 - ldi resCrcH, 0 - ldi polyL, lo8(0xa001) - ldi polyH, hi8(0xa001) - com argLen ; argLen = -argLen - 1 -crcByteLoop: - subi argLen, -1 - brcc crcReady ; modified loop to ensure that carry is set below - ld byte, ptr+ - ldi bitCnt, -8 ; strange loop counter to ensure that carry is set where we need it - eor resCrcL, byte -crcBitLoop: - ror resCrcH ; carry is always set here - ror resCrcL - brcs crcNoXor - eor resCrcL, polyL - eor resCrcH, polyH -crcNoXor: - subi bitCnt, -1 - brcs crcBitLoop - rjmp crcByteLoop -crcReady: - ret -; Thanks to Reimar Doeffinger for optimizing this CRC routine! - -; extern unsigned usbCrc16Append(unsigned char *data, unsigned char len); -usbCrc16Append: - rcall usbCrc16 - st ptr+, resCrcL - st ptr+, resCrcH - ret - -#undef argLen -#undef argPtrL -#undef argPtrH -#undef resCrcL -#undef resCrcH -#undef ptrL -#undef ptrH -#undef ptr -#undef byte -#undef bitCnt -#undef polyL -#undef polyH -#undef scratch - - -#if USB_CFG_HAVE_MEASURE_FRAME_LENGTH -#ifdef __IAR_SYSTEMS_ASM__ -/* Register assignments for usbMeasureFrameLength on IAR cc */ -/* Calling conventions on IAR: - * First parameter passed in r16/r17, second in r18/r19 and so on. - * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer) - * Result is passed in r16/r17 - * In case of the "tiny" memory model, pointers are only 8 bit with no - * padding. We therefore pass argument 1 as "16 bit unsigned". - */ -# define resL r16 -# define resH r17 -# define cnt16L r30 -# define cnt16H r31 -# define cntH r18 - -#else /* __IAR_SYSTEMS_ASM__ */ -/* Register assignments for usbMeasureFrameLength on gcc */ -/* Calling conventions on gcc: - * First parameter passed in r24/r25, second in r22/23 and so on. - * Callee must preserve r1-r17, r28/r29 - * Result is passed in r24/r25 - */ -# define resL r24 -# define resH r25 -# define cnt16L r24 -# define cnt16H r25 -# define cntH r26 -#endif -# define cnt16 cnt16L - -; extern unsigned usbMeasurePacketLength(void); -; returns time between two idle strobes in multiples of 7 CPU clocks -.global usbMeasureFrameLength -usbMeasureFrameLength: - ldi cntH, 6 ; wait ~ 10 ms for D- == 0 - clr cnt16L - clr cnt16H -usbMFTime16: - dec cntH - breq usbMFTimeout -usbMFWaitStrobe: ; first wait for D- == 0 (idle strobe) - sbiw cnt16, 1 ;[0] [6] - breq usbMFTime16 ;[2] - sbic USBIN, USBMINUS ;[3] - rjmp usbMFWaitStrobe ;[4] -usbMFWaitIdle: ; then wait until idle again - sbis USBIN, USBMINUS ;1 wait for D- == 1 - rjmp usbMFWaitIdle ;2 - ldi cnt16L, 1 ;1 represents cycles so far - clr cnt16H ;1 -usbMFWaitLoop: - in cntH, USBIN ;[0] [7] - adiw cnt16, 1 ;[1] - breq usbMFTimeout ;[3] - andi cntH, USBMASK ;[4] - brne usbMFWaitLoop ;[5] -usbMFTimeout: -#if resL != cnt16L - mov resL, cnt16L - mov resH, cnt16H -#endif - ret - -#undef resL -#undef resH -#undef cnt16 -#undef cnt16L -#undef cnt16H -#undef cntH - -#endif /* USB_CFG_HAVE_MEASURE_FRAME_LENGTH */ - -;---------------------------------------------------------------------------- -; Now include the clock rate specific code -;---------------------------------------------------------------------------- - -#ifndef USB_CFG_CLOCK_KHZ -# define USB_CFG_CLOCK_KHZ 12000 -#endif - -#if USB_CFG_CHECK_CRC /* separate dispatcher for CRC type modules */ -# if USB_CFG_CLOCK_KHZ == 18000 -# include "usbdrvasm18-crc.inc" -# else -# error "USB_CFG_CLOCK_KHZ is not one of the supported crc-rates!" -# endif -#else /* USB_CFG_CHECK_CRC */ -# if USB_CFG_CLOCK_KHZ == 12000 -# include "usbdrvasm12.inc" -# elif USB_CFG_CLOCK_KHZ == 12800 -# include "usbdrvasm128.inc" -# elif USB_CFG_CLOCK_KHZ == 15000 -# include "usbdrvasm15.inc" -# elif USB_CFG_CLOCK_KHZ == 16000 -# include "usbdrvasm16.inc" -# elif USB_CFG_CLOCK_KHZ == 16500 -# include "usbdrvasm165.inc" -# elif USB_CFG_CLOCK_KHZ == 20000 -# include "usbdrvasm20.inc" -# else -# error "USB_CFG_CLOCK_KHZ is not one of the supported non-crc-rates!" -# endif -#endif /* USB_CFG_CHECK_CRC */ diff --git a/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm.asm b/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm.asm deleted file mode 100644 index a534b73..0000000 --- a/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm.asm +++ /dev/null @@ -1,21 +0,0 @@ -/* Name: usbdrvasm.asm - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2006-03-01 - * Tabsize: 4 - * Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id$ - */ - -/* -General Description: -The IAR compiler/assembler system prefers assembler files with file extension -".asm". We simply provide this file as an alias for usbdrvasm.S. - -Thanks to Oleg Semyonov for his help with the IAR tools port! -*/ - -#include "usbdrvasm.S" - -end diff --git a/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm12.inc b/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm12.inc deleted file mode 100644 index 08dddd3..0000000 --- a/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm12.inc +++ /dev/null @@ -1,393 +0,0 @@ -/* Name: usbdrvasm12.inc - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2004-12-29 - * Tabsize: 4 - * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: usbdrvasm12.inc 692 2008-11-07 15:07:40Z cs $ - */ - -/* Do not link this file! Link usbdrvasm.S instead, which includes the - * appropriate implementation! - */ - -/* -General Description: -This file is the 12 MHz version of the asssembler part of the USB driver. It -requires a 12 MHz crystal (not a ceramic resonator and not a calibrated RC -oscillator). - -See usbdrv.h for a description of the entire driver. - -Since almost all of this code is timing critical, don't change unless you -really know what you are doing! Many parts require not only a maximum number -of CPU cycles, but even an exact number of cycles! - - -Timing constraints according to spec (in bit times): -timing subject min max CPUcycles ---------------------------------------------------------------------------- -EOP of OUT/SETUP to sync pattern of DATA0 (both rx) 2 16 16-128 -EOP of IN to sync pattern of DATA0 (rx, then tx) 2 7.5 16-60 -DATAx (rx) to ACK/NAK/STALL (tx) 2 7.5 16-60 -*/ - -;Software-receiver engine. Strict timing! Don't change unless you can preserve timing! -;interrupt response time: 4 cycles + insn running = 7 max if interrupts always enabled -;max allowable interrupt latency: 34 cycles -> max 25 cycles interrupt disable -;max stack usage: [ret(2), YL, SREG, YH, shift, x1, x2, x3, cnt, x4] = 11 bytes -;Numbers in brackets are maximum cycles since SOF. -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt - push YL ;2 [35] push only what is necessary to sync with edge ASAP - in YL, SREG ;1 [37] - push YL ;2 [39] -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of 1/4 bit which meets the spec. - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -foundK: -;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling] -;we have 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push YH ;2 [2] - lds YL, usbInputBufOffset;2 [4] - clr YH ;1 [5] - subi YL, lo8(-(usbRxBuf));1 [6] - sbci YH, hi8(-(usbRxBuf));1 [7] - - sbis USBIN, USBMINUS ;1 [8] we want two bits K [sample 1 cycle too early] - rjmp haveTwoBitsK ;2 [10] - pop YH ;2 [11] undo the push from before - rjmp waitForK ;2 [13] this was not the end of sync, retry -haveTwoBitsK: -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- - push shift ;2 [16] - push x1 ;2 [12] - push x2 ;2 [14] - - in x1, USBIN ;1 [17] <-- sample bit 0 - ldi shift, 0xff ;1 [18] - bst x1, USBMINUS ;1 [19] - bld shift, 0 ;1 [20] - push x3 ;2 [22] - push cnt ;2 [24] - - in x2, USBIN ;1 [25] <-- sample bit 1 - ser x3 ;1 [26] [inserted init instruction] - eor x1, x2 ;1 [27] - bst x1, USBMINUS ;1 [28] - bld shift, 1 ;1 [29] - ldi cnt, USB_BUFSIZE;1 [30] [inserted init instruction] - rjmp rxbit2 ;2 [32] - -;---------------------------------------------------------------------------- -; Receiver loop (numbers in brackets are cycles within byte after instr) -;---------------------------------------------------------------------------- - -unstuff0: ;1 (branch taken) - andi x3, ~0x01 ;1 [15] - mov x1, x2 ;1 [16] x2 contains last sampled (stuffed) bit - in x2, USBIN ;1 [17] <-- sample bit 1 again - ori shift, 0x01 ;1 [18] - rjmp didUnstuff0 ;2 [20] - -unstuff1: ;1 (branch taken) - mov x2, x1 ;1 [21] x1 contains last sampled (stuffed) bit - andi x3, ~0x02 ;1 [22] - ori shift, 0x02 ;1 [23] - nop ;1 [24] - in x1, USBIN ;1 [25] <-- sample bit 2 again - rjmp didUnstuff1 ;2 [27] - -unstuff2: ;1 (branch taken) - andi x3, ~0x04 ;1 [29] - ori shift, 0x04 ;1 [30] - mov x1, x2 ;1 [31] x2 contains last sampled (stuffed) bit - nop ;1 [32] - in x2, USBIN ;1 [33] <-- sample bit 3 - rjmp didUnstuff2 ;2 [35] - -unstuff3: ;1 (branch taken) - in x2, USBIN ;1 [34] <-- sample stuffed bit 3 [one cycle too late] - andi x3, ~0x08 ;1 [35] - ori shift, 0x08 ;1 [36] - rjmp didUnstuff3 ;2 [38] - -unstuff4: ;1 (branch taken) - andi x3, ~0x10 ;1 [40] - in x1, USBIN ;1 [41] <-- sample stuffed bit 4 - ori shift, 0x10 ;1 [42] - rjmp didUnstuff4 ;2 [44] - -unstuff5: ;1 (branch taken) - andi x3, ~0x20 ;1 [48] - in x2, USBIN ;1 [49] <-- sample stuffed bit 5 - ori shift, 0x20 ;1 [50] - rjmp didUnstuff5 ;2 [52] - -unstuff6: ;1 (branch taken) - andi x3, ~0x40 ;1 [56] - in x1, USBIN ;1 [57] <-- sample stuffed bit 6 - ori shift, 0x40 ;1 [58] - rjmp didUnstuff6 ;2 [60] - -; extra jobs done during bit interval: -; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs] -; bit 1: se0 check -; bit 2: overflow check -; bit 3: recovery from delay [bit 0 tasks took too long] -; bit 4: none -; bit 5: none -; bit 6: none -; bit 7: jump, eor -rxLoop: - eor x3, shift ;1 [0] reconstruct: x3 is 0 at bit locations we changed, 1 at others - in x1, USBIN ;1 [1] <-- sample bit 0 - st y+, x3 ;2 [3] store data - ser x3 ;1 [4] - nop ;1 [5] - eor x2, x1 ;1 [6] - bst x2, USBMINUS;1 [7] - bld shift, 0 ;1 [8] - in x2, USBIN ;1 [9] <-- sample bit 1 (or possibly bit 0 stuffed) - andi x2, USBMASK ;1 [10] - breq se0 ;1 [11] SE0 check for bit 1 - andi shift, 0xf9 ;1 [12] -didUnstuff0: - breq unstuff0 ;1 [13] - eor x1, x2 ;1 [14] - bst x1, USBMINUS;1 [15] - bld shift, 1 ;1 [16] -rxbit2: - in x1, USBIN ;1 [17] <-- sample bit 2 (or possibly bit 1 stuffed) - andi shift, 0xf3 ;1 [18] - breq unstuff1 ;1 [19] do remaining work for bit 1 -didUnstuff1: - subi cnt, 1 ;1 [20] - brcs overflow ;1 [21] loop control - eor x2, x1 ;1 [22] - bst x2, USBMINUS;1 [23] - bld shift, 2 ;1 [24] - in x2, USBIN ;1 [25] <-- sample bit 3 (or possibly bit 2 stuffed) - andi shift, 0xe7 ;1 [26] - breq unstuff2 ;1 [27] -didUnstuff2: - eor x1, x2 ;1 [28] - bst x1, USBMINUS;1 [29] - bld shift, 3 ;1 [30] -didUnstuff3: - andi shift, 0xcf ;1 [31] - breq unstuff3 ;1 [32] - in x1, USBIN ;1 [33] <-- sample bit 4 - eor x2, x1 ;1 [34] - bst x2, USBMINUS;1 [35] - bld shift, 4 ;1 [36] -didUnstuff4: - andi shift, 0x9f ;1 [37] - breq unstuff4 ;1 [38] - nop2 ;2 [40] - in x2, USBIN ;1 [41] <-- sample bit 5 - eor x1, x2 ;1 [42] - bst x1, USBMINUS;1 [43] - bld shift, 5 ;1 [44] -didUnstuff5: - andi shift, 0x3f ;1 [45] - breq unstuff5 ;1 [46] - nop2 ;2 [48] - in x1, USBIN ;1 [49] <-- sample bit 6 - eor x2, x1 ;1 [50] - bst x2, USBMINUS;1 [51] - bld shift, 6 ;1 [52] -didUnstuff6: - cpi shift, 0x02 ;1 [53] - brlo unstuff6 ;1 [54] - nop2 ;2 [56] - in x2, USBIN ;1 [57] <-- sample bit 7 - eor x1, x2 ;1 [58] - bst x1, USBMINUS;1 [59] - bld shift, 7 ;1 [60] -didUnstuff7: - cpi shift, 0x04 ;1 [61] - brsh rxLoop ;2 [63] loop control -unstuff7: - andi x3, ~0x80 ;1 [63] - ori shift, 0x80 ;1 [64] - in x2, USBIN ;1 [65] <-- sample stuffed bit 7 - nop ;1 [66] - rjmp didUnstuff7 ;2 [68] - -macro POP_STANDARD ; 12 cycles - pop cnt - pop x3 - pop x2 - pop x1 - pop shift - pop YH - endm -macro POP_RETI ; 5 cycles - pop YL - out SREG, YL - pop YL - endm - -#include "asmcommon.inc" - -;---------------------------------------------------------------------------- -; Transmitting data -;---------------------------------------------------------------------------- - -txByteLoop: -txBitloop: -stuffN1Delay: ; [03] - ror shift ;[-5] [11] [59] - brcc doExorN1 ;[-4] [60] - subi x4, 1 ;[-3] - brne commonN1 ;[-2] - lsl shift ;[-1] compensate ror after rjmp stuffDelay - nop ;[00] stuffing consists of just waiting 8 cycles - rjmp stuffN1Delay ;[01] after ror, C bit is reliably clear - -sendNakAndReti: ;0 [-19] 19 cycles until SOP - ldi x3, USBPID_NAK ;1 [-18] - rjmp usbSendX3 ;2 [-16] -sendAckAndReti: ;0 [-19] 19 cycles until SOP - ldi x3, USBPID_ACK ;1 [-18] - rjmp usbSendX3 ;2 [-16] -sendCntAndReti: ;0 [-17] 17 cycles until SOP - mov x3, cnt ;1 [-16] -usbSendX3: ;0 [-16] - ldi YL, 20 ;1 [-15] 'x3' is R20 - ldi YH, 0 ;1 [-14] - ldi cnt, 2 ;1 [-13] -; rjmp usbSendAndReti fallthrough - -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) or USBOUT = 0x01 -; K = (D+ = 1), (D- = 0) or USBOUT = 0x02 -; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles) - -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte -;uses: x1...x2, x4, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x4 = bitstuff cnt] -;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction) -usbSendAndReti: - in x2, USBDDR ;[-12] 12 cycles until SOP - ori x2, USBMASK ;[-11] - sbi USBOUT, USBMINUS ;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) - out USBDDR, x2 ;[-8] <--- acquire bus - in x1, USBOUT ;[-7] port mirror for tx loop - ldi shift, 0x40 ;[-6] sync byte is first byte sent (we enter loop after ror) - ldi x2, USBMASK ;[-5] - push x4 ;[-4] -doExorN1: - eor x1, x2 ;[-2] [06] [62] - ldi x4, 6 ;[-1] [07] [63] -commonN1: -stuffN2Delay: - out USBOUT, x1 ;[00] [08] [64] <--- set bit - ror shift ;[01] - brcc doExorN2 ;[02] - subi x4, 1 ;[03] - brne commonN2 ;[04] - lsl shift ;[05] compensate ror after rjmp stuffDelay - rjmp stuffN2Delay ;[06] after ror, C bit is reliably clear -doExorN2: - eor x1, x2 ;[04] [12] - ldi x4, 6 ;[05] [13] -commonN2: - nop ;[06] [14] - subi cnt, 171 ;[07] [15] trick: (3 * 171) & 0xff = 1 - out USBOUT, x1 ;[08] [16] <--- set bit - brcs txBitloop ;[09] [25] [41] - -stuff6Delay: - ror shift ;[42] [50] - brcc doExor6 ;[43] - subi x4, 1 ;[44] - brne common6 ;[45] - lsl shift ;[46] compensate ror after rjmp stuffDelay - nop ;[47] stuffing consists of just waiting 8 cycles - rjmp stuff6Delay ;[48] after ror, C bit is reliably clear -doExor6: - eor x1, x2 ;[45] [53] - ldi x4, 6 ;[46] -common6: -stuff7Delay: - ror shift ;[47] [55] - out USBOUT, x1 ;[48] <--- set bit - brcc doExor7 ;[49] - subi x4, 1 ;[50] - brne common7 ;[51] - lsl shift ;[52] compensate ror after rjmp stuffDelay - rjmp stuff7Delay ;[53] after ror, C bit is reliably clear -doExor7: - eor x1, x2 ;[51] [59] - ldi x4, 6 ;[52] -common7: - ld shift, y+ ;[53] - tst cnt ;[55] - out USBOUT, x1 ;[56] <--- set bit - brne txByteLoop ;[57] - -;make SE0: - cbr x1, USBMASK ;[58] prepare SE0 [spec says EOP may be 15 to 18 cycles] - lds x2, usbNewDeviceAddr;[59] - lsl x2 ;[61] we compare with left shifted address - subi YL, 2 + 20 ;[62] Only assign address on data packets, not ACK/NAK in x3 - sbci YH, 0 ;[63] - out USBOUT, x1 ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - breq skipAddrAssign ;[01] - sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer -skipAddrAssign: -;end of usbDeviceAddress transfer - ldi x2, 1< 12.5625 MHz -max frequency: 69.286 cycles for 8 bit -> 12.99 MHz -nominal frequency: 12.77 MHz ( = sqrt(min * max)) - -sampling positions: (next even number in range [+/- 0.5]) -cycle index range: 0 ... 66 -bits: -.5, 8.875, 17.25, 25.625, 34, 42.375, 50.75, 59.125 -[0/1], [9], [17], [25/+26], [34], [+42/43], [51], [59] - -bit number: 0 1 2 3 4 5 6 7 -spare cycles 1 2 1 2 1 1 1 0 - -operations to perform: duration cycle - ---------------- - eor fix, shift 1 -> 00 - andi phase, USBMASK 1 -> 08 - breq se0 1 -> 16 (moved to 11) - st y+, data 2 -> 24, 25 - mov data, fix 1 -> 33 - ser data 1 -> 41 - subi cnt, 1 1 -> 49 - brcs overflow 1 -> 50 - -layout of samples and operations: -[##] = sample bit -<##> = sample phase -*##* = operation - -0: *00* [01] 02 03 04 <05> 06 07 -1: *08* [09] 10 11 12 <13> 14 15 *16* -2: [17] 18 19 20 <21> 22 23 -3: *24* *25* [26] 27 28 29 <30> 31 32 -4: *33* [34] 35 36 37 <38> 39 40 -5: *41* [42] 43 44 45 <46> 47 48 -6: *49* *50* [51] 52 53 54 <55> 56 57 58 -7: [59] 60 61 62 <63> 64 65 66 -*****************************************************************************/ - -/* we prefer positive expressions (do if condition) instead of negative - * (skip if condition), therefore use defines for skip instructions: - */ -#define ifioclr sbis -#define ifioset sbic -#define ifrclr sbrs -#define ifrset sbrc - -/* The registers "fix" and "data" swap their meaning during the loop. Use - * defines to keep their name constant. - */ -#define fix x2 -#define data x1 -#undef phase /* phase has a default definition to x4 */ -#define phase x3 - - -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt, r0 - push YL ;2 push only what is necessary to sync with edge ASAP - in YL, SREG ;1 - push YL ;2 -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of 1/4 bit which meets the spec. - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS ;[0] - rjmp foundK ;[1] -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError - -foundK: -;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling] -;we have 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push YH ;[2] - lds YL, usbInputBufOffset;[4] - clr YH ;[6] - subi YL, lo8(-(usbRxBuf));[7] - sbci YH, hi8(-(usbRxBuf));[8] - - sbis USBIN, USBMINUS ;[9] we want two bits K [we want to sample at 8 + 4 - 1.5 = 10.5] - rjmp haveTwoBitsK ;[10] - pop YH ;[11] undo the push from before - rjmp waitForK ;[13] this was not the end of sync, retry -haveTwoBitsK: -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -#define fix x2 -#define data x1 - - push shift ;[12] - push x1 ;[14] - push x2 ;[16] - ldi shift, 0x80 ;[18] prevent bit-unstuffing but init low bits to 0 - ifioset USBIN, USBMINUS ;[19] [01] <--- bit 0 [10.5 + 8 = 18.5] - ori shift, 1<<0 ;[02] - push x3 ;[03] - push cnt ;[05] - push r0 ;[07] - ifioset USBIN, USBMINUS ;[09] <--- bit 1 - ori shift, 1<<1 ;[10] - ser fix ;[11] - ldi cnt, USB_BUFSIZE ;[12] - mov data, shift ;[13] - lsl shift ;[14] - nop2 ;[15] - ifioset USBIN, USBMINUS ;[17] <--- bit 2 - ori data, 3<<2 ;[18] store in bit 2 AND bit 3 - eor shift, data ;[19] do nrzi decoding - andi data, 1<<3 ;[20] - in phase, USBIN ;[21] <- phase - brne jumpToEntryAfterSet ;[22] if USBMINS at bit 3 was 1 - nop ;[23] - rjmp entryAfterClr ;[24] -jumpToEntryAfterSet: - rjmp entryAfterSet ;[24] - -;---------------------------------------------------------------------------- -; Receiver loop (numbers in brackets are cycles within byte after instr) -;---------------------------------------------------------------------------- -#undef fix -#define fix x1 -#undef data -#define data x2 - -bit7IsSet: - ifrclr phase, USBMINUS ;[62] check phase only if D- changed - lpm ;[63] - in phase, USBIN ;[64] <- phase (one cycle too late) - ori shift, 1 << 7 ;[65] - nop ;[66] -;;;;rjmp bit0AfterSet ; -> [00] == [67] moved block up to save jump -bit0AfterSet: - eor fix, shift ;[00] -#undef fix -#define fix x2 -#undef data -#define data x1 /* we now have result in data, fix is reset to 0xff */ - ifioclr USBIN, USBMINUS ;[01] <--- sample 0 - rjmp bit0IsClr ;[02] - andi shift, ~(7 << 0) ;[03] - breq unstuff0s ;[04] - in phase, USBIN ;[05] <- phase - rjmp bit1AfterSet ;[06] -unstuff0s: - in phase, USBIN ;[06] <- phase (one cycle too late) - andi fix, ~(1 << 0) ;[07] - ifioclr USBIN, USBMINUS ;[00] - ifioset USBIN, USBPLUS ;[01] - rjmp bit0IsClr ;[02] executed if first expr false or second true -jumpToSe0AndStore: - rjmp se0AndStore ;[03] executed only if both bits 0 -bit0IsClr: - ifrset phase, USBMINUS ;[04] check phase only if D- changed - lpm ;[05] - in phase, USBIN ;[06] <- phase (one cycle too late) - ori shift, 1 << 0 ;[07] -bit1AfterClr: - andi phase, USBMASK ;[08] - ifioset USBIN, USBMINUS ;[09] <--- sample 1 - rjmp bit1IsSet ;[10] - breq jumpToSe0AndStore ;[11] - andi shift, ~(7 << 1) ;[12] - in phase, USBIN ;[13] <- phase - breq unstuff1c ;[14] - rjmp bit2AfterClr ;[15] -unstuff1c: - andi fix, ~(1 << 1) ;[16] - nop2 ;[08] - nop2 ;[10] -bit1IsSet: - ifrclr phase, USBMINUS ;[12] check phase only if D- changed - lpm ;[13] - in phase, USBIN ;[14] <- phase (one cycle too late) - ori shift, 1 << 1 ;[15] - nop ;[16] -bit2AfterSet: - ifioclr USBIN, USBMINUS ;[17] <--- sample 2 - rjmp bit2IsClr ;[18] - andi shift, ~(7 << 2) ;[19] - breq unstuff2s ;[20] - in phase, USBIN ;[21] <- phase - rjmp bit3AfterSet ;[22] -unstuff2s: - in phase, USBIN ;[22] <- phase (one cycle too late) - andi fix, ~(1 << 2) ;[23] - nop2 ;[16] - nop2 ;[18] -bit2IsClr: - ifrset phase, USBMINUS ;[20] check phase only if D- changed - lpm ;[21] - in phase, USBIN ;[22] <- phase (one cycle too late) - ori shift, 1 << 2 ;[23] -bit3AfterClr: - st y+, data ;[24] -entryAfterClr: - ifioset USBIN, USBMINUS ;[26] <--- sample 3 - rjmp bit3IsSet ;[27] - andi shift, ~(7 << 3) ;[28] - breq unstuff3c ;[29] - in phase, USBIN ;[30] <- phase - rjmp bit4AfterClr ;[31] -unstuff3c: - in phase, USBIN ;[31] <- phase (one cycle too late) - andi fix, ~(1 << 3) ;[32] - nop2 ;[25] - nop2 ;[27] -bit3IsSet: - ifrclr phase, USBMINUS ;[29] check phase only if D- changed - lpm ;[30] - in phase, USBIN ;[31] <- phase (one cycle too late) - ori shift, 1 << 3 ;[32] -bit4AfterSet: - mov data, fix ;[33] undo this move by swapping defines -#undef fix -#define fix x1 -#undef data -#define data x2 - ifioclr USBIN, USBMINUS ;[34] <--- sample 4 - rjmp bit4IsClr ;[35] - andi shift, ~(7 << 4) ;[36] - breq unstuff4s ;[37] - in phase, USBIN ;[38] <- phase - rjmp bit5AfterSet ;[39] -unstuff4s: - in phase, USBIN ;[39] <- phase (one cycle too late) - andi fix, ~(1 << 4) ;[40] - nop2 ;[33] - nop2 ;[35] -bit4IsClr: - ifrset phase, USBMINUS ;[37] check phase only if D- changed - lpm ;[38] - in phase, USBIN ;[39] <- phase (one cycle too late) - ori shift, 1 << 4 ;[40] -bit5AfterClr: - ser data ;[41] - ifioset USBIN, USBMINUS ;[42] <--- sample 5 - rjmp bit5IsSet ;[43] - andi shift, ~(7 << 5) ;[44] - breq unstuff5c ;[45] - in phase, USBIN ;[46] <- phase - rjmp bit6AfterClr ;[47] -unstuff5c: - in phase, USBIN ;[47] <- phase (one cycle too late) - andi fix, ~(1 << 5) ;[48] - nop2 ;[41] - nop2 ;[43] -bit5IsSet: - ifrclr phase, USBMINUS ;[45] check phase only if D- changed - lpm ;[46] - in phase, USBIN ;[47] <- phase (one cycle too late) - ori shift, 1 << 5 ;[48] -bit6AfterSet: - subi cnt, 1 ;[49] - brcs jumpToOverflow ;[50] - ifioclr USBIN, USBMINUS ;[51] <--- sample 6 - rjmp bit6IsClr ;[52] - andi shift, ~(3 << 6) ;[53] - cpi shift, 2 ;[54] - in phase, USBIN ;[55] <- phase - brlt unstuff6s ;[56] - rjmp bit7AfterSet ;[57] - -jumpToOverflow: - rjmp overflow - -unstuff6s: - andi fix, ~(1 << 6) ;[50] - lpm ;[51] -bit6IsClr: - ifrset phase, USBMINUS ;[54] check phase only if D- changed - lpm ;[55] - in phase, USBIN ;[56] <- phase (one cycle too late) - ori shift, 1 << 6 ;[57] - nop ;[58] -bit7AfterClr: - ifioset USBIN, USBMINUS ;[59] <--- sample 7 - rjmp bit7IsSet ;[60] - andi shift, ~(1 << 7) ;[61] - cpi shift, 4 ;[62] - in phase, USBIN ;[63] <- phase - brlt unstuff7c ;[64] - rjmp bit0AfterClr ;[65] -> [00] == [67] -unstuff7c: - andi fix, ~(1 << 7) ;[58] - nop ;[59] - rjmp bit7IsSet ;[60] - -se0AndStore: - st y+, x1 ;[15/17] cycles after start of byte - rjmp se0 ;[17/19] - -bit7IsClr: - ifrset phase, USBMINUS ;[62] check phase only if D- changed - lpm ;[63] - in phase, USBIN ;[64] <- phase (one cycle too late) - ori shift, 1 << 7 ;[65] - nop ;[66] -;;;;rjmp bit0AfterClr ; -> [00] == [67] moved block up to save jump -bit0AfterClr: - eor fix, shift ;[00] -#undef fix -#define fix x2 -#undef data -#define data x1 /* we now have result in data, fix is reset to 0xff */ - ifioset USBIN, USBMINUS ;[01] <--- sample 0 - rjmp bit0IsSet ;[02] - andi shift, ~(7 << 0) ;[03] - breq unstuff0c ;[04] - in phase, USBIN ;[05] <- phase - rjmp bit1AfterClr ;[06] -unstuff0c: - in phase, USBIN ;[06] <- phase (one cycle too late) - andi fix, ~(1 << 0) ;[07] - ifioclr USBIN, USBMINUS ;[00] - ifioset USBIN, USBPLUS ;[01] - rjmp bit0IsSet ;[02] executed if first expr false or second true - rjmp se0AndStore ;[03] executed only if both bits 0 -bit0IsSet: - ifrclr phase, USBMINUS ;[04] check phase only if D- changed - lpm ;[05] - in phase, USBIN ;[06] <- phase (one cycle too late) - ori shift, 1 << 0 ;[07] -bit1AfterSet: - andi phase, USBMASK ;[08] - ifioclr USBIN, USBMINUS ;[09] <--- sample 1 - rjmp bit1IsClr ;[10] - andi shift, ~(7 << 1) ;[11] - breq unstuff1s ;[12] - in phase, USBIN ;[13] <- phase - nop ;[14] - rjmp bit2AfterSet ;[15] -unstuff1s: - in phase, USBIN ;[14] <- phase (one cycle too late) - andi fix, ~(1 << 1) ;[15] - nop2 ;[08] - nop2 ;[10] -bit1IsClr: - ifrset phase, USBMINUS ;[12] check phase only if D- changed - lpm ;[13] - in phase, USBIN ;[14] <- phase (one cycle too late) - breq se0AndStore ;[15] if we come from unstuff1s, Z bit is never set - ori shift, 1 << 1 ;[16] -bit2AfterClr: - ifioset USBIN, USBMINUS ;[17] <--- sample 2 - rjmp bit2IsSet ;[18] - andi shift, ~(7 << 2) ;[19] - breq unstuff2c ;[20] - in phase, USBIN ;[21] <- phase - rjmp bit3AfterClr ;[22] -unstuff2c: - in phase, USBIN ;[22] <- phase (one cycle too late) - andi fix, ~(1 << 2) ;[23] - nop2 ;[16] - nop2 ;[18] -bit2IsSet: - ifrclr phase, USBMINUS ;[20] check phase only if D- changed - lpm ;[21] - in phase, USBIN ;[22] <- phase (one cycle too late) - ori shift, 1 << 2 ;[23] -bit3AfterSet: - st y+, data ;[24] -entryAfterSet: - ifioclr USBIN, USBMINUS ;[26] <--- sample 3 - rjmp bit3IsClr ;[27] - andi shift, ~(7 << 3) ;[28] - breq unstuff3s ;[29] - in phase, USBIN ;[30] <- phase - rjmp bit4AfterSet ;[31] -unstuff3s: - in phase, USBIN ;[31] <- phase (one cycle too late) - andi fix, ~(1 << 3) ;[32] - nop2 ;[25] - nop2 ;[27] -bit3IsClr: - ifrset phase, USBMINUS ;[29] check phase only if D- changed - lpm ;[30] - in phase, USBIN ;[31] <- phase (one cycle too late) - ori shift, 1 << 3 ;[32] -bit4AfterClr: - mov data, fix ;[33] undo this move by swapping defines -#undef fix -#define fix x1 -#undef data -#define data x2 - ifioset USBIN, USBMINUS ;[34] <--- sample 4 - rjmp bit4IsSet ;[35] - andi shift, ~(7 << 4) ;[36] - breq unstuff4c ;[37] - in phase, USBIN ;[38] <- phase - rjmp bit5AfterClr ;[39] -unstuff4c: - in phase, USBIN ;[39] <- phase (one cycle too late) - andi fix, ~(1 << 4) ;[40] - nop2 ;[33] - nop2 ;[35] -bit4IsSet: - ifrclr phase, USBMINUS ;[37] check phase only if D- changed - lpm ;[38] - in phase, USBIN ;[39] <- phase (one cycle too late) - ori shift, 1 << 4 ;[40] -bit5AfterSet: - ser data ;[41] - ifioclr USBIN, USBMINUS ;[42] <--- sample 5 - rjmp bit5IsClr ;[43] - andi shift, ~(7 << 5) ;[44] - breq unstuff5s ;[45] - in phase, USBIN ;[46] <- phase - rjmp bit6AfterSet ;[47] -unstuff5s: - in phase, USBIN ;[47] <- phase (one cycle too late) - andi fix, ~(1 << 5) ;[48] - nop2 ;[41] - nop2 ;[43] -bit5IsClr: - ifrset phase, USBMINUS ;[45] check phase only if D- changed - lpm ;[46] - in phase, USBIN ;[47] <- phase (one cycle too late) - ori shift, 1 << 5 ;[48] -bit6AfterClr: - subi cnt, 1 ;[49] - brcs overflow ;[50] - ifioset USBIN, USBMINUS ;[51] <--- sample 6 - rjmp bit6IsSet ;[52] - andi shift, ~(3 << 6) ;[53] - cpi shift, 2 ;[54] - in phase, USBIN ;[55] <- phase - brlt unstuff6c ;[56] - rjmp bit7AfterClr ;[57] -unstuff6c: - andi fix, ~(1 << 6) ;[50] - lpm ;[51] -bit6IsSet: - ifrclr phase, USBMINUS ;[54] check phase only if D- changed - lpm ;[55] - in phase, USBIN ;[56] <- phase (one cycle too late) - ori shift, 1 << 6 ;[57] -bit7AfterSet: - ifioclr USBIN, USBMINUS ;[59] <--- sample 7 - rjmp bit7IsClr ;[60] - andi shift, ~(1 << 7) ;[61] - cpi shift, 4 ;[62] - in phase, USBIN ;[63] <- phase - brlt unstuff7s ;[64] - rjmp bit0AfterSet ;[65] -> [00] == [67] -unstuff7s: - andi fix, ~(1 << 7) ;[58] - nop ;[59] - rjmp bit7IsClr ;[60] - -macro POP_STANDARD ; 14 cycles - pop r0 - pop cnt - pop x3 - pop x2 - pop x1 - pop shift - pop YH - endm -macro POP_RETI ; 5 cycles - pop YL - out SREG, YL - pop YL - endm - -#include "asmcommon.inc" - -;---------------------------------------------------------------------------- -; Transmitting data -;---------------------------------------------------------------------------- - -txByteLoop: -txBitloop: -stuffN1Delay: ; [03] - ror shift ;[-5] [11] [63] - brcc doExorN1 ;[-4] [64] - subi x3, 1 ;[-3] - brne commonN1 ;[-2] - lsl shift ;[-1] compensate ror after rjmp stuffDelay - nop ;[00] stuffing consists of just waiting 8 cycles - rjmp stuffN1Delay ;[01] after ror, C bit is reliably clear - -sendNakAndReti: - ldi cnt, USBPID_NAK ;[-19] - rjmp sendCntAndReti ;[-18] -sendAckAndReti: - ldi cnt, USBPID_ACK ;[-17] -sendCntAndReti: - mov r0, cnt ;[-16] - ldi YL, 0 ;[-15] R0 address is 0 - ldi YH, 0 ;[-14] - ldi cnt, 2 ;[-13] -; rjmp usbSendAndReti fallthrough - -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) or USBOUT = 0x01 -; K = (D+ = 1), (D- = 0) or USBOUT = 0x02 -; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles) - -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte -;uses: x1...x3, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x3 = bitstuff cnt] -;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction) -usbSendAndReti: - in x2, USBDDR ;[-10] 10 cycles until SOP - ori x2, USBMASK ;[-9] - sbi USBOUT, USBMINUS ;[-8] prepare idle state; D+ and D- must have been 0 (no pullups) - out USBDDR, x2 ;[-6] <--- acquire bus - in x1, USBOUT ;[-5] port mirror for tx loop - ldi shift, 0x40 ;[-4] sync byte is first byte sent (we enter loop after ror) - ldi x2, USBMASK ;[-3] -doExorN1: - eor x1, x2 ;[-2] [06] [62] - ldi x3, 6 ;[-1] [07] [63] -commonN1: -stuffN2Delay: - out USBOUT, x1 ;[00] [08] [64] <--- set bit - ror shift ;[01] - brcc doExorN2 ;[02] - subi x3, 1 ;[03] - brne commonN2 ;[04] - lsl shift ;[05] compensate ror after rjmp stuffDelay - rjmp stuffN2Delay ;[06] after ror, C bit is reliably clear -doExorN2: - eor x1, x2 ;[04] [12] - ldi x3, 6 ;[05] [13] -commonN2: - nop2 ;[06] [14] - subi cnt, 171 ;[08] [16] trick: (3 * 171) & 0xff = 1 - out USBOUT, x1 ;[09] [17] <--- set bit - brcs txBitloop ;[10] [27] [44] - -stuff6Delay: - ror shift ;[45] [53] - brcc doExor6 ;[46] - subi x3, 1 ;[47] - brne common6 ;[48] - lsl shift ;[49] compensate ror after rjmp stuffDelay - nop ;[50] stuffing consists of just waiting 8 cycles - rjmp stuff6Delay ;[51] after ror, C bit is reliably clear -doExor6: - eor x1, x2 ;[48] [56] - ldi x3, 6 ;[49] -common6: -stuff7Delay: - ror shift ;[50] [58] - out USBOUT, x1 ;[51] <--- set bit - brcc doExor7 ;[52] - subi x3, 1 ;[53] - brne common7 ;[54] - lsl shift ;[55] compensate ror after rjmp stuffDelay - rjmp stuff7Delay ;[56] after ror, C bit is reliably clear -doExor7: - eor x1, x2 ;[54] [62] - ldi x3, 6 ;[55] -common7: - ld shift, y+ ;[56] - nop ;[58] - tst cnt ;[59] - out USBOUT, x1 ;[60] [00]<--- set bit - brne txByteLoop ;[61] [01] -;make SE0: - cbr x1, USBMASK ;[02] prepare SE0 [spec says EOP may be 15 to 18 cycles] - lds x2, usbNewDeviceAddr;[03] - lsl x2 ;[05] we compare with left shifted address - subi YL, 2 + 0 ;[06] Only assign address on data packets, not ACK/NAK in r0 - sbci YH, 0 ;[07] - out USBOUT, x1 ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - breq skipAddrAssign ;[01] - sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer -skipAddrAssign: -;end of usbDeviceAddress transfer - ldi x2, 1< 0) - echo "$s\n"; - } -} - -function printBit($isAfterSet, $bitNum) -{ - ob_start(); - if($isAfterSet){ -?> - ifioclr USBIN, USBMINUS ;[00] <--- sample - rjmp bit#IsClr ;[01] - andi shift, ~(7 << #) ;[02] - breq unstuff#s ;[03] - in phase, USBIN ;[04] <- phase - rjmp bit@AfterSet ;[05] -unstuff#s: - in phase, USBIN ;[05] <- phase (one cycle too late) - andi fix, ~(1 << #) ;[06] - nop2 ;[-1] - nop2 ;[01] -bit#IsClr: - ifrset phase, USBMINUS ;[03] check phase only if D- changed - lpm ;[04] - in phase, USBIN ;[05] <- phase (one cycle too late) - ori shift, 1 << # ;[06] - - ifioset USBIN, USBMINUS ;[00] <--- sample - rjmp bit#IsSet ;[01] - andi shift, ~(7 << #) ;[02] - breq unstuff#c ;[03] - in phase, USBIN ;[04] <- phase - rjmp bit@AfterClr ;[05] -unstuff#c: - in phase, USBIN ;[05] <- phase (one cycle too late) - andi fix, ~(1 << #) ;[06] - nop2 ;[-1] - nop2 ;[01] -bit#IsSet: - ifrclr phase, USBMINUS ;[03] check phase only if D- changed - lpm ;[04] - in phase, USBIN ;[05] <- phase (one cycle too late) - ori shift, 1 << # ;[06] - -*****************************************************************************/ diff --git a/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm15.inc b/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm15.inc deleted file mode 100644 index 1016124..0000000 --- a/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm15.inc +++ /dev/null @@ -1,423 +0,0 @@ -/* Name: usbdrvasm15.inc - * Project: AVR USB driver - * Author: contributed by V. Bosch - * Creation Date: 2007-08-06 - * Tabsize: 4 - * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * Revision: $Id: usbdrvasm15.inc 692 2008-11-07 15:07:40Z cs $ - */ - -/* Do not link this file! Link usbdrvasm.S instead, which includes the - * appropriate implementation! - */ - -/* -General Description: -This file is the 15 MHz version of the asssembler part of the USB driver. It -requires a 15 MHz crystal (not a ceramic resonator and not a calibrated RC -oscillator). - -See usbdrv.h for a description of the entire driver. - -Since almost all of this code is timing critical, don't change unless you -really know what you are doing! Many parts require not only a maximum number -of CPU cycles, but even an exact number of cycles! -*/ - -;max stack usage: [ret(2), YL, SREG, YH, bitcnt, shift, x1, x2, x3, x4, cnt] = 12 bytes -;nominal frequency: 15 MHz -> 10.0 cycles per bit, 80.0 cycles per byte -; Numbers in brackets are clocks counted from center of last sync bit -; when instruction starts - -;---------------------------------------------------------------------------- -; order of registers pushed: -; YL, SREG [sofError] YH, shift, x1, x2, x3, bitcnt, cnt, x4 -;---------------------------------------------------------------------------- -USB_INTR_VECTOR: - push YL ;2 push only what is necessary to sync with edge ASAP - in YL, SREG ;1 - push YL ;2 -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -; -; sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -; sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -;------------------------------------------------------------------------------- -; The following code results in a sampling window of < 1/4 bit -; which meets the spec. -;------------------------------------------------------------------------------- -waitForK: ;- - sbis USBIN, USBMINUS ;1 [00] <-- sample - rjmp foundK ;2 [01] - sbis USBIN, USBMINUS ; <-- sample - rjmp foundK - sbis USBIN, USBMINUS ; <-- sample - rjmp foundK - sbis USBIN, USBMINUS ; <-- sample - rjmp foundK - sbis USBIN, USBMINUS ; <-- sample - rjmp foundK - sbis USBIN, USBMINUS ; <-- sample - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -;------------------------------------------------------------------------------ -; {3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for -; center sampling] -; we have 1 bit time for setup purposes, then sample again. -; Numbers in brackets are cycles from center of first sync (double K) -; bit after the instruction -;------------------------------------------------------------------------------ -foundK: ;- [02] - lds YL, usbInputBufOffset;2 [03+04] tx loop - push YH ;2 [05+06] - clr YH ;1 [07] - subi YL, lo8(-(usbRxBuf)) ;1 [08] [rx loop init] - sbci YH, hi8(-(usbRxBuf)) ;1 [09] [rx loop init] - push shift ;2 [10+11] - ser shift ;1 [12] - sbis USBIN, USBMINUS ;1 [-1] [13] <--sample:we want two bits K (sample 1 cycle too early) - rjmp haveTwoBitsK ;2 [00] [14] - pop shift ;2 [15+16] undo the push from before - pop YH ;2 [17+18] undo the push from before - rjmp waitForK ;2 [19+20] this was not the end of sync, retry -; The entire loop from waitForK until rjmp waitForK above must not exceed two -; bit times (= 20 cycles). - -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -haveTwoBitsK: ;- [01] - push x1 ;2 [02+03] - push x2 ;2 [04+05] - push x3 ;2 [06+07] - push bitcnt ;2 [08+09] - in x1, USBIN ;1 [00] [10] <-- sample bit 0 - bst x1, USBMINUS ;1 [01] - bld shift, 0 ;1 [02] - push cnt ;2 [03+04] - ldi cnt, USB_BUFSIZE ;1 [05] - push x4 ;2 [06+07] tx loop - rjmp rxLoop ;2 [08] -;---------------------------------------------------------------------------- -; Receiver loop (numbers in brackets are cycles within byte after instr) -;---------------------------------------------------------------------------- -unstuff0: ;- [07] (branch taken) - andi x3, ~0x01 ;1 [08] - mov x1, x2 ;1 [09] x2 contains last sampled (stuffed) bit - in x2, USBIN ;1 [00] [10] <-- sample bit 1 again - andi x2, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 1 - ori shift, 0x01 ;1 [03] 0b00000001 - nop ;1 [04] - rjmp didUnstuff0 ;2 [05] -;----------------------------------------------------- -unstuff1: ;- [05] (branch taken) - mov x2, x1 ;1 [06] x1 contains last sampled (stuffed) bit - andi x3, ~0x02 ;1 [07] - ori shift, 0x02 ;1 [08] 0b00000010 - nop ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample bit 2 again - andi x1, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 2 - rjmp didUnstuff1 ;2 [03] -;----------------------------------------------------- -unstuff2: ;- [05] (branch taken) - andi x3, ~0x04 ;1 [06] - ori shift, 0x04 ;1 [07] 0b00000100 - mov x1, x2 ;1 [08] x2 contains last sampled (stuffed) bit - nop ;1 [09] - in x2, USBIN ;1 [00] [10] <-- sample bit 3 - andi x2, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 3 - rjmp didUnstuff2 ;2 [03] -;----------------------------------------------------- -unstuff3: ;- [00] [10] (branch taken) - in x2, USBIN ;1 [01] [11] <-- sample stuffed bit 3 one cycle too late - andi x2, USBMASK ;1 [02] - breq se0Hop ;1 [03] SE0 check for stuffed bit 3 - andi x3, ~0x08 ;1 [04] - ori shift, 0x08 ;1 [05] 0b00001000 - rjmp didUnstuff3 ;2 [06] -;---------------------------------------------------------------------------- -; extra jobs done during bit interval: -; -; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs], -; overflow check, jump to the head of rxLoop -; bit 1: SE0 check -; bit 2: SE0 check, recovery from delay [bit 0 tasks took too long] -; bit 3: SE0 check, recovery from delay [bit 0 tasks took too long] -; bit 4: SE0 check, none -; bit 5: SE0 check, none -; bit 6: SE0 check, none -; bit 7: SE0 check, reconstruct: x3 is 0 at bit locations we changed, 1 at others -;---------------------------------------------------------------------------- -rxLoop: ;- [09] - in x2, USBIN ;1 [00] [10] <-- sample bit 1 (or possibly bit 0 stuffed) - andi x2, USBMASK ;1 [01] - brne SkipSe0Hop ;1 [02] -se0Hop: ;- [02] - rjmp se0 ;2 [03] SE0 check for bit 1 -SkipSe0Hop: ;- [03] - ser x3 ;1 [04] - andi shift, 0xf9 ;1 [05] 0b11111001 - breq unstuff0 ;1 [06] -didUnstuff0: ;- [06] - eor x1, x2 ;1 [07] - bst x1, USBMINUS ;1 [08] - bld shift, 1 ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample bit 2 (or possibly bit 1 stuffed) - andi x1, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 2 - andi shift, 0xf3 ;1 [03] 0b11110011 - breq unstuff1 ;1 [04] do remaining work for bit 1 -didUnstuff1: ;- [04] - eor x2, x1 ;1 [05] - bst x2, USBMINUS ;1 [06] - bld shift, 2 ;1 [07] - nop2 ;2 [08+09] - in x2, USBIN ;1 [00] [10] <-- sample bit 3 (or possibly bit 2 stuffed) - andi x2, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 3 - andi shift, 0xe7 ;1 [03] 0b11100111 - breq unstuff2 ;1 [04] -didUnstuff2: ;- [04] - eor x1, x2 ;1 [05] - bst x1, USBMINUS ;1 [06] - bld shift, 3 ;1 [07] -didUnstuff3: ;- [07] - andi shift, 0xcf ;1 [08] 0b11001111 - breq unstuff3 ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample bit 4 - andi x1, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 4 - eor x2, x1 ;1 [03] - bst x2, USBMINUS ;1 [04] - bld shift, 4 ;1 [05] -didUnstuff4: ;- [05] - andi shift, 0x9f ;1 [06] 0b10011111 - breq unstuff4 ;1 [07] - nop2 ;2 [08+09] - in x2, USBIN ;1 [00] [10] <-- sample bit 5 - andi x2, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for bit 5 - eor x1, x2 ;1 [03] - bst x1, USBMINUS ;1 [04] - bld shift, 5 ;1 [05] -didUnstuff5: ;- [05] - andi shift, 0x3f ;1 [06] 0b00111111 - breq unstuff5 ;1 [07] - nop2 ;2 [08+09] - in x1, USBIN ;1 [00] [10] <-- sample bit 6 - andi x1, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for bit 6 - eor x2, x1 ;1 [03] - bst x2, USBMINUS ;1 [04] - bld shift, 6 ;1 [05] -didUnstuff6: ;- [05] - cpi shift, 0x02 ;1 [06] 0b00000010 - brlo unstuff6 ;1 [07] - nop2 ;2 [08+09] - in x2, USBIN ;1 [00] [10] <-- sample bit 7 - andi x2, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for bit 7 - eor x1, x2 ;1 [03] - bst x1, USBMINUS ;1 [04] - bld shift, 7 ;1 [05] -didUnstuff7: ;- [05] - cpi shift, 0x04 ;1 [06] 0b00000100 - brlo unstuff7 ;1 [07] - eor x3, shift ;1 [08] reconstruct: x3 is 0 at bit locations we changed, 1 at others - nop ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample bit 0 - st y+, x3 ;2 [01+02] store data - eor x2, x1 ;1 [03] - bst x2, USBMINUS ;1 [04] - bld shift, 0 ;1 [05] - subi cnt, 1 ;1 [06] - brcs overflow ;1 [07] - rjmp rxLoop ;2 [08] -;----------------------------------------------------- -unstuff4: ;- [08] - andi x3, ~0x10 ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 4 - andi x1, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for stuffed bit 4 - ori shift, 0x10 ;1 [03] - rjmp didUnstuff4 ;2 [04] -;----------------------------------------------------- -unstuff5: ;- [08] - ori shift, 0x20 ;1 [09] - in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 5 - andi x2, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for stuffed bit 5 - andi x3, ~0x20 ;1 [03] - rjmp didUnstuff5 ;2 [04] -;----------------------------------------------------- -unstuff6: ;- [08] - andi x3, ~0x40 ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 6 - andi x1, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for stuffed bit 6 - ori shift, 0x40 ;1 [03] - rjmp didUnstuff6 ;2 [04] -;----------------------------------------------------- -unstuff7: ;- [08] - andi x3, ~0x80 ;1 [09] - in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 7 - andi x2, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for stuffed bit 7 - ori shift, 0x80 ;1 [03] - rjmp didUnstuff7 ;2 [04] - -macro POP_STANDARD ; 16 cycles - pop x4 - pop cnt - pop bitcnt - pop x3 - pop x2 - pop x1 - pop shift - pop YH - endm -macro POP_RETI ; 5 cycles - pop YL - out SREG, YL - pop YL - endm - -#include "asmcommon.inc" - -;--------------------------------------------------------------------------- -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) -; K = (D+ = 1), (D- = 0) -; Spec allows 7.5 bit times from EOP to SOP for replies -;--------------------------------------------------------------------------- -bitstuffN: ;- [04] - eor x1, x4 ;1 [05] - clr x2 ;1 [06] - nop ;1 [07] - rjmp didStuffN ;1 [08] -;--------------------------------------------------------------------------- -bitstuff6: ;- [04] - eor x1, x4 ;1 [05] - clr x2 ;1 [06] - rjmp didStuff6 ;1 [07] -;--------------------------------------------------------------------------- -bitstuff7: ;- [02] - eor x1, x4 ;1 [03] - clr x2 ;1 [06] - nop ;1 [05] - rjmp didStuff7 ;1 [06] -;--------------------------------------------------------------------------- -sendNakAndReti: ;- [-19] - ldi x3, USBPID_NAK ;1 [-18] - rjmp sendX3AndReti ;1 [-17] -;--------------------------------------------------------------------------- -sendAckAndReti: ;- [-17] - ldi cnt, USBPID_ACK ;1 [-16] -sendCntAndReti: ;- [-16] - mov x3, cnt ;1 [-15] -sendX3AndReti: ;- [-15] - ldi YL, 20 ;1 [-14] x3==r20 address is 20 - ldi YH, 0 ;1 [-13] - ldi cnt, 2 ;1 [-12] -; rjmp usbSendAndReti fallthrough -;--------------------------------------------------------------------------- -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] -;uses: x1...x4, btcnt, shift, cnt, Y -;Numbers in brackets are time since first bit of sync pattern is sent -;We need not to match the transfer rate exactly because the spec demands -;only 1.5% precision anyway. -usbSendAndReti: ;- [-13] 13 cycles until SOP - in x2, USBDDR ;1 [-12] - ori x2, USBMASK ;1 [-11] - sbi USBOUT, USBMINUS ;2 [-09-10] prepare idle state; D+ and D- must have been 0 (no pullups) - in x1, USBOUT ;1 [-08] port mirror for tx loop - out USBDDR, x2 ;1 [-07] <- acquire bus - ; need not init x2 (bitstuff history) because sync starts with 0 - ldi x4, USBMASK ;1 [-06] exor mask - ldi shift, 0x80 ;1 [-05] sync byte is first byte sent - ldi bitcnt, 6 ;1 [-04] -txBitLoop: ;- [-04] [06] - sbrs shift, 0 ;1 [-03] [07] - eor x1, x4 ;1 [-02] [08] - ror shift ;1 [-01] [09] -didStuffN: ;- [09] - out USBOUT, x1 ;1 [00] [10] <-- out N - ror x2 ;1 [01] - cpi x2, 0xfc ;1 [02] - brcc bitstuffN ;1 [03] - dec bitcnt ;1 [04] - brne txBitLoop ;1 [05] - sbrs shift, 0 ;1 [06] - eor x1, x4 ;1 [07] - ror shift ;1 [08] -didStuff6: ;- [08] - nop ;1 [09] - out USBOUT, x1 ;1 [00] [10] <-- out 6 - ror x2 ;1 [01] - cpi x2, 0xfc ;1 [02] - brcc bitstuff6 ;1 [03] - sbrs shift, 0 ;1 [04] - eor x1, x4 ;1 [05] - ror shift ;1 [06] - ror x2 ;1 [07] -didStuff7: ;- [07] - ldi bitcnt, 6 ;1 [08] - cpi x2, 0xfc ;1 [09] - out USBOUT, x1 ;1 [00] [10] <-- out 7 - brcc bitstuff7 ;1 [01] - ld shift, y+ ;2 [02+03] - dec cnt ;1 [04] - brne txBitLoop ;1 [05] -makeSE0: - cbr x1, USBMASK ;1 [06] prepare SE0 [spec says EOP may be 19 to 23 cycles] - lds x2, usbNewDeviceAddr;2 [07+08] - lsl x2 ;1 [09] we compare with left shifted address -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - out USBOUT, x1 ;1 [00] [10] <-- out SE0-- from now 2 bits==20 cycl. until bus idle - subi YL, 20 + 2 ;1 [01] Only assign address on data packets, not ACK/NAK in x3 - sbci YH, 0 ;1 [02] - breq skipAddrAssign ;1 [03] - sts usbDeviceAddr, x2 ;2 [04+05] if not skipped: SE0 is one cycle longer -;---------------------------------------------------------------------------- -;end of usbDeviceAddress transfer -skipAddrAssign: ;- [03/04] - ldi x2, 1< 10.6666666 cycles per bit, 85.333333333 cycles per byte -; Numbers in brackets are clocks counted from center of last sync bit -; when instruction starts - -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt - push YL ;[-25] push only what is necessary to sync with edge ASAP - in YL, SREG ;[-23] - push YL ;[-22] - push YH ;[-20] -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of < 1/4 bit which meets the spec. - sbis USBIN, USBMINUS ;[-15] - rjmp foundK ;[-14] - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -foundK: ;[-12] -;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling] -;we have 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push bitcnt ;[-12] -; [---] ;[-11] - lds YL, usbInputBufOffset;[-10] -; [---] ;[-9] - clr YH ;[-8] - subi YL, lo8(-(usbRxBuf));[-7] [rx loop init] - sbci YH, hi8(-(usbRxBuf));[-6] [rx loop init] - push shift ;[-5] -; [---] ;[-4] - ldi bitcnt, 0x55 ;[-3] [rx loop init] - sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early) - rjmp haveTwoBitsK ;[-1] - pop shift ;[0] undo the push from before - pop bitcnt ;[2] undo the push from before - rjmp waitForK ;[4] this was not the end of sync, retry -; The entire loop from waitForK until rjmp waitForK above must not exceed two -; bit times (= 21 cycles). - -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -haveTwoBitsK: - push x1 ;[1] - push x2 ;[3] - push x3 ;[5] - ldi shift, 0 ;[7] - ldi x3, 1<<4 ;[8] [rx loop init] first sample is inverse bit, compensate that - push x4 ;[9] == leap - - in x1, USBIN ;[11] <-- sample bit 0 - andi x1, USBMASK ;[12] - bst x1, USBMINUS ;[13] - bld shift, 7 ;[14] - push cnt ;[15] - ldi leap, 0 ;[17] [rx loop init] - ldi cnt, USB_BUFSIZE;[18] [rx loop init] - rjmp rxbit1 ;[19] arrives at [21] - -;---------------------------------------------------------------------------- -; Receiver loop (numbers in brackets are cycles within byte after instr) -;---------------------------------------------------------------------------- - -unstuff6: - andi x2, USBMASK ;[03] - ori x3, 1<<6 ;[04] will not be shifted any more - andi shift, ~0x80;[05] - mov x1, x2 ;[06] sampled bit 7 is actually re-sampled bit 6 - subi leap, 3 ;[07] since this is a short (10 cycle) bit, enforce leap bit - rjmp didUnstuff6 ;[08] - -unstuff7: - ori x3, 1<<7 ;[09] will not be shifted any more - in x2, USBIN ;[00] [10] re-sample bit 7 - andi x2, USBMASK ;[01] - andi shift, ~0x80;[02] - subi leap, 3 ;[03] since this is a short (10 cycle) bit, enforce leap bit - rjmp didUnstuff7 ;[04] - -unstuffEven: - ori x3, 1<<6 ;[09] will be shifted right 6 times for bit 0 - in x1, USBIN ;[00] [10] - andi shift, ~0x80;[01] - andi x1, USBMASK ;[02] - breq se0 ;[03] - subi leap, 3 ;[04] since this is a short (10 cycle) bit, enforce leap bit - nop ;[05] - rjmp didUnstuffE ;[06] - -unstuffOdd: - ori x3, 1<<5 ;[09] will be shifted right 4 times for bit 1 - in x2, USBIN ;[00] [10] - andi shift, ~0x80;[01] - andi x2, USBMASK ;[02] - breq se0 ;[03] - subi leap, 3 ;[04] since this is a short (10 cycle) bit, enforce leap bit - nop ;[05] - rjmp didUnstuffO ;[06] - -rxByteLoop: - andi x1, USBMASK ;[03] - eor x2, x1 ;[04] - subi leap, 1 ;[05] - brpl skipLeap ;[06] - subi leap, -3 ;1 one leap cycle every 3rd byte -> 85 + 1/3 cycles per byte - nop ;1 -skipLeap: - subi x2, 1 ;[08] - ror shift ;[09] -didUnstuff6: - cpi shift, 0xfc ;[10] - in x2, USBIN ;[00] [11] <-- sample bit 7 - brcc unstuff6 ;[01] - andi x2, USBMASK ;[02] - eor x1, x2 ;[03] - subi x1, 1 ;[04] - ror shift ;[05] -didUnstuff7: - cpi shift, 0xfc ;[06] - brcc unstuff7 ;[07] - eor x3, shift ;[08] reconstruct: x3 is 1 at bit locations we changed, 0 at others - st y+, x3 ;[09] store data -rxBitLoop: - in x1, USBIN ;[00] [11] <-- sample bit 0/2/4 - andi x1, USBMASK ;[01] - eor x2, x1 ;[02] - andi x3, 0x3f ;[03] topmost two bits reserved for 6 and 7 - subi x2, 1 ;[04] - ror shift ;[05] - cpi shift, 0xfc ;[06] - brcc unstuffEven ;[07] -didUnstuffE: - lsr x3 ;[08] - lsr x3 ;[09] -rxbit1: - in x2, USBIN ;[00] [10] <-- sample bit 1/3/5 - andi x2, USBMASK ;[01] - breq se0 ;[02] - eor x1, x2 ;[03] - subi x1, 1 ;[04] - ror shift ;[05] - cpi shift, 0xfc ;[06] - brcc unstuffOdd ;[07] -didUnstuffO: - subi bitcnt, 0xab;[08] == addi 0x55, 0x55 = 0x100/3 - brcs rxBitLoop ;[09] - - subi cnt, 1 ;[10] - in x1, USBIN ;[00] [11] <-- sample bit 6 - brcc rxByteLoop ;[01] - rjmp overflow - -macro POP_STANDARD ; 14 cycles - pop cnt - pop x4 - pop x3 - pop x2 - pop x1 - pop shift - pop bitcnt - endm -macro POP_RETI ; 7 cycles - pop YH - pop YL - out SREG, YL - pop YL - endm - -#include "asmcommon.inc" - -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) -; K = (D+ = 1), (D- = 0) -; Spec allows 7.5 bit times from EOP to SOP for replies - -bitstuffN: - eor x1, x4 ;[5] - ldi x2, 0 ;[6] - nop2 ;[7] - nop ;[9] - out USBOUT, x1 ;[10] <-- out - rjmp didStuffN ;[0] - -bitstuff6: - eor x1, x4 ;[5] - ldi x2, 0 ;[6] Carry is zero due to brcc - rol shift ;[7] compensate for ror shift at branch destination - rjmp didStuff6 ;[8] - -bitstuff7: - ldi x2, 0 ;[2] Carry is zero due to brcc - rjmp didStuff7 ;[3] - - -sendNakAndReti: - ldi x3, USBPID_NAK ;[-18] - rjmp sendX3AndReti ;[-17] -sendAckAndReti: - ldi cnt, USBPID_ACK ;[-17] -sendCntAndReti: - mov x3, cnt ;[-16] -sendX3AndReti: - ldi YL, 20 ;[-15] x3==r20 address is 20 - ldi YH, 0 ;[-14] - ldi cnt, 2 ;[-13] -; rjmp usbSendAndReti fallthrough - -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] -;uses: x1...x4, btcnt, shift, cnt, Y -;Numbers in brackets are time since first bit of sync pattern is sent -;We don't match the transfer rate exactly (don't insert leap cycles every third -;byte) because the spec demands only 1.5% precision anyway. -usbSendAndReti: ; 12 cycles until SOP - in x2, USBDDR ;[-12] - ori x2, USBMASK ;[-11] - sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) - in x1, USBOUT ;[-8] port mirror for tx loop - out USBDDR, x2 ;[-7] <- acquire bus -; need not init x2 (bitstuff history) because sync starts with 0 - ldi x4, USBMASK ;[-6] exor mask - ldi shift, 0x80 ;[-5] sync byte is first byte sent -txByteLoop: - ldi bitcnt, 0x35 ;[-4] [6] binary 0011 0101 -txBitLoop: - sbrs shift, 0 ;[-3] [7] - eor x1, x4 ;[-2] [8] - out USBOUT, x1 ;[-1] [9] <-- out N - ror shift ;[0] [10] - ror x2 ;[1] -didStuffN: - cpi x2, 0xfc ;[2] - brcc bitstuffN ;[3] - lsr bitcnt ;[4] - brcc txBitLoop ;[5] - brne txBitLoop ;[6] - - sbrs shift, 0 ;[7] - eor x1, x4 ;[8] -didStuff6: - out USBOUT, x1 ;[-1] [9] <-- out 6 - ror shift ;[0] [10] - ror x2 ;[1] - cpi x2, 0xfc ;[2] - brcc bitstuff6 ;[3] - ror shift ;[4] -didStuff7: - ror x2 ;[5] - sbrs x2, 7 ;[6] - eor x1, x4 ;[7] - nop ;[8] - cpi x2, 0xfc ;[9] - out USBOUT, x1 ;[-1][10] <-- out 7 - brcc bitstuff7 ;[0] [11] - ld shift, y+ ;[1] - dec cnt ;[3] - brne txByteLoop ;[4] -;make SE0: - cbr x1, USBMASK ;[5] prepare SE0 [spec says EOP may be 21 to 25 cycles] - lds x2, usbNewDeviceAddr;[6] - lsl x2 ;[8] we compare with left shifted address - subi YL, 20 + 2 ;[9] Only assign address on data packets, not ACK/NAK in x3 - sbci YH, 0 ;[10] - out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - breq skipAddrAssign ;[0] - sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer -skipAddrAssign: -;end of usbDeviceAddress transfer - ldi x2, 1< max 52 cycles interrupt disable -;max stack usage: [ret(2), r0, SREG, YL, YH, shift, x1, x2, x3, x4, cnt] = 12 bytes -;nominal frequency: 16.5 MHz -> 11 cycles per bit -; 16.3125 MHz < F_CPU < 16.6875 MHz (+/- 1.1%) -; Numbers in brackets are clocks counted from center of last sync bit -; when instruction starts - - -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG [sofError], r0, YH, shift, x1, x2, x3, x4, cnt - push YL ;[-23] push only what is necessary to sync with edge ASAP - in YL, SREG ;[-21] - push YL ;[-20] -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of < 1/4 bit which meets the spec. - sbis USBIN, USBMINUS ;[-15] - rjmp foundK ;[-14] - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -foundK: ;[-12] -;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling] -;we have 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push r0 ;[-12] -; [---] ;[-11] - push YH ;[-10] -; [---] ;[-9] - lds YL, usbInputBufOffset;[-8] -; [---] ;[-7] - clr YH ;[-6] - subi YL, lo8(-(usbRxBuf));[-5] [rx loop init] - sbci YH, hi8(-(usbRxBuf));[-4] [rx loop init] - mov r0, x2 ;[-3] [rx loop init] - sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early) - rjmp haveTwoBitsK ;[-1] - pop YH ;[0] undo the pushes from before - pop r0 ;[2] - rjmp waitForK ;[4] this was not the end of sync, retry -; The entire loop from waitForK until rjmp waitForK above must not exceed two -; bit times (= 22 cycles). - -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -haveTwoBitsK: ;[1] - push shift ;[1] - push x1 ;[3] - push x2 ;[5] - push x3 ;[7] - ldi shift, 0xff ;[9] [rx loop init] - ori x3, 0xff ;[10] [rx loop init] == ser x3, clear zero flag - - in x1, USBIN ;[11] <-- sample bit 0 - bst x1, USBMINUS ;[12] - bld shift, 0 ;[13] - push x4 ;[14] == phase -; [---] ;[15] - push cnt ;[16] -; [---] ;[17] - ldi phase, 0 ;[18] [rx loop init] - ldi cnt, USB_BUFSIZE;[19] [rx loop init] - rjmp rxbit1 ;[20] -; [---] ;[21] - -;---------------------------------------------------------------------------- -; Receiver loop (numbers in brackets are cycles within byte after instr) -;---------------------------------------------------------------------------- -/* -byte oriented operations done during loop: -bit 0: store data -bit 1: SE0 check -bit 2: overflow check -bit 3: catch up -bit 4: rjmp to achieve conditional jump range -bit 5: PLL -bit 6: catch up -bit 7: jump, fixup bitstuff -; 87 [+ 2] cycles ------------------------------------------------------------------- -*/ -continueWithBit5: - in x2, USBIN ;[055] <-- bit 5 - eor r0, x2 ;[056] - or phase, r0 ;[057] - sbrc phase, USBMINUS ;[058] - lpm ;[059] optional nop3; modifies r0 - in phase, USBIN ;[060] <-- phase - eor x1, x2 ;[061] - bst x1, USBMINUS ;[062] - bld shift, 5 ;[063] - andi shift, 0x3f ;[064] - in x1, USBIN ;[065] <-- bit 6 - breq unstuff5 ;[066] *** unstuff escape - eor phase, x1 ;[067] - eor x2, x1 ;[068] - bst x2, USBMINUS ;[069] - bld shift, 6 ;[070] -didUnstuff6: ;[ ] - in r0, USBIN ;[071] <-- phase - cpi shift, 0x02 ;[072] - brlo unstuff6 ;[073] *** unstuff escape -didUnstuff5: ;[ ] - nop2 ;[074] -; [---] ;[075] - in x2, USBIN ;[076] <-- bit 7 - eor x1, x2 ;[077] - bst x1, USBMINUS ;[078] - bld shift, 7 ;[079] -didUnstuff7: ;[ ] - eor r0, x2 ;[080] - or phase, r0 ;[081] - in r0, USBIN ;[082] <-- phase - cpi shift, 0x04 ;[083] - brsh rxLoop ;[084] -; [---] ;[085] -unstuff7: ;[ ] - andi x3, ~0x80 ;[085] - ori shift, 0x80 ;[086] - in x2, USBIN ;[087] <-- sample stuffed bit 7 - nop ;[088] - rjmp didUnstuff7 ;[089] -; [---] ;[090] - ;[080] - -unstuff5: ;[067] - eor phase, x1 ;[068] - andi x3, ~0x20 ;[069] - ori shift, 0x20 ;[070] - in r0, USBIN ;[071] <-- phase - mov x2, x1 ;[072] - nop ;[073] - nop2 ;[074] -; [---] ;[075] - in x1, USBIN ;[076] <-- bit 6 - eor r0, x1 ;[077] - or phase, r0 ;[078] - eor x2, x1 ;[079] - bst x2, USBMINUS ;[080] - bld shift, 6 ;[081] no need to check bitstuffing, we just had one - in r0, USBIN ;[082] <-- phase - rjmp didUnstuff5 ;[083] -; [---] ;[084] - ;[074] - -unstuff6: ;[074] - andi x3, ~0x40 ;[075] - in x1, USBIN ;[076] <-- bit 6 again - ori shift, 0x40 ;[077] - nop2 ;[078] -; [---] ;[079] - rjmp didUnstuff6 ;[080] -; [---] ;[081] - ;[071] - -unstuff0: ;[013] - eor r0, x2 ;[014] - or phase, r0 ;[015] - andi x2, USBMASK ;[016] check for SE0 - in r0, USBIN ;[017] <-- phase - breq didUnstuff0 ;[018] direct jump to se0 would be too long - andi x3, ~0x01 ;[019] - ori shift, 0x01 ;[020] - mov x1, x2 ;[021] mov existing sample - in x2, USBIN ;[022] <-- bit 1 again - rjmp didUnstuff0 ;[023] -; [---] ;[024] - ;[014] - -unstuff1: ;[024] - eor r0, x1 ;[025] - or phase, r0 ;[026] - andi x3, ~0x02 ;[027] - in r0, USBIN ;[028] <-- phase - ori shift, 0x02 ;[029] - mov x2, x1 ;[030] - rjmp didUnstuff1 ;[031] -; [---] ;[032] - ;[022] - -unstuff2: ;[035] - eor r0, x2 ;[036] - or phase, r0 ;[037] - andi x3, ~0x04 ;[038] - in r0, USBIN ;[039] <-- phase - ori shift, 0x04 ;[040] - mov x1, x2 ;[041] - rjmp didUnstuff2 ;[042] -; [---] ;[043] - ;[033] - -unstuff3: ;[043] - in x2, USBIN ;[044] <-- bit 3 again - eor r0, x2 ;[045] - or phase, r0 ;[046] - andi x3, ~0x08 ;[047] - ori shift, 0x08 ;[048] - nop ;[049] - in r0, USBIN ;[050] <-- phase - rjmp didUnstuff3 ;[051] -; [---] ;[052] - ;[042] - -unstuff4: ;[053] - andi x3, ~0x10 ;[054] - in x1, USBIN ;[055] <-- bit 4 again - ori shift, 0x10 ;[056] - rjmp didUnstuff4 ;[057] -; [---] ;[058] - ;[048] - -rxLoop: ;[085] - eor x3, shift ;[086] reconstruct: x3 is 0 at bit locations we changed, 1 at others - in x1, USBIN ;[000] <-- bit 0 - st y+, x3 ;[001] -; [---] ;[002] - eor r0, x1 ;[003] - or phase, r0 ;[004] - eor x2, x1 ;[005] - in r0, USBIN ;[006] <-- phase - ser x3 ;[007] - bst x2, USBMINUS ;[008] - bld shift, 0 ;[009] - andi shift, 0xf9 ;[010] -rxbit1: ;[ ] - in x2, USBIN ;[011] <-- bit 1 - breq unstuff0 ;[012] *** unstuff escape - andi x2, USBMASK ;[013] SE0 check for bit 1 -didUnstuff0: ;[ ] Z only set if we detected SE0 in bitstuff - breq se0 ;[014] - eor r0, x2 ;[015] - or phase, r0 ;[016] - in r0, USBIN ;[017] <-- phase - eor x1, x2 ;[018] - bst x1, USBMINUS ;[019] - bld shift, 1 ;[020] - andi shift, 0xf3 ;[021] -didUnstuff1: ;[ ] - in x1, USBIN ;[022] <-- bit 2 - breq unstuff1 ;[023] *** unstuff escape - eor r0, x1 ;[024] - or phase, r0 ;[025] - subi cnt, 1 ;[026] overflow check - brcs overflow ;[027] - in r0, USBIN ;[028] <-- phase - eor x2, x1 ;[029] - bst x2, USBMINUS ;[030] - bld shift, 2 ;[031] - andi shift, 0xe7 ;[032] -didUnstuff2: ;[ ] - in x2, USBIN ;[033] <-- bit 3 - breq unstuff2 ;[034] *** unstuff escape - eor r0, x2 ;[035] - or phase, r0 ;[036] - eor x1, x2 ;[037] - bst x1, USBMINUS ;[038] - in r0, USBIN ;[039] <-- phase - bld shift, 3 ;[040] - andi shift, 0xcf ;[041] -didUnstuff3: ;[ ] - breq unstuff3 ;[042] *** unstuff escape - nop ;[043] - in x1, USBIN ;[044] <-- bit 4 - eor x2, x1 ;[045] - bst x2, USBMINUS ;[046] - bld shift, 4 ;[047] -didUnstuff4: ;[ ] - eor r0, x1 ;[048] - or phase, r0 ;[049] - in r0, USBIN ;[050] <-- phase - andi shift, 0x9f ;[051] - breq unstuff4 ;[052] *** unstuff escape - rjmp continueWithBit5;[053] -; [---] ;[054] - -macro POP_STANDARD ; 16 cycles - pop cnt - pop x4 - pop x3 - pop x2 - pop x1 - pop shift - pop YH - pop r0 - endm -macro POP_RETI ; 5 cycles - pop YL - out SREG, YL - pop YL - endm - -#include "asmcommon.inc" - - -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) -; K = (D+ = 1), (D- = 0) -; Spec allows 7.5 bit times from EOP to SOP for replies - -bitstuff7: - eor x1, x4 ;[4] - ldi x2, 0 ;[5] - nop2 ;[6] C is zero (brcc) - rjmp didStuff7 ;[8] - -bitstuffN: - eor x1, x4 ;[5] - ldi x2, 0 ;[6] - lpm ;[7] 3 cycle NOP, modifies r0 - out USBOUT, x1 ;[10] <-- out - rjmp didStuffN ;[0] - -#define bitStatus x3 - -sendNakAndReti: - ldi cnt, USBPID_NAK ;[-19] - rjmp sendCntAndReti ;[-18] -sendAckAndReti: - ldi cnt, USBPID_ACK ;[-17] -sendCntAndReti: - mov r0, cnt ;[-16] - ldi YL, 0 ;[-15] R0 address is 0 - ldi YH, 0 ;[-14] - ldi cnt, 2 ;[-13] -; rjmp usbSendAndReti fallthrough - -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] -;uses: x1...x4, shift, cnt, Y -;Numbers in brackets are time since first bit of sync pattern is sent -usbSendAndReti: ; 12 cycles until SOP - in x2, USBDDR ;[-12] - ori x2, USBMASK ;[-11] - sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) - in x1, USBOUT ;[-8] port mirror for tx loop - out USBDDR, x2 ;[-7] <- acquire bus -; need not init x2 (bitstuff history) because sync starts with 0 - ldi x4, USBMASK ;[-6] exor mask - ldi shift, 0x80 ;[-5] sync byte is first byte sent - ldi bitStatus, 0xff ;[-4] init bit loop counter, works for up to 12 bytes -byteloop: -bitloop: - sbrs shift, 0 ;[8] [-3] - eor x1, x4 ;[9] [-2] - out USBOUT, x1 ;[10] [-1] <-- out - ror shift ;[0] - ror x2 ;[1] -didStuffN: - cpi x2, 0xfc ;[2] - brcc bitstuffN ;[3] - nop ;[4] - subi bitStatus, 37 ;[5] 256 / 7 ~=~ 37 - brcc bitloop ;[6] when we leave the loop, bitStatus has almost the initial value - sbrs shift, 0 ;[7] - eor x1, x4 ;[8] - ror shift ;[9] -didStuff7: - out USBOUT, x1 ;[10] <-- out - ror x2 ;[0] - cpi x2, 0xfc ;[1] - brcc bitstuff7 ;[2] - ld shift, y+ ;[3] - dec cnt ;[5] - brne byteloop ;[6] -;make SE0: - cbr x1, USBMASK ;[7] prepare SE0 [spec says EOP may be 21 to 25 cycles] - lds x2, usbNewDeviceAddr;[8] - lsl x2 ;[10] we compare with left shifted address - out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - subi YL, 2 ;[0] Only assign address on data packets, not ACK/NAK in r0 - sbci YH, 0 ;[1] - breq skipAddrAssign ;[2] - sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer -skipAddrAssign: -;end of usbDeviceAddress transfer - ldi x2, 1< 12 cycles per bit -; Numbers in brackets are clocks counted from center of last sync bit -; when instruction starts -;register use in receive loop to receive the data bytes: -; shift assembles the byte currently being received -; x1 holds the D+ and D- line state -; x2 holds the previous line state -; cnt holds the number of bytes left in the receive buffer -; x3 holds the higher crc byte (see algorithm below) -; x4 is used as temporary register for the crc algorithm -; x5 is used for unstuffing: when unstuffing the last received bit is inverted in shift (to prevent further -; unstuffing calls. In the same time the corresponding bit in x5 is cleared to mark the bit as beening iverted -; zl lower crc value and crc table index -; zh used for crc table accesses - -;-------------------------------------------------------------------------------------------------------------- -; CRC mods: -; table driven crc checker, Z points to table in prog space -; ZL is the lower crc byte, x3 is the higher crc byte -; x4 is used as temp register to store different results -; the initialization of the crc register is not 0xFFFF but 0xFE54. This is because during the receipt of the -; first data byte an virtual zero data byte is added to the crc register, this results in the correct initial -; value of 0xFFFF at beginning of the second data byte before the first data byte is added to the crc. -; The magic number 0xFE54 results form the crc table: At tabH[0x54] = 0xFF = crcH (required) and -; tabL[0x54] = 0x01 -> crcL = 0x01 xor 0xFE = 0xFF -; bitcnt is renamed to x5 and is used for unstuffing purposes, the unstuffing works like in the 12MHz version -;-------------------------------------------------------------------------------------------------------------- -; CRC algorithm: -; The crc register is formed by x3 (higher byte) and ZL (lower byte). The algorithm uses a 'reversed' form -; i.e. that it takes the least significant bit first and shifts to the right. So in fact the highest order -; bit seen from the polynomial devision point of view is the lsb of ZL. (If this sounds strange to you i -; propose a research on CRC :-) ) -; Each data byte received is xored to ZL, the lower crc byte. This byte now builds the crc -; table index. Next the new high byte is loaded from the table and stored in x4 until we have space in x3 -; (its destination). -; Afterwards the lower table is loaded from the table and stored in ZL (the old index is overwritten as -; we don't need it anymore. In fact this is a right shift by 8 bits.) Now the old crc high value is xored -; to ZL, this is the second shift of the old crc value. Now x4 (the temp reg) is moved to x3 and the crc -; calculation is done. -; Prior to the first byte the two CRC register have to be initialized to 0xFFFF (as defined in usb spec) -; however the crc engine also runs during the receipt of the first byte, therefore x3 and zl are initialized -; to a magic number which results in a crc value of 0xFFFF after the first complete byte. -; -; This algorithm is split into the extra cycles of the different bits: -; bit7: XOR the received byte to ZL -; bit5: load the new high byte to x4 -; bit6: load the lower xor byte from the table, xor zl and x3, store result in zl (=the new crc low value) -; move x4 (the new high byte) to x3, the crc value is ready -; - - -macro POP_STANDARD ; 18 cycles - pop ZH - pop ZL - pop cnt - pop x5 - pop x3 - pop x2 - pop x1 - pop shift - pop x4 - endm -macro POP_RETI ; 7 cycles - pop YH - pop YL - out SREG, YL - pop YL - endm - -macro CRC_CLEANUP_AND_CHECK - ; the last byte has already been xored with the lower crc byte, we have to do the table lookup and xor - ; x3 is the higher crc byte, zl the lower one - ldi ZH, hi8(usbCrcTableHigh);[+1] get the new high byte from the table - lpm x2, Z ;[+2][+3][+4] - ldi ZH, hi8(usbCrcTableLow);[+5] get the new low xor byte from the table - lpm ZL, Z ;[+6][+7][+8] - eor ZL, x3 ;[+7] xor the old high byte with the value from the table, x2:ZL now holds the crc value - cpi ZL, 0x01 ;[+8] if the crc is ok we have a fixed remainder value of 0xb001 in x2:ZL (see usb spec) - brne ignorePacket ;[+9] detected a crc fault -> paket is ignored and retransmitted by the host - cpi x2, 0xb0 ;[+10] - brne ignorePacket ;[+11] detected a crc fault -> paket is ignored and retransmitted by the host - endm - - -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG, YH, [sofError], x4, shift, x1, x2, x3, x5, cnt, ZL, ZH - push YL ;[-28] push only what is necessary to sync with edge ASAP - in YL, SREG ;[-26] - push YL ;[-25] - push YH ;[-23] -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of < 1/4 bit which meets the spec. - sbis USBIN, USBMINUS ;[-17] - rjmp foundK ;[-16] - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -foundK: ;[-15] -;{3, 5} after falling D- edge, average delay: 4 cycles -;bit0 should be at 30 (2.5 bits) for center sampling. Currently at 4 so 26 cylces till bit 0 sample -;use 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push x4 ;[-14] -; [---] ;[-13] - lds YL, usbInputBufOffset;[-12] used to toggle the two usb receive buffers -; [---] ;[-11] - clr YH ;[-10] - subi YL, lo8(-(usbRxBuf));[-9] [rx loop init] - sbci YH, hi8(-(usbRxBuf));[-8] [rx loop init] - push shift ;[-7] -; [---] ;[-6] - ldi shift, 0x80 ;[-5] the last bit is the end of byte marker for the pid receiver loop - clc ;[-4] the carry has to be clear for receipt of pid bit 0 - sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early) - rjmp haveTwoBitsK ;[-2] - pop shift ;[-1] undo the push from before - pop x4 ;[1] - rjmp waitForK ;[3] this was not the end of sync, retry -; The entire loop from waitForK until rjmp waitForK above must not exceed two -; bit times (= 24 cycles). - -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -haveTwoBitsK: - push x1 ;[0] - push x2 ;[2] - push x3 ;[4] crc high byte - ldi x2, 1< jump back and store the byte - ori shift, 0x01 ;[11] invert the last received bit to prevent furhter unstuffing - in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors - andi x5, 0xFE ;[1] mark this bit as inverted (will be corrected before storing shift) - eor x1, x2 ;[2] x1 and x2 have to be different because the stuff bit is always a zero - andi x1, USBMASK ;[3] mask the interesting bits - breq stuffErr ;[4] if the stuff bit is a 1-bit something went wrong - mov x1, x2 ;[5] the next bit expects the last state to be in x1 - rjmp didunstuff0 ;[6] - ;[7] jump delay of rjmp didunstuffX - -unstuff1: ;[11] this is the jump delay of breq unstuffX - in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors - ori shift, 0x02 ;[1] invert the last received bit to prevent furhter unstuffing - andi x5, 0xFD ;[2] mark this bit as inverted (will be corrected before storing shift) - eor x2, x1 ;[3] x1 and x2 have to be different because the stuff bit is always a zero - andi x2, USBMASK ;[4] mask the interesting bits - breq stuffErr ;[5] if the stuff bit is a 1-bit something went wrong - mov x2, x1 ;[6] the next bit expects the last state to be in x2 - nop2 ;[7] - ;[8] - rjmp didunstuff1 ;[9] - ;[10] jump delay of rjmp didunstuffX - -unstuff2: ;[9] this is the jump delay of breq unstuffX - ori shift, 0x04 ;[10] invert the last received bit to prevent furhter unstuffing - andi x5, 0xFB ;[11] mark this bit as inverted (will be corrected before storing shift) - in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors - eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero - andi x1, USBMASK ;[2] mask the interesting bits - breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong - mov x1, x2 ;[4] the next bit expects the last state to be in x1 - nop2 ;[5] - ;[6] - rjmp didunstuff2 ;[7] - ;[8] jump delay of rjmp didunstuffX - -unstuff3: ;[9] this is the jump delay of breq unstuffX - ori shift, 0x08 ;[10] invert the last received bit to prevent furhter unstuffing - andi x5, 0xF7 ;[11] mark this bit as inverted (will be corrected before storing shift) - in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors - eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero - andi x2, USBMASK ;[2] mask the interesting bits - breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong - mov x2, x1 ;[4] the next bit expects the last state to be in x2 - nop2 ;[5] - ;[6] - rjmp didunstuff3 ;[7] - ;[8] jump delay of rjmp didunstuffX - - - -; the include has to be here due to branch distance restirctions -#define __USE_CRC__ -#include "asmcommon.inc" - - - -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) -; K = (D+ = 1), (D- = 0) -; Spec allows 7.5 bit times from EOP to SOP for replies -; 7.5 bit times is 90 cycles. ...there is plenty of time - - -sendNakAndReti: - ldi x3, USBPID_NAK ;[-18] - rjmp sendX3AndReti ;[-17] -sendAckAndReti: - ldi cnt, USBPID_ACK ;[-17] -sendCntAndReti: - mov x3, cnt ;[-16] -sendX3AndReti: - ldi YL, 20 ;[-15] x3==r20 address is 20 - ldi YH, 0 ;[-14] - ldi cnt, 2 ;[-13] -; rjmp usbSendAndReti fallthrough - -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] -;uses: x1...x4, btcnt, shift, cnt, Y -;Numbers in brackets are time since first bit of sync pattern is sent - -usbSendAndReti: ; 12 cycles until SOP - in x2, USBDDR ;[-12] - ori x2, USBMASK ;[-11] - sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) - in x1, USBOUT ;[-8] port mirror for tx loop - out USBDDR, x2 ;[-6] <- acquire bus - ldi x2, 0 ;[-6] init x2 (bitstuff history) because sync starts with 0 - ldi x4, USBMASK ;[-5] exor mask - ldi shift, 0x80 ;[-4] sync byte is first byte sent -txByteLoop: - ldi bitcnt, 0x40 ;[-3]=[9] binary 01000000 -txBitLoop: ; the loop sends the first 7 bits of the byte - sbrs shift, 0 ;[-2]=[10] if we have to send a 1 don't change the line state - eor x1, x4 ;[-1]=[11] - out USBOUT, x1 ;[0] - ror shift ;[1] - ror x2 ;[2] transfers the last sent bit to the stuffing history -didStuffN: - nop ;[3] - nop ;[4] - cpi x2, 0xfc ;[5] if we sent six consecutive ones - brcc bitstuffN ;[6] - lsr bitcnt ;[7] - brne txBitLoop ;[8] restart the loop while the 1 is still in the bitcount - -; transmit bit 7 - sbrs shift, 0 ;[9] - eor x1, x4 ;[10] -didStuff7: - ror shift ;[11] - out USBOUT, x1 ;[0] transfer bit 7 to the pins - ror x2 ;[1] move the bit into the stuffing history - cpi x2, 0xfc ;[2] - brcc bitstuff7 ;[3] - ld shift, y+ ;[4] get next byte to transmit - dec cnt ;[5] decrement byte counter - brne txByteLoop ;[7] if we have more bytes start next one - ;[8] branch delay - -;make SE0: - cbr x1, USBMASK ;[8] prepare SE0 [spec says EOP may be 25 to 30 cycles] - lds x2, usbNewDeviceAddr;[9] - lsl x2 ;[11] we compare with left shifted address - out USBOUT, x1 ;[0] <-- out SE0 -- from now 2 bits = 24 cycles until bus idle - subi YL, 20 + 2 ;[1] Only assign address on data packets, not ACK/NAK in x3 - sbci YH, 0 ;[2] -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - breq skipAddrAssign ;[3] - sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer -skipAddrAssign: -;end of usbDeviceAddress transfer - ldi x2, 1< -int main (int argc, char **argv) -{ - int i, j; - for (i=0; i<512; i++){ - unsigned short crc = i & 0xff; - for(j=0; j<8; j++) crc = (crc >> 1) ^ ((crc & 1) ? 0xa001 : 0); - if((i & 7) == 0) printf("\n.byte "); - printf("0x%02x, ", (i > 0xff ? (crc >> 8) : crc) & 0xff); - if(i == 255) printf("\n"); - } - return 0; -} - -// Use the following algorithm to compute CRC values: -ushort computeCrc(uchar *msg, uchar msgLen) -{ - uchar i; - ushort crc = 0xffff; - for(i = 0; i < msgLen; i++) - crc = usbCrcTable16[lo8(crc) ^ msg[i]] ^ hi8(crc); - return crc; -} -*/ - -.balign 256 -usbCrcTableLow: -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 - -; .balign 256 -usbCrcTableHigh: -.byte 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2 -.byte 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04 -.byte 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E -.byte 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8 -.byte 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A -.byte 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC -.byte 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6 -.byte 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10 -.byte 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32 -.byte 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4 -.byte 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE -.byte 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38 -.byte 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA -.byte 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C -.byte 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26 -.byte 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0 -.byte 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62 -.byte 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4 -.byte 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE -.byte 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68 -.byte 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA -.byte 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C -.byte 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76 -.byte 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0 -.byte 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92 -.byte 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54 -.byte 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E -.byte 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98 -.byte 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A -.byte 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C -.byte 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86 -.byte 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 - diff --git a/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm20.inc b/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm20.inc deleted file mode 100644 index 5cfaa5f..0000000 --- a/tools/avrusb/examples/hid-data/firmware/usbdrv/usbdrvasm20.inc +++ /dev/null @@ -1,360 +0,0 @@ -/* Name: usbdrvasm20.inc - * Project: AVR USB driver - * Author: Jeroen Benschop - * Based on usbdrvasm16.inc from Christian Starkjohann - * Creation Date: 2008-03-05 - * Tabsize: 4 - * Copyright: (c) 2008 by Jeroen Benschop and OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * Revision: $Id: usbdrvasm20.inc 692 2008-11-07 15:07:40Z cs $ - */ - -/* Do not link this file! Link usbdrvasm.S instead, which includes the - * appropriate implementation! - */ - -/* -General Description: -This file is the 20 MHz version of the asssembler part of the USB driver. It -requires a 20 MHz crystal (not a ceramic resonator and not a calibrated RC -oscillator). - -See usbdrv.h for a description of the entire driver. - -Since almost all of this code is timing critical, don't change unless you -really know what you are doing! Many parts require not only a maximum number -of CPU cycles, but even an exact number of cycles! -*/ - -#define leap2 x3 -#ifdef __IAR_SYSTEMS_ASM__ -#define nextInst $+2 -#else -#define nextInst .+0 -#endif - -;max stack usage: [ret(2), YL, SREG, YH, bitcnt, shift, x1, x2, x3, x4, cnt] = 12 bytes -;nominal frequency: 20 MHz -> 13.333333 cycles per bit, 106.666667 cycles per byte -; Numbers in brackets are clocks counted from center of last sync bit -; when instruction starts -;register use in receive loop: -; shift assembles the byte currently being received -; x1 holds the D+ and D- line state -; x2 holds the previous line state -; x4 (leap) is used to add a leap cycle once every three bytes received -; X3 (leap2) is used to add a leap cycle once every three stuff bits received -; bitcnt is used to determine when a stuff bit is due -; cnt holds the number of bytes left in the receive buffer - -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt - push YL ;[-28] push only what is necessary to sync with edge ASAP - in YL, SREG ;[-26] - push YL ;[-25] - push YH ;[-23] -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of < 1/4 bit which meets the spec. - sbis USBIN, USBMINUS ;[-19] - rjmp foundK ;[-18] - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -foundK: ;[-16] -;{3, 5} after falling D- edge, average delay: 4 cycles -;bit0 should be at 34 for center sampling. Currently at 4 so 30 cylces till bit 0 sample -;use 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push bitcnt ;[-16] -; [---] ;[-15] - lds YL, usbInputBufOffset;[-14] -; [---] ;[-13] - clr YH ;[-12] - subi YL, lo8(-(usbRxBuf));[-11] [rx loop init] - sbci YH, hi8(-(usbRxBuf));[-10] [rx loop init] - push shift ;[-9] -; [---] ;[-8] - ldi shift,0x40 ;[-7] set msb to "1" so processing bit7 can be detected - nop2 ;[-6] -; [---] ;[-5] - ldi bitcnt, 5 ;[-4] [rx loop init] - sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early) - rjmp haveTwoBitsK ;[-2] - pop shift ;[-1] undo the push from before - pop bitcnt ;[1] - rjmp waitForK ;[3] this was not the end of sync, retry -; The entire loop from waitForK until rjmp waitForK above must not exceed two -; bit times (= 27 cycles). - -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -haveTwoBitsK: - push x1 ;[0] - push x2 ;[2] - push x3 ;[4] (leap2) - ldi leap2, 0x55 ;[6] add leap cycle on 2nd,5th,8th,... stuff bit - push x4 ;[7] == leap - ldi leap, 0x55 ;[9] skip leap cycle on 2nd,5th,8th,... byte received - push cnt ;[10] - ldi cnt, USB_BUFSIZE ;[12] [rx loop init] - ldi x2, 1< -#ifndef __IAR_SYSTEMS_ASM__ -# include -#endif - -#define __attribute__(arg) /* not supported on IAR */ - -#ifdef __IAR_SYSTEMS_ASM__ -# define __ASSEMBLER__ /* IAR does not define standard macro for asm */ -#endif - -#ifdef __HAS_ELPM__ -# define PROGMEM __farflash -#else -# define PROGMEM __flash -#endif - -#define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr)) - -/* The following definitions are not needed by the driver, but may be of some - * help if you port a gcc based project to IAR. - */ -#define cli() __disable_interrupt() -#define sei() __enable_interrupt() -#define wdt_reset() __watchdog_reset() -#define _BV(x) (1 << (x)) - -/* assembler compatibility macros */ -#define nop2 rjmp $+2 /* jump to next instruction */ -#define XL r26 -#define XH r27 -#define YL r28 -#define YH r29 -#define ZL r30 -#define ZH r31 -#define lo8(x) LOW(x) -#define hi8(x) (((x)>>8) & 0xff) /* not HIGH to allow XLINK to make a proper range check */ - -/* Depending on the device you use, you may get problems with the way usbdrv.h - * handles the differences between devices. Since IAR does not use #defines - * for MCU registers, we can't check for the existence of a particular - * register with an #ifdef. If the autodetection mechanism fails, include - * definitions for the required USB_INTR_* macros in your usbconfig.h. See - * usbconfig-prototype.h and usbdrv.h for details. - */ - -/* ------------------------------------------------------------------------- */ -#elif __CODEVISIONAVR__ /* check for CodeVision AVR */ -/* ------------------------------------------------------------------------- */ -/* This port is not working (yet) */ - -/* #define F_CPU _MCU_CLOCK_FREQUENCY_ seems to be defined automatically */ - -#include -#include - -#define __attribute__(arg) /* not supported on IAR */ - -#define PROGMEM __flash -#define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr)) - -#ifndef __ASSEMBLER__ -static inline void cli(void) -{ - #asm("cli"); -} -static inline void sei(void) -{ - #asm("sei"); -} -#endif -#define _delay_ms(t) delay_ms(t) -#define _BV(x) (1 << (x)) -#define USB_CFG_USE_SWITCH_STATEMENT 1 /* macro for if() cascase fails for unknown reason */ - -#define macro .macro -#define endm .endmacro -#define nop2 rjmp .+0 /* jump to next instruction */ - -/* ------------------------------------------------------------------------- */ -#else /* default development environment is avr-gcc/avr-libc */ -/* ------------------------------------------------------------------------- */ - -#include -#ifdef __ASSEMBLER__ -# define _VECTOR(N) __vector_ ## N /* io.h does not define this for asm */ -#else -# include -#endif - -#define USB_READ_FLASH(addr) pgm_read_byte(addr) - -#define macro .macro -#define endm .endm -#define nop2 rjmp .+0 /* jump to next instruction */ - -#endif /* development environment */ - -/* for conveniecne, ensure that PRG_RDB exists */ -#ifndef PRG_RDB -# define PRG_RDB(addr) USB_READ_FLASH(addr) -#endif -#endif /* __usbportability_h_INCLUDED__ */ diff --git a/tools/avrusb/examples/hid-mouse/Readme.txt b/tools/avrusb/examples/hid-mouse/Readme.txt deleted file mode 100644 index e0c8142..0000000 --- a/tools/avrusb/examples/hid-mouse/Readme.txt +++ /dev/null @@ -1,48 +0,0 @@ -This is the Readme file for hid-mouse, an example of a USB mouse device. In -order to have as little dependencies on hardware and architecture as -possible, mouse movements are computed internally so that the mouse pointer -moves in a circle. - - -WHAT IS DEMONSTRATED? -===================== -This example demonstrates how HID class devices are implemented. The example -is kept as simple as possible, except the report descriptor which is taken -from a real-world mouse. - -It does NOT include a host side driver because all modern operating systems -include one. It does NOT implement USBRQ_HID_SET_REPORT and report-IDs. See -the "hid-data" example for this topic. It does NOT implement any special -features such as suspend mode etc. - - -PREREQUISITES -============= -Target hardware: You need an AVR based circuit based on one of the examples -(see the "circuits" directory at the top level of this package), e.g. the -metaboard (http://www.obdev.at/goto.php?t=metaboard). - -AVR development environment: You need the gcc tool chain for the AVR, see -the Prerequisites section in the top level Readme file for how to obtain it. - - -BUILDING THE FIRMWARE -===================== -Change to the "firmware" directory and modify Makefile according to your -architecture (CPU clock, target device, fuse values) and ISP programmer. Then -edit usbconfig.h according to your pin assignments for D+ and D-. The default -settings are for the metaboard hardware. - -Type "make hex" to build main.hex, then "make flash" to upload the firmware -to the device. Don't forget to run "make fuse" once to program the fuses. If -you use a prototyping board with boot loader, follow the instructions of the -boot loader instead. - -Please note that the first "make hex" copies the driver from the top level -into the firmware directory. If you use a different build system than our -Makefile, you must copy the driver by hand. - - ----------------------------------------------------------------------------- -(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH. -http://www.obdev.at/ diff --git a/tools/avrusb/examples/hid-mouse/firmware/Makefile b/tools/avrusb/examples/hid-mouse/firmware/Makefile deleted file mode 100644 index 22b1227..0000000 --- a/tools/avrusb/examples/hid-mouse/firmware/Makefile +++ /dev/null @@ -1,164 +0,0 @@ -# Name: Makefile -# Project: hid-mouse example -# Author: Christian Starkjohann -# Creation Date: 2008-04-07 -# Tabsize: 4 -# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH -# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) -# This Revision: $Id: Makefile 692 2008-11-07 15:07:40Z cs $ - -DEVICE = atmega168 -F_CPU = 16000000 # in Hz -FUSE_L = # see below for fuse values for particular devices -FUSE_H = -AVRDUDE = avrdude -c usbasp -p $(DEVICE) # edit this line for your programmer - -CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0 -OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o - -COMPILE = avr-gcc -Wall -Os -DF_CPU=$(F_CPU) $(CFLAGS) -mmcu=$(DEVICE) - -############################################################################## -# Fuse values for particular devices -############################################################################## -# If your device is not listed here, go to -# http://palmavr.sourceforge.net/cgi-bin/fc.cgi -# and choose options for external crystal clock and no clock divider -# -################################## ATMega8 ################################## -# ATMega8 FUSE_L (Fuse low byte): -# 0x9f = 1 0 0 1 1 1 1 1 -# ^ ^ \ / \--+--/ -# | | | +------- CKSEL 3..0 (external >8M crystal) -# | | +--------------- SUT 1..0 (crystal osc, BOD enabled) -# | +------------------ BODEN (BrownOut Detector enabled) -# +-------------------- BODLEVEL (2.7V) -# ATMega8 FUSE_H (Fuse high byte): -# 0xc9 = 1 1 0 0 1 0 0 1 <-- BOOTRST (boot reset vector at 0x0000) -# ^ ^ ^ ^ ^ ^ ^------ BOOTSZ0 -# | | | | | +-------- BOOTSZ1 -# | | | | + --------- EESAVE (don't preserve EEPROM over chip erase) -# | | | +-------------- CKOPT (full output swing) -# | | +---------------- SPIEN (allow serial programming) -# | +------------------ WDTON (WDT not always on) -# +-------------------- RSTDISBL (reset pin is enabled) -# -############################## ATMega48/88/168 ############################## -# ATMega*8 FUSE_L (Fuse low byte): -# 0xdf = 1 1 0 1 1 1 1 1 -# ^ ^ \ / \--+--/ -# | | | +------- CKSEL 3..0 (external >8M crystal) -# | | +--------------- SUT 1..0 (crystal osc, BOD enabled) -# | +------------------ CKOUT (if 0: Clock output enabled) -# +-------------------- CKDIV8 (if 0: divide by 8) -# ATMega*8 FUSE_H (Fuse high byte): -# 0xde = 1 1 0 1 1 1 1 0 -# ^ ^ ^ ^ ^ \-+-/ -# | | | | | +------ BODLEVEL 0..2 (110 = 1.8 V) -# | | | | + --------- EESAVE (preserve EEPROM over chip erase) -# | | | +-------------- WDTON (if 0: watchdog always on) -# | | +---------------- SPIEN (allow serial programming) -# | +------------------ DWEN (debug wire enable) -# +-------------------- RSTDISBL (reset pin is enabled) -# -############################## ATTiny25/45/85 ############################### -# ATMega*5 FUSE_L (Fuse low byte): -# 0xef = 1 1 1 0 1 1 1 1 -# ^ ^ \+/ \--+--/ -# | | | +------- CKSEL 3..0 (clock selection -> crystal @ 12 MHz) -# | | +--------------- SUT 1..0 (BOD enabled, fast rising power) -# | +------------------ CKOUT (clock output on CKOUT pin -> disabled) -# +-------------------- CKDIV8 (divide clock by 8 -> don't divide) -# ATMega*5 FUSE_H (Fuse high byte): -# 0xdd = 1 1 0 1 1 1 0 1 -# ^ ^ ^ ^ ^ \-+-/ -# | | | | | +------ BODLEVEL 2..0 (brownout trigger level -> 2.7V) -# | | | | +---------- EESAVE (preserve EEPROM on Chip Erase -> not preserved) -# | | | +-------------- WDTON (watchdog timer always on -> disable) -# | | +---------------- SPIEN (enable serial programming -> enabled) -# | +------------------ DWEN (debug wire enable) -# +-------------------- RSTDISBL (disable external reset -> enabled) -# -################################ ATTiny2313 ################################# -# ATTiny2313 FUSE_L (Fuse low byte): -# 0xef = 1 1 1 0 1 1 1 1 -# ^ ^ \+/ \--+--/ -# | | | +------- CKSEL 3..0 (clock selection -> crystal @ 12 MHz) -# | | +--------------- SUT 1..0 (BOD enabled, fast rising power) -# | +------------------ CKOUT (clock output on CKOUT pin -> disabled) -# +-------------------- CKDIV8 (divide clock by 8 -> don't divide) -# ATTiny2313 FUSE_H (Fuse high byte): -# 0xdb = 1 1 0 1 1 0 1 1 -# ^ ^ ^ ^ \-+-/ ^ -# | | | | | +---- RSTDISBL (disable external reset -> enabled) -# | | | | +-------- BODLEVEL 2..0 (brownout trigger level -> 2.7V) -# | | | +-------------- WDTON (watchdog timer always on -> disable) -# | | +---------------- SPIEN (enable serial programming -> enabled) -# | +------------------ EESAVE (preserve EEPROM on Chip Erase -> not preserved) -# +-------------------- DWEN (debug wire enable) - - -# symbolic targets: -help: - @echo "This Makefile has no default rule. Use one of the following:" - @echo "make hex ....... to build main.hex" - @echo "make program ... to flash fuses and firmware" - @echo "make fuse ...... to flash the fuses" - @echo "make flash ..... to flash the firmware (use this on metaboard)" - @echo "make clean ..... to delete objects and hex file" - -hex: main.hex - -program: flash fuse - -# rule for programming fuse bits: -fuse: - @[ "$(FUSE_H)" != "" -a "$(FUSE_L)" != "" ] || \ - { echo "*** Edit Makefile and choose values for FUSE_L and FUSE_H!"; exit 1; } - $(AVRDUDE) -U hfuse:w:$(FUSE_H):m -U lfuse:w:$(FUSE_L):m - -# rule for uploading firmware: -flash: main.hex - $(AVRDUDE) -U flash:w:main.hex:i - -# rule for deleting dependent files (those which can be built by Make): -clean: - rm -f main.hex main.lst main.obj main.cof main.list main.map main.eep.hex main.elf *.o usbdrv/*.o main.s usbdrv/oddebug.s usbdrv/usbdrv.s - -# Generic rule for compiling C files: -.c.o: - $(COMPILE) -c $< -o $@ - -# Generic rule for assembling Assembler source files: -.S.o: - $(COMPILE) -x assembler-with-cpp -c $< -o $@ -# "-x assembler-with-cpp" should not be necessary since this is the default -# file type for the .S (with capital S) extension. However, upper case -# characters are not always preserved on Windows. To ensure WinAVR -# compatibility define the file type manually. - -# Generic rule for compiling C to assembler, used for debugging only. -.c.s: - $(COMPILE) -S $< -o $@ - -# file targets: - -# Since we don't want to ship the driver multipe times, we copy it into this project: -usbdrv: - cp -r ../../../usbdrv . - -main.elf: usbdrv $(OBJECTS) # usbdrv dependency only needed because we copy it - $(COMPILE) -o main.elf $(OBJECTS) - -main.hex: main.elf - rm -f main.hex main.eep.hex - avr-objcopy -j .text -j .data -O ihex main.elf main.hex - avr-size main.hex - -# debugging targets: - -disasm: main.elf - avr-objdump -d main.elf - -cpp: - $(COMPILE) -E main.c diff --git a/tools/avrusb/examples/hid-mouse/firmware/main.c b/tools/avrusb/examples/hid-mouse/firmware/main.c deleted file mode 100644 index cfd3287..0000000 --- a/tools/avrusb/examples/hid-mouse/firmware/main.c +++ /dev/null @@ -1,165 +0,0 @@ -/* Name: main.c - * Project: hid-mouse, a very simple HID example - * Author: Christian Starkjohann - * Creation Date: 2008-04-07 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: main.c 692 2008-11-07 15:07:40Z cs $ - */ - -/* -This example should run on most AVRs with only little changes. No special -hardware resources except INT0 are used. You may have to change usbconfig.h for -different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or -at least be connected to INT0 as well. - -We use VID/PID 0x046D/0xC00E which is taken from a Logitech mouse. Don't -publish any hardware using these IDs! This is for demonstration only! -*/ - -#include -#include -#include /* for sei() */ -#include /* for _delay_ms() */ - -#include /* required by usbdrv.h */ -#include "usbdrv.h" -#include "oddebug.h" /* This is also an example for using debug macros */ - -/* ------------------------------------------------------------------------- */ -/* ----------------------------- USB interface ----------------------------- */ -/* ------------------------------------------------------------------------- */ - -PROGMEM char usbHidReportDescriptor[52] = { /* USB report descriptor, size must match usbconfig.h */ - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) - 0x09, 0x02, // USAGE (Mouse) - 0xa1, 0x01, // COLLECTION (Application) - 0x09, 0x01, // USAGE (Pointer) - 0xA1, 0x00, // COLLECTION (Physical) - 0x05, 0x09, // USAGE_PAGE (Button) - 0x19, 0x01, // USAGE_MINIMUM - 0x29, 0x03, // USAGE_MAXIMUM - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x25, 0x01, // LOGICAL_MAXIMUM (1) - 0x95, 0x03, // REPORT_COUNT (3) - 0x75, 0x01, // REPORT_SIZE (1) - 0x81, 0x02, // INPUT (Data,Var,Abs) - 0x95, 0x01, // REPORT_COUNT (1) - 0x75, 0x05, // REPORT_SIZE (5) - 0x81, 0x03, // INPUT (Const,Var,Abs) - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) - 0x09, 0x30, // USAGE (X) - 0x09, 0x31, // USAGE (Y) - 0x09, 0x38, // USAGE (Wheel) - 0x15, 0x81, // LOGICAL_MINIMUM (-127) - 0x25, 0x7F, // LOGICAL_MAXIMUM (127) - 0x75, 0x08, // REPORT_SIZE (8) - 0x95, 0x03, // REPORT_COUNT (3) - 0x81, 0x06, // INPUT (Data,Var,Rel) - 0xC0, // END_COLLECTION - 0xC0, // END COLLECTION -}; -/* This is the same report descriptor as seen in a Logitech mouse. The data - * described by this descriptor consists of 4 bytes: - * . . . . . B2 B1 B0 .... one byte with mouse button states - * X7 X6 X5 X4 X3 X2 X1 X0 .... 8 bit signed relative coordinate x - * Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 .... 8 bit signed relative coordinate y - * W7 W6 W5 W4 W3 W2 W1 W0 .... 8 bit signed relative coordinate wheel - */ -typedef struct{ - uchar buttonMask; - char dx; - char dy; - char dWheel; -}report_t; - -static report_t reportBuffer; -static int sinus = 7 << 6, cosinus = 0; -static uchar idleRate; /* repeat rate for keyboards, never used for mice */ - - -/* The following function advances sin/cos by a fixed angle - * and stores the difference to the previous coordinates in the report - * descriptor. - * The algorithm is the simulation of a second order differential equation. - */ -static void advanceCircleByFixedAngle(void) -{ -char d; - -#define DIVIDE_BY_64(val) (val + (val > 0 ? 32 : -32)) >> 6 /* rounding divide */ - reportBuffer.dx = d = DIVIDE_BY_64(cosinus); - sinus += d; - reportBuffer.dy = d = DIVIDE_BY_64(sinus); - cosinus -= d; -} - -/* ------------------------------------------------------------------------- */ - -usbMsgLen_t usbFunctionSetup(uchar data[8]) -{ -usbRequest_t *rq = (void *)data; - - /* The following requests are never used. But since they are required by - * the specification, we implement them in this example. - */ - if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */ - DBG1(0x50, &rq->bRequest, 1); /* debug output: print our request */ - if(rq->bRequest == USBRQ_HID_GET_REPORT){ /* wValue: ReportType (highbyte), ReportID (lowbyte) */ - /* we only have one report type, so don't look at wValue */ - usbMsgPtr = (void *)&reportBuffer; - return sizeof(reportBuffer); - }else if(rq->bRequest == USBRQ_HID_GET_IDLE){ - usbMsgPtr = &idleRate; - return 1; - }else if(rq->bRequest == USBRQ_HID_SET_IDLE){ - idleRate = rq->wValue.bytes[1]; - } - }else{ - /* no vendor specific requests implemented */ - } - return 0; /* default for not implemented requests: return no data back to host */ -} - -/* ------------------------------------------------------------------------- */ - -int main(void) -{ -uchar i; - - wdt_enable(WDTO_1S); - /* Even if you don't use the watchdog, turn it off here. On newer devices, - * the status of the watchdog (on/off, period) is PRESERVED OVER RESET! - */ - DBG1(0x00, 0, 0); /* debug output: main starts */ - /* RESET status: all port bits are inputs without pull-up. - * That's the way we need D+ and D-. Therefore we don't need any - * additional hardware initialization. - */ - odDebugInit(); - usbInit(); - usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */ - i = 0; - while(--i){ /* fake USB disconnect for > 250 ms */ - wdt_reset(); - _delay_ms(1); - } - usbDeviceConnect(); - sei(); - DBG1(0x01, 0, 0); /* debug output: main loop starts */ - for(;;){ /* main event loop */ - DBG1(0x02, 0, 0); /* debug output: main loop iterates */ - wdt_reset(); - usbPoll(); - if(usbInterruptIsReady()){ - /* called after every poll of the interrupt endpoint */ - advanceCircleByFixedAngle(); - DBG1(0x03, 0, 0); /* debug output: interrupt report prepared */ - usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer)); - } - } - return 0; -} - -/* ------------------------------------------------------------------------- */ diff --git a/tools/avrusb/examples/hid-mouse/firmware/usbconfig.h b/tools/avrusb/examples/hid-mouse/firmware/usbconfig.h deleted file mode 100644 index 9ff541f..0000000 --- a/tools/avrusb/examples/hid-mouse/firmware/usbconfig.h +++ /dev/null @@ -1,350 +0,0 @@ -/* Name: usbconfig.h - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2005-04-01 - * Tabsize: 4 - * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: usbconfig-prototype.h 734 2009-03-23 11:10:07Z cs $ - */ - -#ifndef __usbconfig_h_included__ -#define __usbconfig_h_included__ - -/* -General Description: -This file is an example configuration (with inline documentation) for the USB -driver. It configures AVR-USB for USB D+ connected to Port D bit 2 (which is -also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may -wire the lines to any other port, as long as D+ is also wired to INT0 (or any -other hardware interrupt, as long as it is the highest level interrupt, see -section at the end of this file). -*/ - -/* ---------------------------- Hardware Config ---------------------------- */ - -#define USB_CFG_IOPORTNAME D -/* This is the port where the USB bus is connected. When you configure it to - * "B", the registers PORTB, PINB and DDRB will be used. - */ -#define USB_CFG_DMINUS_BIT 4 -/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected. - * This may be any bit in the port. - */ -#define USB_CFG_DPLUS_BIT 2 -/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected. - * This may be any bit in the port. Please note that D+ must also be connected - * to interrupt pin INT0! [You can also use other interrupts, see section - * "Optional MCU Description" below, or you can connect D- to the interrupt, as - * it is required if you use the USB_COUNT_SOF feature. If you use D- for the - * interrupt, the USB interrupt will also be triggered at Start-Of-Frame - * markers every millisecond.] - */ -#define USB_CFG_CLOCK_KHZ (F_CPU/1000) -/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000, - * 16500 and 20000. The 12.8 MHz and 16.5 MHz versions of the code require no - * crystal, they tolerate +/- 1% deviation from the nominal frequency. All - * other rates require a precision of 2000 ppm and thus a crystal! - * Default if not specified: 12 MHz - */ -#define USB_CFG_CHECK_CRC 0 -/* Define this to 1 if you want that the driver checks integrity of incoming - * data packets (CRC checks). CRC checks cost quite a bit of code size and are - * currently only available for 18 MHz crystal clock. You must choose - * USB_CFG_CLOCK_KHZ = 18000 if you enable this option. - */ - -/* ----------------------- Optional Hardware Config ------------------------ */ - -/* #define USB_CFG_PULLUP_IOPORTNAME D */ -/* If you connect the 1.5k pullup resistor from D- to a port pin instead of - * V+, you can connect and disconnect the device from firmware by calling - * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h). - * This constant defines the port on which the pullup resistor is connected. - */ -/* #define USB_CFG_PULLUP_BIT 4 */ -/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined - * above) where the 1.5k pullup resistor is connected. See description - * above for details. - */ - -/* --------------------------- Functional Range ---------------------------- */ - -#define USB_CFG_HAVE_INTRIN_ENDPOINT 1 -/* Define this to 1 if you want to compile a version with two endpoints: The - * default control endpoint 0 and an interrupt-in endpoint (any other endpoint - * number). - */ -#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0 -/* Define this to 1 if you want to compile a version with three endpoints: The - * default control endpoint 0, an interrupt-in endpoint 3 (or the number - * configured below) and a catch-all default interrupt-in endpoint as above. - * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature. - */ -#define USB_CFG_EP3_NUMBER 3 -/* If the so-called endpoint 3 is used, it can now be configured to any other - * endpoint number (except 0) with this macro. Default if undefined is 3. - */ -/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */ -/* The above macro defines the startup condition for data toggling on the - * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1. - * Since the token is toggled BEFORE sending any data, the first packet is - * sent with the oposite value of this configuration! - */ -#define USB_CFG_IMPLEMENT_HALT 0 -/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature - * for endpoint 1 (interrupt endpoint). Although you may not need this feature, - * it is required by the standard. We have made it a config option because it - * bloats the code considerably. - */ -#define USB_CFG_SUPPRESS_INTR_CODE 0 -/* Define this to 1 if you want to declare interrupt-in endpoints, but don't - * want to send any data over them. If this macro is defined to 1, functions - * usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if - * you need the interrupt-in endpoints in order to comply to an interface - * (e.g. HID), but never want to send any data. This option saves a couple - * of bytes in flash memory and the transmit buffers in RAM. - */ -#define USB_CFG_INTR_POLL_INTERVAL 100 -/* If you compile a version with endpoint 1 (interrupt-in), this is the poll - * interval. The value is in milliseconds and must not be less than 10 ms for - * low speed devices. - */ -#define USB_CFG_IS_SELF_POWERED 0 -/* Define this to 1 if the device has its own power supply. Set it to 0 if the - * device is powered from the USB bus. - */ -#define USB_CFG_MAX_BUS_POWER 20 -/* Set this variable to the maximum USB bus power consumption of your device. - * The value is in milliamperes. [It will be divided by two since USB - * communicates power requirements in units of 2 mA.] - */ -#define USB_CFG_IMPLEMENT_FN_WRITE 0 -/* Set this to 1 if you want usbFunctionWrite() to be called for control-out - * transfers. Set it to 0 if you don't need it and want to save a couple of - * bytes. - */ -#define USB_CFG_IMPLEMENT_FN_READ 0 -/* Set this to 1 if you need to send control replies which are generated - * "on the fly" when usbFunctionRead() is called. If you only want to send - * data from a static buffer, set it to 0 and return the data from - * usbFunctionSetup(). This saves a couple of bytes. - */ -#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0 -/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints. - * You must implement the function usbFunctionWriteOut() which receives all - * interrupt/bulk data sent to any endpoint other than 0. The endpoint number - * can be found in 'usbRxToken'. - */ -#define USB_CFG_HAVE_FLOWCONTROL 0 -/* Define this to 1 if you want flowcontrol over USB data. See the definition - * of the macros usbDisableAllRequests() and usbEnableAllRequests() in - * usbdrv.h. - */ -#define USB_CFG_LONG_TRANSFERS 0 -/* Define this to 1 if you want to send/receive blocks of more than 254 bytes - * in a single control-in or control-out transfer. Note that the capability - * for long transfers increases the driver size. - */ -/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */ -/* This macro is a hook if you want to do unconventional things. If it is - * defined, it's inserted at the beginning of received message processing. - * If you eat the received message and don't want default processing to - * proceed, do a return after doing your things. One possible application - * (besides debugging) is to flash a status LED on each packet. - */ -/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */ -/* This macro is a hook if you need to know when an USB RESET occurs. It has - * one parameter which distinguishes between the start of RESET state and its - * end. - */ -/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */ -/* This macro (if defined) is executed when a USB SET_ADDRESS request was - * received. - */ -#define USB_COUNT_SOF 0 -/* define this macro to 1 if you need the global variable "usbSofCount" which - * counts SOF packets. This feature requires that the hardware interrupt is - * connected to D- instead of D+. - */ -/* #ifdef __ASSEMBLER__ - * macro myAssemblerMacro - * in YL, TCNT0 - * sts timer0Snapshot, YL - * endm - * #endif - * #define USB_SOF_HOOK myAssemblerMacro - * This macro (if defined) is executed in the assembler module when a - * Start Of Frame condition is detected. It is recommended to define it to - * the name of an assembler macro which is defined here as well so that more - * than one assembler instruction can be used. The macro may use the register - * YL and modify SREG. If it lasts longer than a couple of cycles, USB messages - * immediately after an SOF pulse may be lost and must be retried by the host. - * What can you do with this hook? Since the SOF signal occurs exactly every - * 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in - * designs running on the internal RC oscillator. - * Please note that Start Of Frame detection works only if D- is wired to the - * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES! - */ -#define USB_CFG_CHECK_DATA_TOGGLING 0 -/* define this macro to 1 if you want to filter out duplicate data packets - * sent by the host. Duplicates occur only as a consequence of communication - * errors, when the host does not receive an ACK. Please note that you need to - * implement the filtering yourself in usbFunctionWriteOut() and - * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable - * for each control- and out-endpoint to check for duplicate packets. - */ -#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0 -/* define this macro to 1 if you want the function usbMeasureFrameLength() - * compiled in. This function can be used to calibrate the AVR's RC oscillator. - */ - -/* -------------------------- Device Description --------------------------- */ - -#define USB_CFG_VENDOR_ID 0xc0, 0x16 -/* USB vendor ID for the device, low byte first. If you have registered your - * own Vendor ID, define it here. Otherwise you use one of obdev's free shared - * VID/PID pairs. Be sure to read USBID-License.txt for rules! - */ -#define USB_CFG_DEVICE_ID 0xdf, 0x05 /* obdev's shared PID for HIDs */ -/* This is the ID of the product, low byte first. It is interpreted in the - * scope of the vendor ID. If you have registered your own VID with usb.org - * or if you have licensed a PID from somebody else, define it here. Otherwise - * you use obdev's free shared VID/PID pair. Be sure to read the rules in - * USBID-License.txt! - */ -#define USB_CFG_DEVICE_VERSION 0x00, 0x01 -/* Version number of the device: Minor number first, then major number. - */ -#define USB_CFG_VENDOR_NAME 'o', 'b', 'd', 'e', 'v', '.', 'a', 't' -#define USB_CFG_VENDOR_NAME_LEN 8 -/* These two values define the vendor name returned by the USB device. The name - * must be given as a list of characters under single quotes. The characters - * are interpreted as Unicode (UTF-16) entities. - * If you don't want a vendor name string, undefine these macros. - * ALWAYS define a vendor name containing your Internet domain name if you use - * obdev's free shared VID/PID pair. See the file USBID-License.txt for - * details. - */ -#define USB_CFG_DEVICE_NAME 'D', 'a', 't', 'a', 'S', 't', 'o', 'r', 'e' -#define USB_CFG_DEVICE_NAME_LEN 9 -/* Same as above for the device name. If you don't want a device name, undefine - * the macros. See the file USBID-License.txt before you assign a name if you - * use a shared VID/PID. - */ -/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */ -/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */ -/* Same as above for the serial number. If you don't want a serial number, - * undefine the macros. - * It may be useful to provide the serial number through other means than at - * compile time. See the section about descriptor properties below for how - * to fine tune control over USB descriptors such as the string descriptor - * for the serial number. - */ -#define USB_CFG_DEVICE_CLASS 0 -#define USB_CFG_DEVICE_SUBCLASS 0 -/* See USB specification if you want to conform to an existing device class. - * Class 0xff is "vendor specific". - */ -#define USB_CFG_INTERFACE_CLASS 3 -#define USB_CFG_INTERFACE_SUBCLASS 0 -#define USB_CFG_INTERFACE_PROTOCOL 0 -/* See USB specification if you want to conform to an existing device class or - * protocol. The following classes must be set at interface level: - * HID class is 3, no subclass and protocol required (but may be useful!) - * CDC class is 2, use subclass 2 and protocol 1 for ACM - */ -#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 52 -/* Define this to the length of the HID report descriptor, if you implement - * an HID device. Otherwise don't define it or define it to 0. - * If you use this define, you must add a PROGMEM character array named - * "usbHidReportDescriptor" to your code which contains the report descriptor. - * Don't forget to keep the array and this define in sync! - */ - -/* #define USB_PUBLIC static */ -/* Use the define above if you #include usbdrv.c instead of linking against it. - * This technique saves a couple of bytes in flash memory. - */ - -/* ------------------- Fine Control over USB Descriptors ------------------- */ -/* If you don't want to use the driver's default USB descriptors, you can - * provide our own. These can be provided as (1) fixed length static data in - * flash memory, (2) fixed length static data in RAM or (3) dynamically at - * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more - * information about this function. - * Descriptor handling is configured through the descriptor's properties. If - * no properties are defined or if they are 0, the default descriptor is used. - * Possible properties are: - * + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched - * at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is - * used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if - * you want RAM pointers. - * + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found - * in static memory is in RAM, not in flash memory. - * + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash), - * the driver must know the descriptor's length. The descriptor itself is - * found at the address of a well known identifier (see below). - * List of static descriptor names (must be declared PROGMEM if in flash): - * char usbDescriptorDevice[]; - * char usbDescriptorConfiguration[]; - * char usbDescriptorHidReport[]; - * char usbDescriptorString0[]; - * int usbDescriptorStringVendor[]; - * int usbDescriptorStringDevice[]; - * int usbDescriptorStringSerialNumber[]; - * Other descriptors can't be provided statically, they must be provided - * dynamically at runtime. - * - * Descriptor properties are or-ed or added together, e.g.: - * #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18)) - * - * The following descriptors are defined: - * USB_CFG_DESCR_PROPS_DEVICE - * USB_CFG_DESCR_PROPS_CONFIGURATION - * USB_CFG_DESCR_PROPS_STRINGS - * USB_CFG_DESCR_PROPS_STRING_0 - * USB_CFG_DESCR_PROPS_STRING_VENDOR - * USB_CFG_DESCR_PROPS_STRING_PRODUCT - * USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER - * USB_CFG_DESCR_PROPS_HID - * USB_CFG_DESCR_PROPS_HID_REPORT - * USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver) - * - * Note about string descriptors: String descriptors are not just strings, they - * are Unicode strings prefixed with a 2 byte header. Example: - * int serialNumberDescriptor[] = { - * USB_STRING_DESCRIPTOR_HEADER(6), - * 'S', 'e', 'r', 'i', 'a', 'l' - * }; - */ - -#define USB_CFG_DESCR_PROPS_DEVICE 0 -#define USB_CFG_DESCR_PROPS_CONFIGURATION 0 -#define USB_CFG_DESCR_PROPS_STRINGS 0 -#define USB_CFG_DESCR_PROPS_STRING_0 0 -#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0 -#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0 -#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0 -#define USB_CFG_DESCR_PROPS_HID 0 -#define USB_CFG_DESCR_PROPS_HID_REPORT 0 -#define USB_CFG_DESCR_PROPS_UNKNOWN 0 - -/* ----------------------- Optional MCU Description ------------------------ */ - -/* The following configurations have working defaults in usbdrv.h. You - * usually don't need to set them explicitly. Only if you want to run - * the driver on a device which is not yet supported or with a compiler - * which is not fully supported (such as IAR C) or if you use a differnt - * interrupt than INT0, you may have to define some of these. - */ -/* #define USB_INTR_CFG MCUCR */ -/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */ -/* #define USB_INTR_CFG_CLR 0 */ -/* #define USB_INTR_ENABLE GIMSK */ -/* #define USB_INTR_ENABLE_BIT INT0 */ -/* #define USB_INTR_PENDING GIFR */ -/* #define USB_INTR_PENDING_BIT INTF0 */ -/* #define USB_INTR_VECTOR SIG_INTERRUPT0 */ - -#endif /* __usbconfig_h_included__ */ diff --git a/tools/avrusb/examples/usbtool/Makefile b/tools/avrusb/examples/usbtool/Makefile deleted file mode 100644 index d41aba6..0000000 --- a/tools/avrusb/examples/usbtool/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -# Name: Makefile -# Project: usbtool -# Author: Christian Starkjohann -# Creation Date: 2008-04-06 -# Tabsize: 4 -# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH -# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) -# This Revision: $Id: Makefile 692 2008-11-07 15:07:40Z cs $ - - -# Concigure the following definitions according to your system. -# This Makefile has been tested on Mac OS X, Linux and Windows. - -# Use the following 3 lines on Unix (uncomment the framework on Mac OS X): -USBFLAGS = `libusb-config --cflags` -USBLIBS = `libusb-config --libs` -EXE_SUFFIX = - -# Use the following 3 lines on Windows and comment out the 3 above. You may -# have to change the include paths to where you installed libusb-win32 -#USBFLAGS = -I/usr/local/include -#USBLIBS = -L/usr/local/lib -lusb -#EXE_SUFFIX = .exe - -NAME = usbtool - -OBJECTS = opendevice.o $(NAME).o - -CC = gcc -CFLAGS = $(CPPFLAGS) $(USBFLAGS) -O -g -Wall -LIBS = $(USBLIBS) - -PROGRAM = $(NAME)$(EXE_SUFFIX) - - -all: $(PROGRAM) - -.c.o: - $(CC) $(CFLAGS) -c $< - -$(PROGRAM): $(OBJECTS) - $(CC) -o $(PROGRAM) $(OBJECTS) $(LIBS) - -strip: $(PROGRAM) - strip $(PROGRAM) - -clean: - rm -f *.o $(PROGRAM) diff --git a/tools/avrusb/examples/usbtool/Makefile.windows b/tools/avrusb/examples/usbtool/Makefile.windows deleted file mode 100644 index fa910fc..0000000 --- a/tools/avrusb/examples/usbtool/Makefile.windows +++ /dev/null @@ -1,18 +0,0 @@ -# Name: Makefile.windows -# Project: usbtool -# Author: Christian Starkjohann -# Creation Date: 2008-04-06 -# Tabsize: 4 -# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH -# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) -# This Revision: $Id$ - -# You may use this file with -# make -f Makefile.windows -# on Windows with MinGW instead of editing the main Makefile. - -include Makefile - -USBFLAGS = -I/usr/local/mingw/include -USBLIBS = -L/usr/local/mingw/lib -lusb -EXE_SUFFIX = .exe diff --git a/tools/avrusb/examples/usbtool/Readme.txt b/tools/avrusb/examples/usbtool/Readme.txt deleted file mode 100644 index 33f527c..0000000 --- a/tools/avrusb/examples/usbtool/Readme.txt +++ /dev/null @@ -1,209 +0,0 @@ -This is the Readme file for usbtool, a general purpose command line utility -which can send USB requests to arbitrary devices. Usbtool is based on libusb. - - -WHAT IS USBTOOL GOOD FOR? -========================= -When you implement a communication protocol like USB, you must usually write -two programs: one on each end of the communication. For USB, this means that -you must write a firmware for the device and driver software for the host. - -Usbtool can save you the work of writing the host software, at least during -firmware development and testing. Usbtool can send control-in and -out -requests to arbitrary devices and send and receive data on interrupt- and -bulk-endpoints. - -Usbtool is not only a useful developer tool, it's also an example for using -libusb for communication with the device. - - -SYNOPSIS -======== - usbtool [options] - - -COMMANDS -======== - list - This command prints a list of devices found on all available USB busses. - Options -v, -V, -p and -P can be used to filter the list. - - control in|out - Sends a control-in or control-out request to the device. The request - parameters are: - type ........ Type of request, can be "standard", "class", "vendor" or - "reserved". The type determines which software module in - the device is responsible for answering the request: - Standard requests are answered by the driver, class - requests by the class implementation (e.g. HID, CDC) and - vendor requests by custom code. - recipient ... Recipient of the request in the device. Can be "device", - "interface", "endpoint" or "other". For standard and - class requests, the specification defines a recipient for - each request. For vendor requests, choose whatever your - code expects. - request ..... 8 bit numeric value identifying the request. - value ....... 16 bit numeric value passed to the device. - index ....... another 16 bit numeric value passed to the device. - Use options -v, -V, -p and -P to single out a particular device. Use - options -d or -D to to send data in an OUT request. Use options -n, -O - and -b to determine what to do with data received in an IN request. - - interrupt in|out - Sends or receives data on an interrupt-out resp. -in endpoint. - Use options -v, -V, -p and -P to single out a particular device. Use - options -d or -D to to send data to an OUT endpoint. Use options -n, -O - and -b to determine what to do with data received from an IN endpoint. - Use option -e to set the endpoint number, -c to choose a configuration - -i to claim a particular interface. - - bulk in|out - Same as "interrupt in" and "interrupt out", but for bulk endpoints. - - -OPTIONS -======= -Most options have already been mentioned at the commands which use them. -here is a complete list: - - -h or -? - Prints a short help. - - -v - Numeric vendor ID, can be "*" to allow any VID. Take only devices with - matching vendor ID into account. - - -p - Numeric product ID, can be "*" to allow any PID. Take only devices with - matching product ID into account. - - -V - Shell style matching pattern for vendor name. Take only devices into - account which have a vendor name that matches this pattern. - - -P - Shell style matching pattern for product name. Take only devices into - account which have a product name that matches this pattern. - - -S - Shell style matching pattern for serial number. Take only devices into - account which have a serial number that matches this pattern. - - -d - Data bytes to send to the device, comma separated list of numeric values. - E.g.: "1,2,3,4,5". - - -D - Binary data sent to the device should be taken from this file. - - -O - Write received data bytes to the given file. Format is either hex or - binary, depending on the -b flag. By default, received data is printed - to standard output. - - -b - Request binary output format for files and standard output. Default is - a hexadecimal listing. - - -n - Numeric value: Maximum number of bytes to receive. This value is passed - directly to the libusb API functions. - - -e - Numeric value: Endpoint number for interrupt and bulk commands. - - -t - Numeric value: Timeout in milliseconds for the request. This value is - passed directly to the libusb API functions. - - -c - Numeric value: Interrupt and bulk endpoints can usually only be used if - a configuration and an interface has been chosen. Use -c and -i to - specify configuration and interface values. - - -i - Numeric value: Interrupt and bulk endpoints can usually only be used if - a configuration and an interface has been chosen. Use -c and -i to - specify configuration and interface values. - - -w - Usbtool may be too verbose with warnings for some applications. Use this - option to suppress USB warnings. - - -NUMERIC VALUES -============== -All numeric values can be given in hexadecimal, decimal or octal. Hex values -are identified by their 0x or 0X prefix, octal values by a leading "0" (the -digit zero) and decimal values because they start with a non-zero digit. An -optional sign character is allowed. The special value "*" is translated to -zero and stands for "any value" in some contexts. - - -SHELL STYLE MATCHING PATTERNS -============================= -Some options take shell style matching patterns as an argument. This refers -to Unix shells and their file wildcard operations: - + "*" (asterisk character) matches any number (0 to infinite) of any - characters. - + "?" matches exactly one arbitrary character. - + A list of characters in square brackets (e.g. "[abc]") matches any of the - characters in the list. If a dash ("-") is in the list, it must be the - first or the last character. If a caret ("^") is in the list, it must - not be the first character. A closing square bracket ("]") must be the - first character in the list. A range of characters can be specified in - the way "[a-z]". This matches all characters with numeric representation - (usually ASCII) starting with "a" and ending with "z". The entire - construct matches only one character. - + A list of characters in square brackets starting with a caret ("^"), e.g. - ("[^abc]") matches any character NOT in the list. The other rules are as - above. - + "\" (backslash) followed by any character matches that following - character. This can be used to escape "*", "?", "[" and "\". - - -BUILDING USBTOOL -================ -Usbtool uses libusb on Unix and libusb-win32 on Windows. These libraries can -be obtained from http://libusb.sourceforge.net/ and -http://libusb-win32.sourceforge.net/ respectively. On Unix, a simple "make" -should compile the sources (although you may have to edit Makefile to -include or remove additional libraries). On Windows, we recommend that you -use MinGW and MSYS. See the top level Readme file for details. Edit -Makefile.windows according to your library installation paths and build with -"make -f Makefile.windows". - - -EXAMPLES -======== -To list all devices connected to your computer, do - - usbtool -w list - -To check whether our selection options single out the desired device, use eg. - - usbtool -w -P LEDControl list - -This command shows all LEDControl devices connected or prints nothing if -none is found. LEDControl is the device from the "custom-class" example. - -You can also send commands to the LEDControl device using usbtool. From -the file requests.h in custom-class/firmware, we know that the set-status -request has numeric value 1 and the get-status request is 2. See this file -for details of the protocol used. We can therefore query the status with - - usbtool -w -P LEDControl control in vendor device 2 0 0 - -This command prints 0x00 if the LED is off or 0x01 if it is on. To turn the -LED on, use - - usbtool -w -P LEDControl control out vendor device 1 1 0 - -and to turn it off, use - - usbtool -w -P LEDControl control out vendor device 1 0 0 - - ----------------------------------------------------------------------------- -(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH. -http://www.obdev.at/ diff --git a/tools/avrusb/examples/usbtool/opendevice.c b/tools/avrusb/examples/usbtool/opendevice.c deleted file mode 100644 index 791175b..0000000 --- a/tools/avrusb/examples/usbtool/opendevice.c +++ /dev/null @@ -1,203 +0,0 @@ -/* Name: opendevice.c - * Project: AVR-USB host-side library - * Author: Christian Starkjohann - * Creation Date: 2008-04-10 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: opendevice.c 692 2008-11-07 15:07:40Z cs $ - */ - -/* -General Description: -The functions in this module can be used to find and open a device based on -libusb or libusb-win32. -*/ - -#include -#include "opendevice.h" - -/* ------------------------------------------------------------------------- */ - -#define MATCH_SUCCESS 1 -#define MATCH_FAILED 0 -#define MATCH_ABORT -1 - -/* private interface: match text and p, return MATCH_SUCCESS, MATCH_FAILED, or MATCH_ABORT. */ -static int _shellStyleMatch(char *text, char *p) -{ -int last, matched, reverse; - - for(; *p; text++, p++){ - if(*text == 0 && *p != '*') - return MATCH_ABORT; - switch(*p){ - case '\\': - /* Literal match with following character. */ - p++; - /* FALLTHROUGH */ - default: - if(*text != *p) - return MATCH_FAILED; - continue; - case '?': - /* Match anything. */ - continue; - case '*': - while(*++p == '*') - /* Consecutive stars act just like one. */ - continue; - if(*p == 0) - /* Trailing star matches everything. */ - return MATCH_SUCCESS; - while(*text) - if((matched = _shellStyleMatch(text++, p)) != MATCH_FAILED) - return matched; - return MATCH_ABORT; - case '[': - reverse = p[1] == '^'; - if(reverse) /* Inverted character class. */ - p++; - matched = MATCH_FAILED; - if(p[1] == ']' || p[1] == '-') - if(*++p == *text) - matched = MATCH_SUCCESS; - for(last = *p; *++p && *p != ']'; last = *p) - if (*p == '-' && p[1] != ']' ? *text <= *++p && *text >= last : *text == *p) - matched = MATCH_SUCCESS; - if(matched == reverse) - return MATCH_FAILED; - continue; - } - } - return *text == 0; -} - -/* public interface for shell style matching: returns 0 if fails, 1 if matches */ -static int shellStyleMatch(char *text, char *pattern) -{ - if(pattern == NULL) /* NULL pattern is synonymous to "*" */ - return 1; - return _shellStyleMatch(text, pattern) == MATCH_SUCCESS; -} - -/* ------------------------------------------------------------------------- */ - -int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen) -{ -char buffer[256]; -int rval, i; - - if((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use libusb version if it works */ - return rval; - if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, 0x0409, buffer, sizeof(buffer), 5000)) < 0) - return rval; - if(buffer[1] != USB_DT_STRING){ - *buf = 0; - return 0; - } - if((unsigned char)buffer[0] < rval) - rval = (unsigned char)buffer[0]; - rval /= 2; - /* lossy conversion to ISO Latin1: */ - for(i=1;i buflen) /* destination buffer overflow */ - break; - buf[i-1] = buffer[2 * i]; - if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */ - buf[i-1] = '?'; - } - buf[i-1] = 0; - return i-1; -} - -/* ------------------------------------------------------------------------- */ - -int usbOpenDevice(usb_dev_handle **device, int vendorID, char *vendorNamePattern, int productID, char *productNamePattern, char *serialNamePattern, FILE *printMatchingDevicesFp, FILE *warningsFp) -{ -struct usb_bus *bus; -struct usb_device *dev; -usb_dev_handle *handle = NULL; -int errorCode = USBOPEN_ERR_NOTFOUND; - - usb_find_busses(); - usb_find_devices(); - for(bus = usb_get_busses(); bus; bus = bus->next){ - for(dev = bus->devices; dev; dev = dev->next){ /* iterate over all devices on all busses */ - if((vendorID == 0 || dev->descriptor.idVendor == vendorID) - && (productID == 0 || dev->descriptor.idProduct == productID)){ - char vendor[256], product[256], serial[256]; - int len; - handle = usb_open(dev); /* we need to open the device in order to query strings */ - if(!handle){ - errorCode = USBOPEN_ERR_ACCESS; - if(warningsFp != NULL) - fprintf(warningsFp, "Warning: cannot open VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); - continue; - } - /* now check whether the names match: */ - len = vendor[0] = 0; - if(dev->descriptor.iManufacturer > 0){ - len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, vendor, sizeof(vendor)); - } - if(len < 0){ - errorCode = USBOPEN_ERR_ACCESS; - if(warningsFp != NULL) - fprintf(warningsFp, "Warning: cannot query manufacturer for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); - }else{ - errorCode = USBOPEN_ERR_NOTFOUND; - /* printf("seen device from vendor ->%s<-\n", vendor); */ - if(shellStyleMatch(vendor, vendorNamePattern)){ - len = product[0] = 0; - if(dev->descriptor.iProduct > 0){ - len = usbGetStringAscii(handle, dev->descriptor.iProduct, product, sizeof(product)); - } - if(len < 0){ - errorCode = USBOPEN_ERR_ACCESS; - if(warningsFp != NULL) - fprintf(warningsFp, "Warning: cannot query product for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); - }else{ - errorCode = USBOPEN_ERR_NOTFOUND; - /* printf("seen product ->%s<-\n", product); */ - if(shellStyleMatch(product, productNamePattern)){ - len = serial[0] = 0; - if(dev->descriptor.iSerialNumber > 0){ - len = usbGetStringAscii(handle, dev->descriptor.iSerialNumber, serial, sizeof(serial)); - } - if(len < 0){ - errorCode = USBOPEN_ERR_ACCESS; - if(warningsFp != NULL) - fprintf(warningsFp, "Warning: cannot query serial for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); - } - if(shellStyleMatch(serial, serialNamePattern)){ - if(printMatchingDevicesFp != NULL){ - if(serial[0] == 0){ - fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product); - }else{ - fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\" serial=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product, serial); - } - }else{ - break; - } - } - } - } - } - } - usb_close(handle); - handle = NULL; - } - } - if(handle) /* we have found a deice */ - break; - } - if(handle != NULL){ - errorCode = 0; - *device = handle; - } - if(printMatchingDevicesFp != NULL) /* never return an error for listing only */ - errorCode = 0; - return errorCode; -} - -/* ------------------------------------------------------------------------- */ diff --git a/tools/avrusb/examples/usbtool/opendevice.h b/tools/avrusb/examples/usbtool/opendevice.h deleted file mode 100644 index 5e9b68b..0000000 --- a/tools/avrusb/examples/usbtool/opendevice.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Name: opendevice.h - * Project: AVR-USB host-side library - * Author: Christian Starkjohann - * Creation Date: 2008-04-10 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: opendevice.h 692 2008-11-07 15:07:40Z cs $ - */ - -/* -General Description: -This module offers additional functionality for host side drivers based on -libusb or libusb-win32. It includes a function to find and open a device -based on numeric IDs and textual description. It also includes a function to -obtain textual descriptions from a device. - -To use this functionality, simply copy opendevice.c and opendevice.h into your -project and add them to your Makefile. You may modify and redistribute these -files according to the GNU General Public License (GPL) version 2 or 3. -*/ - -#ifndef __OPENDEVICE_H_INCLUDED__ -#define __OPENDEVICE_H_INCLUDED__ - -#include /* this is libusb, see http://libusb.sourceforge.net/ */ -#include - -int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen); -/* This function gets a string descriptor from the device. 'index' is the - * string descriptor index. The string is returned in ISO Latin 1 encoding in - * 'buf' and it is terminated with a 0-character. The buffer size must be - * passed in 'buflen' to prevent buffer overflows. A libusb device handle - * must be given in 'dev'. - * Returns: The length of the string (excluding the terminating 0) or - * a negative number in case of an error. If there was an error, use - * usb_strerror() to obtain the error message. - */ - -int usbOpenDevice(usb_dev_handle **device, int vendorID, char *vendorNamePattern, int productID, char *productNamePattern, char *serialNamePattern, FILE *printMatchingDevicesFp, FILE *warningsFp); -/* This function iterates over all devices on all USB busses and searches for - * a device. Matching is done first by means of Vendor- and Product-ID (passed - * in 'vendorID' and 'productID'. An ID of 0 matches any numeric ID (wildcard). - * When a device matches by its IDs, matching by names is performed. Name - * matching can be done on textual vendor name ('vendorNamePattern'), product - * name ('productNamePattern') and serial number ('serialNamePattern'). A - * device matches only if all non-null pattern match. If you don't care about - * a string, pass NULL for the pattern. Patterns are Unix shell style pattern: - * '*' stands for 0 or more characters, '?' for one single character, a list - * of characters in square brackets for a single character from the list - * (dashes are allowed to specify a range) and if the lis of characters begins - * with a caret ('^'), it matches one character which is NOT in the list. - * Other parameters to the function: If 'warningsFp' is not NULL, warning - * messages are printed to this file descriptor with fprintf(). If - * 'printMatchingDevicesFp' is not NULL, no device is opened but matching - * devices are printed to the given file descriptor with fprintf(). - * If a device is opened, the resulting USB handle is stored in '*device'. A - * pointer to a "usb_dev_handle *" type variable must be passed here. - * Returns: 0 on success, an error code (see defines below) on failure. - */ - -/* usbOpenDevice() error codes: */ -#define USBOPEN_SUCCESS 0 /* no error */ -#define USBOPEN_ERR_ACCESS 1 /* not enough permissions to open device */ -#define USBOPEN_ERR_IO 2 /* I/O error */ -#define USBOPEN_ERR_NOTFOUND 3 /* device not found */ - - -/* Obdev's free USB IDs, see USBID-License.txt for details */ - -#define USB_VID_OBDEV_SHARED 5824 /* obdev's shared vendor ID */ -#define USB_PID_OBDEV_SHARED_CUSTOM 1500 /* shared PID for custom class devices */ -#define USB_PID_OBDEV_SHARED_HID 1503 /* shared PID for HIDs except mice & keyboards */ -#define USB_PID_OBDEV_SHARED_CDCACM 1505 /* shared PID for CDC Modem devices */ -#define USB_PID_OBDEV_SHARED_MIDI 1508 /* shared PID for MIDI class devices */ - -#endif /* __OPENDEVICE_H_INCLUDED__ */ diff --git a/tools/avrusb/examples/usbtool/usbtool.c b/tools/avrusb/examples/usbtool/usbtool.c deleted file mode 100644 index 8b9e529..0000000 --- a/tools/avrusb/examples/usbtool/usbtool.c +++ /dev/null @@ -1,356 +0,0 @@ -/* Name: usbtool.c - * Project: AVR-USB examples, host side - * Author: Christian Starkjohann - * Creation Date: 2008-04-06 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: usbtool.c 692 2008-11-07 15:07:40Z cs $ - */ - -/* -General Description: -This command line tool can perform various USB requests at arbitrary -USB devices. It is intended as universal host side tool for experimentation -and debugging purposes. It must be linked with libusb, a library for accessing -the USB bus from Linux, FreeBSD, Mac OS X and other Unix operating systems. -Libusb can be obtained from http://libusb.sourceforge.net/. -On Windows use libusb-win32 from http://libusb-win32.sourceforge.net/. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include /* this is libusb, see http://libusb.sourceforge.net/ */ -#include "opendevice.h" /* common code moved to separate module */ - -#define DEFAULT_USB_VID 0 /* any */ -#define DEFAULT_USB_PID 0 /* any */ - -static void usage(char *name) -{ - fprintf(stderr, "usage: %s [options] \n", name); - fprintf(stderr, - "Options are:\n" - " -h or -? (print this help and exit)\n" - " -v (defaults to 0x%x, can be '*' for any VID)\n" - " -p (defaults to 0x%x, can be '*' for any PID)\n" - " -V (shell style matching, defaults to '*')\n" - " -P (shell style matching, defaults to '*')\n" - " -S (shell style matching, defaults to '*')\n" - " -d (data byte for request, comma separated list)\n" - " -D (binary data for request taken from file)\n" - " -O (write received data bytes to file)\n" - " -b (binary output format, default is hex)\n" - " -n (maximum number of bytes to receive)\n" - " -e (specify endpoint for some commands)\n" - " -t (specify USB timeout in milliseconds)\n" - " -c (device configuration to choose)\n" - " -i (configuration interface to claim)\n" - " -w (suppress USB warnings, default is verbose)\n" - "\n" - "Commands are:\n" - " list (list all matching devices by name)\n" - " control in|out (send control request)\n" - " interrupt in|out (send or receive interrupt data)\n" - " bulk in|out (send or receive bulk data)\n" - "For valid enum values for and pass \"x\" for the value.\n" - "Objective Development's free VID/PID pairs are:\n" - " 5824/1500 for vendor class devices\n" - " 5824/1503 for HID class devices excluding mice and keyboards\n" - " 5824/1505 for CDC-ACM class devices\n" - " 5824/1508 for MIDI class devices\n" - , DEFAULT_USB_VID, DEFAULT_USB_PID - ); - - -} - -static int vendorID = DEFAULT_USB_VID; -static int productID = DEFAULT_USB_PID; -static char *vendorNamePattern = "*"; -static char *productNamePattern = "*"; -static char *serialPattern = "*"; -static char *sendBytes = NULL; -static int sendByteCount; -static char *outputFile = NULL; -static int endpoint = 0; -static int outputFormatIsBinary = 0; -static int showWarnings = 1; -static int usbTimeout = 5000; -static int usbCount = 128; -static int usbConfiguration = 1; -static int usbInterface = 0; - -static int usbDirection, usbType, usbRecipient, usbRequest, usbValue, usbIndex; /* arguments of control transfer */ - -/* ------------------------------------------------------------------------- */ - -/* ASCII to integer (number parsing) which allows hex (0x prefix), - * octal (0 prefix) and decimal (1-9 prefix) input. - */ -static int myAtoi(char *text) -{ -long l; -char *endPtr; - - if(strcmp(text, "*") == 0) - return 0; - l = strtol(text, &endPtr, 0); - if(endPtr == text){ - fprintf(stderr, "warning: can't parse numeric parameter ->%s<-, defaults to 0.\n", text); - l = 0; - }else if(*endPtr != 0){ - fprintf(stderr, "warning: numeric parameter ->%s<- only partially parsed.\n", text); - } - return l; -} - -static int parseEnum(char *text, ...) -{ -va_list vlist; -char *entries[64]; -int i, numEntries; - - va_start(vlist, text); - for(i = 0; i < 64; i++){ - entries[i] = va_arg(vlist, char *); - if(entries[i] == NULL) - break; - } - numEntries = i; - va_end(vlist); - for(i = 0; i < numEntries; i++){ - if(strcasecmp(text, entries[i]) == 0) - return i; - } - if(isdigit(*text)){ - return myAtoi(text); - } - fprintf(stderr, "Enum value \"%s\" not allowed. Allowed values are:\n", text); - for(i = 0; i < numEntries; i++){ - fprintf(stderr, " %s\n", entries[i]); - } - exit(1); -} - -/* ------------------------------------------------------------------------- */ - -#define ACTION_LIST 0 -#define ACTION_CONTROL 1 -#define ACTION_INTERRUPT 2 -#define ACTION_BULK 3 - -int main(int argc, char **argv) -{ -usb_dev_handle *handle = NULL; -int opt, len, action, argcnt; -char *myName = argv[0], *s, *rxBuffer = NULL; -FILE *fp; - - while((opt = getopt(argc, argv, "?hv:p:V:P:S:d:D:O:e:n:tbw")) != -1){ - switch(opt){ - case 'h': - case '?': /* -h or -? (print this help and exit) */ - usage(myName); - exit(1); - case 'v': /* -v (defaults to 0x%x, can be '*' for any VID) */ - vendorID = myAtoi(optarg); - break; - case 'p': /* -p (defaults to 0x%x, can be '*' for any PID) */ - productID = myAtoi(optarg); - break; - case 'V': /* -V (shell style matching, defaults to '*') */ - vendorNamePattern = optarg; - break; - case 'P': /* -P (shell style matching, defaults to '*') */ - productNamePattern = optarg; - break; - case 'S': /* -S (shell style matching, defaults to '*') */ - serialPattern = optarg; - break; - case 'd': /* -d (data bytes for requests given on command line) */ - while((s = strtok(optarg, ", ")) != NULL){ - optarg = NULL; - if(sendBytes != NULL){ - sendBytes = realloc(sendBytes, sendByteCount + 1); - }else{ - sendBytes = malloc(sendByteCount + 1); - } - sendBytes[sendByteCount++] = myAtoi(s); - } - break; - case 'D': /* -D (data bytes for request taken from file) */ - if((fp = fopen(optarg, "rb")) == NULL){ - fprintf(stderr, "error opening %s: %s\n", optarg, strerror(errno)); - exit(1); - } - fseek(fp, 0, SEEK_END); - len = ftell(fp); - fseek(fp, 0, SEEK_SET); - if(sendBytes != NULL){ - sendBytes = realloc(sendBytes, sendByteCount + len); - }else{ - sendBytes = malloc(sendByteCount + len); - } - fread(sendBytes + sendByteCount, 1, len, fp); /* would need error checking */ - sendByteCount += len; - fclose(fp); - break; - case 'O': /* -O (write received data bytes to file) */ - outputFile = optarg; - break; - case 'e': /* -e (specify endpoint for some commands) */ - endpoint = myAtoi(optarg); - break; - case 't': /* -t (specify USB timeout in milliseconds) */ - usbTimeout = myAtoi(optarg); - break; - case 'b': /* -b (binary output format, default is hex) */ - outputFormatIsBinary = 1; - break; - case 'n': /* -n (maximum number of bytes to receive) */ - usbCount = myAtoi(optarg); - break; - case 'c': /* -c (device configuration to choose) */ - usbConfiguration = myAtoi(optarg); - break; - case 'i': /* -i (configuration interface to claim) */ - usbInterface = myAtoi(optarg); - break; - case 'w': /* -w (suppress USB warnings, default is verbose) */ - showWarnings = 0; - break; - default: - fprintf(stderr, "Option -%c unknown\n", opt); - exit(1); - } - } - argc -= optind; - argv += optind; - if(argc < 1){ - usage(myName); - exit(1); - } - argcnt = 2; - if(strcasecmp(argv[0], "list") == 0){ - action = ACTION_LIST; - argcnt = 1; - }else if(strcasecmp(argv[0], "control") == 0){ - action = ACTION_CONTROL; - argcnt = 7; - }else if(strcasecmp(argv[0], "interrupt") == 0){ - action = ACTION_INTERRUPT; - }else if(strcasecmp(argv[0], "bulk") == 0){ - action = ACTION_BULK; - }else{ - fprintf(stderr, "command %s not known\n", argv[0]); - usage(myName); - exit(1); - } - if(argc < argcnt){ - fprintf(stderr, "Not enough arguments.\n"); - usage(myName); - exit(1); - } - if(argc > argcnt){ - fprintf(stderr, "Warning: only %d arguments expected, rest ignored.\n", argcnt); - } - usb_init(); - if(usbOpenDevice(&handle, vendorID, vendorNamePattern, productID, productNamePattern, serialPattern, action == ACTION_LIST ? stdout : NULL, showWarnings ? stderr : NULL) != 0){ - 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); - exit(1); - } - if(action == ACTION_LIST) - exit(0); /* we've done what we were asked to do already */ - usbDirection = parseEnum(argv[1], "out", "in", NULL); - if(usbDirection){ /* IN transfer */ - rxBuffer = malloc(usbCount); - } - if(action == ACTION_CONTROL){ - int requestType; - usbType = parseEnum(argv[2], "standard", "class", "vendor", "reserved", NULL); - usbRecipient = parseEnum(argv[3], "device", "interface", "endpoint", "other", NULL); - usbRequest = myAtoi(argv[4]); - usbValue = myAtoi(argv[5]); - usbIndex = myAtoi(argv[6]); - requestType = ((usbDirection & 1) << 7) | ((usbType & 3) << 5) | (usbRecipient & 0x1f); - if(usbDirection){ /* IN transfer */ - len = usb_control_msg(handle, requestType, usbRequest, usbValue, usbIndex, rxBuffer, usbCount, usbTimeout); - }else{ /* OUT transfer */ - len = usb_control_msg(handle, requestType, usbRequest, usbValue, usbIndex, sendBytes, sendByteCount, usbTimeout); - } - }else{ /* must be ACTION_INTERRUPT or ACTION_BULK */ - int retries = 1; - if(usb_set_configuration(handle, usbConfiguration) && showWarnings){ - fprintf(stderr, "Warning: could not set configuration: %s\n", usb_strerror()); - } - /* now try to claim the interface and detach the kernel HID driver on - * linux and other operating systems which support the call. - */ - while((len = usb_claim_interface(handle, usbInterface)) != 0 && retries-- > 0){ -#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP - if(usb_detach_kernel_driver_np(handle, 0) < 0 && showWarnings){ - fprintf(stderr, "Warning: could not detach kernel driver: %s\n", usb_strerror()); - } -#endif - } - if(len != 0 && showWarnings) - fprintf(stderr, "Warning: could not claim interface: %s\n", usb_strerror()); - if(action == ACTION_INTERRUPT){ - if(usbDirection){ /* IN transfer */ - len = usb_interrupt_read(handle, endpoint, rxBuffer, usbCount, usbTimeout); - }else{ - len = usb_interrupt_write(handle, endpoint, sendBytes, sendByteCount, usbTimeout); - } - }else{ - if(usbDirection){ /* IN transfer */ - len = usb_bulk_read(handle, endpoint, rxBuffer, usbCount, usbTimeout); - }else{ - len = usb_bulk_write(handle, endpoint, sendBytes, sendByteCount, usbTimeout); - } - } - } - if(len < 0){ - fprintf(stderr, "USB error: %s\n", usb_strerror()); - exit(1); - } - if(usbDirection == 0) /* OUT */ - printf("%d bytes sent.\n", len); - if(rxBuffer != NULL){ - FILE *fp = stdout; - if(outputFile != NULL){ - fp = fopen(outputFile, outputFormatIsBinary ? "wb" : "w"); - if(fp == NULL){ - fprintf(stderr, "Error writing \"%s\": %s\n", outputFile, strerror(errno)); - exit(1); - } - } - if(outputFormatIsBinary){ - fwrite(rxBuffer, 1, len, fp); - }else{ - int i; - for(i = 0; i < len; i++){ - if(i != 0){ - if(i % 16 == 0){ - fprintf(fp, "\n"); - }else{ - fprintf(fp, " "); - } - } - fprintf(fp, "0x%02x", rxBuffer[i] & 0xff); - } - if(i != 0) - fprintf(fp, "\n"); - } - } - usb_close(handle); - if(rxBuffer != NULL) - free(rxBuffer); - return 0; -} diff --git a/tools/avrusb/libs-device/Readme.txt b/tools/avrusb/libs-device/Readme.txt deleted file mode 100644 index 76518dc..0000000 --- a/tools/avrusb/libs-device/Readme.txt +++ /dev/null @@ -1,22 +0,0 @@ -This is the Readme file for the libs-device directory. This directory contains -code snippets which may be useful for USB device firmware. - - -WHAT IS INCLUDED IN THIS DIRECTORY? -=================================== - -osccal.c and osccal.h - This module contains a function which calibrates the AVR's built-in RC - oscillator based on the USB frame clock. See osccal.h for a documentation - of the API. - -osctune.h - This header file contains a code snippet for usbconfig.h. With this code, - you can keep the AVR's internal RC oscillator in sync with the USB frame - clock. This is a continuous synchronization, not a single calibration at - USB reset as with osccal.c above. Please note that this code works only - if D- is wired to the interrupt, not D+. - ----------------------------------------------------------------------------- -(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH. -http://www.obdev.at/ diff --git a/tools/avrusb/libs-device/osccal.c b/tools/avrusb/libs-device/osccal.c deleted file mode 100644 index 09e2936..0000000 --- a/tools/avrusb/libs-device/osccal.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Name: osccal.c - * Author: Christian Starkjohann - * Creation Date: 2008-04-10 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: osccal.c 692 2008-11-07 15:07:40Z cs $ - */ - -#include - -/* ------------------------------------------------------------------------- */ -/* ------------------------ Oscillator Calibration ------------------------- */ -/* ------------------------------------------------------------------------- */ - -/* Calibrate the RC oscillator. Our timing reference is the Start Of Frame - * signal (a single SE0 bit) repeating every millisecond immediately after - * a USB RESET. We first do a binary search for the OSCCAL value and then - * optimize this value with a neighboorhod search. - */ -void calibrateOscillator(void) -{ -uchar step = 128; -uchar trialValue = 0, optimumValue; -int x, optimumDev, targetValue = (unsigned)(1499 * (double)F_CPU / 10.5e6 + 0.5); - - /* do a binary search: */ - do{ - OSCCAL = trialValue + step; - x = usbMeasureFrameLength(); /* proportional to current real frequency */ - if(x < targetValue) /* frequency still too low */ - trialValue += step; - step >>= 1; - }while(step > 0); - /* We have a precision of +/- 1 for optimum OSCCAL here */ - /* now do a neighborhood search for optimum value */ - optimumValue = trialValue; - optimumDev = x; /* this is certainly far away from optimum */ - for(OSCCAL = trialValue - 1; OSCCAL <= trialValue + 1; OSCCAL++){ - x = usbMeasureFrameLength() - targetValue; - if(x < 0) - x = -x; - if(x < optimumDev){ - optimumDev = x; - optimumValue = OSCCAL; - } - } - OSCCAL = optimumValue; -} -/* -Note: This calibration algorithm may try OSCCAL values of up to 192 even if -the optimum value is far below 192. It may therefore exceed the allowed clock -frequency of the CPU in low voltage designs! -You may replace this search algorithm with any other algorithm you like if -you have additional constraints such as a maximum CPU clock. -For version 5.x RC oscillators (those with a split range of 2x128 steps, e.g. -ATTiny25, ATTiny45, ATTiny85), it may be useful to search for the optimum in -both regions. -*/ diff --git a/tools/avrusb/libs-device/osccal.h b/tools/avrusb/libs-device/osccal.h deleted file mode 100644 index c3c7009..0000000 --- a/tools/avrusb/libs-device/osccal.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Name: osccal.h - * Author: Christian Starkjohann - * Creation Date: 2008-04-10 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: osccal.h 692 2008-11-07 15:07:40Z cs $ - */ - -/* -General Description: -This module contains a function which calibrates the AVR's internal RC -oscillator so that the CPU runs at F_CPU (F_CPU is a macro which must be -defined when the module is compiled, best passed in the compiler command -line). The time reference is the USB frame clock of 1 kHz available -immediately after a USB RESET condition. Timing is done by counting CPU -cycles, so all interrupts must be disabled while the calibration runs. For -low level timing measurements, usbMeasureFrameLength() is called. This -function must be enabled in usbconfig.h by defining -USB_CFG_HAVE_MEASURE_FRAME_LENGTH to 1. It is also recommended to call -calibrateOscillator() from the reset hook in usbconfig.h: - -#ifndef __ASSEMBLER__ -#include /* for sei() */ -extern void calibrateOscillator(void); -#endif -#define USB_RESET_HOOK(resetStarts) if(!resetStarts){cli(); calibrateOscillator(); sei();} - -This routine is an alternative to the continuous synchronization described -in osctune.h. - -Algorithm used: -calibrateOscillator() first does a binary search in the OSCCAL register for -the best matching oscillator frequency. Then it does a next neighbor search -to find the value with the lowest clock rate deviation. It is guaranteed to -find the best match among neighboring values, but for version 5 oscillators -(which have a discontinuous relationship between OSCCAL and frequency) a -better match might be available in another OSCCAL region. - -Limitations: -This calibration algorithm may try OSCCAL values of up to 192 even if the -optimum value is far below 192. It may therefore exceed the allowed clock -frequency of the CPU in low voltage designs! -Precision depends on the OSCCAL vs. frequency dependency of the oscillator. -Typical precision for an ATMega168 (derived from the OSCCAL vs. F_RC diagram -in the data sheet) should be in the range of 0.4%. Only the 12.8 MHz and -16.5 MHz versions of AVR-USB (with built-in receiver PLL) can tolerate this -deviation! All other frequency modules require at least 0.2% precision. -*/ - -#ifndef __OSCCAL_H_INCLUDED__ -#define __OSCCAL_H_INCLUDED__ - -void calibrateOscillator(void); -/* This function calibrates the RC oscillator so that the CPU runs at F_CPU. - * It MUST be called immediately after the end of a USB RESET condition! - * Disable all interrupts during the call! - * It is recommended that you store the resulting value in EEPROM so that a - * good guess value is available after the next reset. - */ - - -#endif /* __OSCCAL_H_INCLUDED__ */ diff --git a/tools/avrusb/libs-device/osctune.h b/tools/avrusb/libs-device/osctune.h deleted file mode 100644 index c751648..0000000 --- a/tools/avrusb/libs-device/osctune.h +++ /dev/null @@ -1,88 +0,0 @@ -/* Name: osctune.h - * Author: Christian Starkjohann - * Creation Date: 2008-10-18 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: osctune.h 692 2008-11-07 15:07:40Z cs $ - */ - -/* -General Description: -This file is declared as C-header file although it is mostly documentation -how the RC oscillator can be kept in sync to the USB frame rate. The code -shown here must be added to usbconfig.h or this header file is included from -there. This code works only if D- is wired to the interrupt, not D+!!! - -This is an alternative to the osccal routine in osccal.c. It has the advantage -that the synchronization is done continuously and that it has more compact -code size. The disadvantages are slow synchronization (it may take a while -until the driver works), that messages immediately after the SOF pulse may be -lost (and need to be retried by the host) and that the interrupt is on D- -contrary to most examples. - -You may want to store a good calibration value in EEPROM for the next startup. -You know that the calibration value is good when the first USB message is -received. Do not store the value on every received message because the EEPROM -has a limited endurance. - -Notes: -(*) You must declare the global character variable "lastTimer0Value" in your -main code. - -(*) Timer 0 must be free running (not written by your code) and the prescaling -must be consistent with the TIMER0_PRESCALING define. - -(*) Good values for Timer 0 prescaling depend on how precise the clock must -be tuned and how far away from the default clock rate the target clock is. -For precise tuning, choose a low prescaler factor, for a broad range of tuning -choose a high one. A prescaler factor of 64 is good for the entire OSCCAL -range and allows a precision of better than +/-1%. A prescaler factor of 8 -allows tuning to slightly more than +/-6% of the default frequency and is -more precise than one step of OSCCAL. It is therefore not suitable to tune an -8 MHz oscillator to 12.5 MHz. - -Thanks to Henrik Haftmann for the idea to this routine! -*/ - -#define TIMER0_PRESCALING 64 /* must match the configuration for TIMER0 in main */ -#define TOLERATED_DEVIATION_PPT 5 /* max clock deviation before we tune in 1/10 % */ -/* derived constants: */ -#define EXPECTED_TIMER0_INCREMENT ((F_CPU / (1000 * TIMER0_PRESCALING)) & 0xff) -#define TOLERATED_DEVIATION (TOLERATED_DEVIATION_PPT * F_CPU / (1000000 * TIMER0_PRESCALING)) - -#ifdef __ASSEMBLER__ -macro tuneOsccal - push YH ;[0] - in YL, TCNT0 ;[2] - lds YH, lastTimer0Value ;[3] - sts lastTimer0Value, YL ;[5] - sub YL, YH ;[7] time passed since last frame - subi YL, EXPECTED_TIMER0_INCREMENT ;[8] -#if OSCCAL > 0x3f /* outside I/O addressable range */ - lds YH, OSCCAL ;[6] -#else - in YH, OSCCAL ;[6] assembler modle uses __SFR_OFFSET == 0 -#endif - cpi YL, TOLERATED_DEVIATION + 1 ;[10] - brmi notTooHigh ;[11] - subi YH, 1 ;[12] clock rate was too high -; brcs tuningOverflow ; optionally check for overflow - rjmp osctuneDone ;[13] -notTooHigh: - cpi YL, -TOLERATED_DEVIATION ;[13] - brpl osctuneDone ;[14] not too low - inc YH ;[15] clock rate was too low -; breq tuningOverflow ; optionally check for overflow -osctuneDone: -#if OSCCAL > 0x3f /* outside I/O addressable range */ - sts OSCCAL, YH ;[12-13] store tuned value -#else - out OSCCAL, YH ;[12-13] store tuned value -#endif -tuningOverflow: - pop YH ;[17] - endm ;[19] max number of cycles -#endif - -#define USB_SOF_HOOK tuneOsccal diff --git a/tools/avrusb/libs-host/Readme.txt b/tools/avrusb/libs-host/Readme.txt deleted file mode 100644 index 5117d18..0000000 --- a/tools/avrusb/libs-host/Readme.txt +++ /dev/null @@ -1,26 +0,0 @@ -This is the Readme file for the libs-host directory. This directory contains -code snippets which may be useful for host side USB software. - - -WHAT IS INCLUDED IN THIS DIRECTORY? -=================================== - -opendevice.c and opendevice.h - This module contains a function to find and open a device given its - numeric IDs (VID, PID), names (vendor name and product name) and serial - number. It is based on libusb/libusb-win32 and returns a libusb device - handle. See opendevice.h for an API documentation. - -hiddata.c and hiddata.h - This module contains functions for data transfer over HID feature reports. - It is based on libusb on Unix and native Windows functions on Windows. No - driver DLL is needed on Windows. See hiddata.h for an API documentation. - -hidsdi.h - This DDK header file is missing in the free MinGW version of the Windows - DDK. Use this version if you get an "include file not found" error. - - ----------------------------------------------------------------------------- -(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH. -http://www.obdev.at/ diff --git a/tools/avrusb/libs-host/hiddata.c b/tools/avrusb/libs-host/hiddata.c deleted file mode 100644 index 8e7d975..0000000 --- a/tools/avrusb/libs-host/hiddata.c +++ /dev/null @@ -1,317 +0,0 @@ -/* Name: hiddata.c - * Author: Christian Starkjohann - * Creation Date: 2008-04-11 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: hiddata.c 692 2008-11-07 15:07:40Z cs $ - */ - -#include -#include "hiddata.h" - -/* ######################################################################## */ -#if defined(WIN32) /* ##################################################### */ -/* ######################################################################## */ - -#include -#include -#include "hidsdi.h" -#include - -#ifdef DEBUG -#define DEBUG_PRINT(arg) printf arg -#else -#define DEBUG_PRINT(arg) -#endif - -/* ------------------------------------------------------------------------ */ - -static void convertUniToAscii(char *buffer) -{ -unsigned short *uni = (void *)buffer; -char *ascii = buffer; - - while(*uni != 0){ - if(*uni >= 256){ - *ascii++ = '?'; - }else{ - *ascii++ = *uni++; - } - } - *ascii++ = 0; -} - -int usbhidOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int usesReportIDs) -{ -GUID hidGuid; /* GUID for HID driver */ -HDEVINFO deviceInfoList; -SP_DEVICE_INTERFACE_DATA deviceInfo; -SP_DEVICE_INTERFACE_DETAIL_DATA *deviceDetails = NULL; -DWORD size; -int i, openFlag = 0; /* may be FILE_FLAG_OVERLAPPED */ -int errorCode = USBOPEN_ERR_NOTFOUND; -HANDLE handle = INVALID_HANDLE_VALUE; -HIDD_ATTRIBUTES deviceAttributes; - - HidD_GetHidGuid(&hidGuid); - deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); - deviceInfo.cbSize = sizeof(deviceInfo); - for(i=0;;i++){ - if(handle != INVALID_HANDLE_VALUE){ - CloseHandle(handle); - handle = INVALID_HANDLE_VALUE; - } - if(!SetupDiEnumDeviceInterfaces(deviceInfoList, 0, &hidGuid, i, &deviceInfo)) - break; /* no more entries */ - /* first do a dummy call just to determine the actual size required */ - SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL); - if(deviceDetails != NULL) - free(deviceDetails); - deviceDetails = malloc(size); - deviceDetails->cbSize = sizeof(*deviceDetails); - /* this call is for real: */ - SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails, size, &size, NULL); - DEBUG_PRINT(("checking HID path \"%s\"\n", deviceDetails->DevicePath)); - /* attempt opening for R/W -- we don't care about devices which can't be accessed */ - handle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, openFlag, NULL); - if(handle == INVALID_HANDLE_VALUE){ - DEBUG_PRINT(("opening failed: %d\n", (int)GetLastError())); - /* errorCode = USBOPEN_ERR_ACCESS; opening will always fail for mouse -- ignore */ - continue; - } - deviceAttributes.Size = sizeof(deviceAttributes); - HidD_GetAttributes(handle, &deviceAttributes); - DEBUG_PRINT(("device attributes: vid=%d pid=%d\n", deviceAttributes.VendorID, deviceAttributes.ProductID)); - if(deviceAttributes.VendorID != vendor || deviceAttributes.ProductID != product) - continue; /* ignore this device */ - errorCode = USBOPEN_ERR_NOTFOUND; - if(vendorName != NULL && productName != NULL){ - char buffer[512]; - if(!HidD_GetManufacturerString(handle, buffer, sizeof(buffer))){ - DEBUG_PRINT(("error obtaining vendor name\n")); - errorCode = USBOPEN_ERR_IO; - continue; - } - convertUniToAscii(buffer); - DEBUG_PRINT(("vendorName = \"%s\"\n", buffer)); - if(strcmp(vendorName, buffer) != 0) - continue; - if(!HidD_GetProductString(handle, buffer, sizeof(buffer))){ - DEBUG_PRINT(("error obtaining product name\n")); - errorCode = USBOPEN_ERR_IO; - continue; - } - convertUniToAscii(buffer); - DEBUG_PRINT(("productName = \"%s\"\n", buffer)); - if(strcmp(productName, buffer) != 0) - continue; - } - break; /* we have found the device we are looking for! */ - } - SetupDiDestroyDeviceInfoList(deviceInfoList); - if(deviceDetails != NULL) - free(deviceDetails); - if(handle != INVALID_HANDLE_VALUE){ - *device = (usbDevice_t *)handle; - errorCode = 0; - } - return errorCode; -} - -/* ------------------------------------------------------------------------ */ - -void usbhidCloseDevice(usbDevice_t *device) -{ - CloseHandle((HANDLE)device); -} - -/* ------------------------------------------------------------------------ */ - -int usbhidSetReport(usbDevice_t *device, char *buffer, int len) -{ -BOOLEAN rval; - - rval = HidD_SetFeature((HANDLE)device, buffer, len); - return rval == 0 ? USBOPEN_ERR_IO : 0; -} - -/* ------------------------------------------------------------------------ */ - -int usbhidGetReport(usbDevice_t *device, int reportNumber, char *buffer, int *len) -{ -BOOLEAN rval = 0; - - buffer[0] = reportNumber; - rval = HidD_GetFeature((HANDLE)device, buffer, *len); - return rval == 0 ? USBOPEN_ERR_IO : 0; -} - -/* ------------------------------------------------------------------------ */ - -/* ######################################################################## */ -#else /* defined WIN32 #################################################### */ -/* ######################################################################## */ - -#include -#include - -#define usbDevice usb_dev_handle /* use libusb's device structure */ - -/* ------------------------------------------------------------------------- */ - -#define USBRQ_HID_GET_REPORT 0x01 -#define USBRQ_HID_SET_REPORT 0x09 - -#define USB_HID_REPORT_TYPE_FEATURE 3 - - -static int usesReportIDs; - -/* ------------------------------------------------------------------------- */ - -static int usbhidGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen) -{ -char buffer[256]; -int rval, i; - - if((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use libusb version if it works */ - return rval; - if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, 0x0409, buffer, sizeof(buffer), 5000)) < 0) - return rval; - if(buffer[1] != USB_DT_STRING){ - *buf = 0; - return 0; - } - if((unsigned char)buffer[0] < rval) - rval = (unsigned char)buffer[0]; - rval /= 2; - /* lossy conversion to ISO Latin1: */ - for(i=1;i buflen) /* destination buffer overflow */ - break; - buf[i-1] = buffer[2 * i]; - if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */ - buf[i-1] = '?'; - } - buf[i-1] = 0; - return i-1; -} - -int usbhidOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int _usesReportIDs) -{ -struct usb_bus *bus; -struct usb_device *dev; -usb_dev_handle *handle = NULL; -int errorCode = USBOPEN_ERR_NOTFOUND; -static int didUsbInit = 0; - - if(!didUsbInit){ - usb_init(); - didUsbInit = 1; - } - usb_find_busses(); - usb_find_devices(); - for(bus=usb_get_busses(); bus; bus=bus->next){ - for(dev=bus->devices; dev; dev=dev->next){ - if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product){ - char string[256]; - int len; - handle = usb_open(dev); /* we need to open the device in order to query strings */ - if(!handle){ - errorCode = USBOPEN_ERR_ACCESS; - fprintf(stderr, "Warning: cannot open USB device: %s\n", usb_strerror()); - continue; - } - if(vendorName == NULL && productName == NULL){ /* name does not matter */ - break; - } - /* now check whether the names match: */ - len = usbhidGetStringAscii(handle, dev->descriptor.iManufacturer, string, sizeof(string)); - if(len < 0){ - errorCode = USBOPEN_ERR_IO; - fprintf(stderr, "Warning: cannot query manufacturer for device: %s\n", usb_strerror()); - }else{ - errorCode = USBOPEN_ERR_NOTFOUND; - /* fprintf(stderr, "seen device from vendor ->%s<-\n", string); */ - if(strcmp(string, vendorName) == 0){ - len = usbhidGetStringAscii(handle, dev->descriptor.iProduct, string, sizeof(string)); - if(len < 0){ - errorCode = USBOPEN_ERR_IO; - fprintf(stderr, "Warning: cannot query product for device: %s\n", usb_strerror()); - }else{ - errorCode = USBOPEN_ERR_NOTFOUND; - /* fprintf(stderr, "seen product ->%s<-\n", string); */ - if(strcmp(string, productName) == 0) - break; - } - } - } - usb_close(handle); - handle = NULL; - } - } - if(handle) - break; - } - if(handle != NULL){ - errorCode = 0; - *device = (void *)handle; - usesReportIDs = _usesReportIDs; - } - return errorCode; -} - -/* ------------------------------------------------------------------------- */ - -void usbhidCloseDevice(usbDevice_t *device) -{ - if(device != NULL) - usb_close((void *)device); -} - -/* ------------------------------------------------------------------------- */ - -int usbhidSetReport(usbDevice_t *device, char *buffer, int len) -{ -int bytesSent; - - if(!usesReportIDs){ - buffer++; /* skip dummy report ID */ - len--; - } - bytesSent = usb_control_msg((void *)device, USB_TYPE_CLASS | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, USBRQ_HID_SET_REPORT, USB_HID_REPORT_TYPE_FEATURE << 8 | (buffer[0] & 0xff), 0, buffer, len, 5000); - if(bytesSent != len){ - if(bytesSent < 0) - fprintf(stderr, "Error sending message: %s\n", usb_strerror()); - return USBOPEN_ERR_IO; - } - return 0; -} - -/* ------------------------------------------------------------------------- */ - -int usbhidGetReport(usbDevice_t *device, int reportNumber, char *buffer, int *len) -{ -int bytesReceived, maxLen = *len; - - if(!usesReportIDs){ - buffer++; /* make room for dummy report ID */ - maxLen--; - } - bytesReceived = usb_control_msg((void *)device, USB_TYPE_CLASS | USB_RECIP_DEVICE | USB_ENDPOINT_IN, USBRQ_HID_GET_REPORT, USB_HID_REPORT_TYPE_FEATURE << 8 | reportNumber, 0, buffer, maxLen, 5000); - if(bytesReceived < 0){ - fprintf(stderr, "Error sending message: %s\n", usb_strerror()); - return USBOPEN_ERR_IO; - } - *len = bytesReceived; - if(!usesReportIDs){ - buffer[-1] = reportNumber; /* add dummy report ID */ - (*len)++; - } - return 0; -} - -/* ######################################################################## */ -#endif /* defined WIN32 ################################################### */ -/* ######################################################################## */ diff --git a/tools/avrusb/libs-host/hiddata.h b/tools/avrusb/libs-host/hiddata.h deleted file mode 100644 index fce0743..0000000 --- a/tools/avrusb/libs-host/hiddata.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Name: hiddata.h - * Author: Christian Starkjohann - * Creation Date: 2008-04-11 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: hiddata.h 692 2008-11-07 15:07:40Z cs $ - */ - -#ifndef __HIDDATA_H_INCLUDED__ -#define __HIDDATA_H_INCLUDED__ - -/* -General Description: -This module implements an abstraction layer for data transfer over HID feature -requests. The implementation uses native Windows functions on Windows so that -no driver installation is required and libusb on Unix. You must link the -appropriate libraries in either case: "-lhid -lusb -lsetupapi" on Windows and -`libusb-config --libs` on Unix. -*/ - -/* ------------------------------------------------------------------------ */ - -#define USBOPEN_SUCCESS 0 /* no error */ -#define USBOPEN_ERR_ACCESS 1 /* not enough permissions to open device */ -#define USBOPEN_ERR_IO 2 /* I/O error */ -#define USBOPEN_ERR_NOTFOUND 3 /* device not found */ - -/* ------------------------------------------------------------------------ */ - -typedef struct usbDevice usbDevice_t; -/* Opaque data type representing the USB device. This can be a Windows handle - * or a libusb handle, depending on the backend implementation. - */ - -/* ------------------------------------------------------------------------ */ - -int usbhidOpenDevice(usbDevice_t **device, int vendorID, char *vendorName, int productID, char *productName, int usesReportIDs); -/* This function opens a USB device. 'vendorID' and 'productID' are the numeric - * Vendor-ID and Product-ID of the device we want to open. If 'vendorName' and - * 'productName' are both not NULL, only devices with matching manufacturer- - * and product name strings are accepted. If the device uses report IDs, - * 'usesReportIDs' must be set to a non-zero value. - * Returns: If a matching device has been found, USBOPEN_SUCCESS is returned - * and '*device' is set to an opaque pointer representing the device. The - * device must be closed with usbhidCloseDevice(). If the device has not been - * found or opening failed, an error code is returned. - */ -void usbhidCloseDevice(usbDevice_t *device); -/* Every device opened with usbhidOpenDevice() must be closed with this function. - */ -int usbhidSetReport(usbDevice_t *device, char *buffer, int len); -/* This function sends a feature report to the device. The report ID must be - * in the first byte of buffer and the length 'len' of the report is specified - * including this report ID. If no report IDs are used, buffer[0] must be set - * to 0 (dummy report ID). - * Returns: 0 on success, an error code otherwise. - */ -int usbhidGetReport(usbDevice_t *device, int reportID, char *buffer, int *len); -/* This function obtains a feature report from the device. The requested - * report-ID is passed in 'reportID'. The caller must pass a buffer of the size - * of the expected report in 'buffer' and initialize the variable pointed to by - * 'len' to the total size of this buffer. Upon successful return, the report - * (prefixed with the report-ID) is in 'buffer' and the actual length of the - * report is returned in '*len'. - * Returns: 0 on success, an error code otherwise. - */ - -/* ------------------------------------------------------------------------ */ - -#endif /* __HIDDATA_H_INCLUDED__ */ diff --git a/tools/avrusb/libs-host/hidsdi.h b/tools/avrusb/libs-host/hidsdi.h deleted file mode 100644 index a549ab1..0000000 --- a/tools/avrusb/libs-host/hidsdi.h +++ /dev/null @@ -1,49 +0,0 @@ -/* Name: hidsdi.h - * Author: Christian Starkjohann - * Creation Date: 2006-02-02 - * Tabsize: 4 - * Copyright: (c) 2006-2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: hidsdi.h 692 2008-11-07 15:07:40Z cs $ - */ - -/* -General Description -This file is a replacement for hidsdi.h from the Windows DDK. It defines some -of the types and function prototypes of this header for our project. If you -have the Windows DDK version of this file or a version shipped with MinGW, use -that instead. -*/ - -#ifndef _HIDSDI_H -#define _HIDSDI_H - -#include - -#include -#include - -typedef struct{ - ULONG Size; - USHORT VendorID; - USHORT ProductID; - USHORT VersionNumber; -}HIDD_ATTRIBUTES; - -void __stdcall HidD_GetHidGuid(OUT LPGUID hidGuid); - -BOOLEAN __stdcall HidD_GetAttributes(IN HANDLE device, OUT HIDD_ATTRIBUTES *attributes); - -BOOLEAN __stdcall HidD_GetManufacturerString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen); -BOOLEAN __stdcall HidD_GetProductString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen); -BOOLEAN __stdcall HidD_GetSerialNumberString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen); - -BOOLEAN __stdcall HidD_GetFeature(IN HANDLE device, OUT void *reportBuffer, IN ULONG bufferLen); -BOOLEAN __stdcall HidD_SetFeature(IN HANDLE device, IN void *reportBuffer, IN ULONG bufferLen); - -BOOLEAN __stdcall HidD_GetNumInputBuffers(IN HANDLE device, OUT ULONG *numBuffers); -BOOLEAN __stdcall HidD_SetNumInputBuffers(IN HANDLE device, OUT ULONG numBuffers); - -#include - -#endif diff --git a/tools/avrusb/libs-host/opendevice.c b/tools/avrusb/libs-host/opendevice.c deleted file mode 100644 index 791175b..0000000 --- a/tools/avrusb/libs-host/opendevice.c +++ /dev/null @@ -1,203 +0,0 @@ -/* Name: opendevice.c - * Project: AVR-USB host-side library - * Author: Christian Starkjohann - * Creation Date: 2008-04-10 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: opendevice.c 692 2008-11-07 15:07:40Z cs $ - */ - -/* -General Description: -The functions in this module can be used to find and open a device based on -libusb or libusb-win32. -*/ - -#include -#include "opendevice.h" - -/* ------------------------------------------------------------------------- */ - -#define MATCH_SUCCESS 1 -#define MATCH_FAILED 0 -#define MATCH_ABORT -1 - -/* private interface: match text and p, return MATCH_SUCCESS, MATCH_FAILED, or MATCH_ABORT. */ -static int _shellStyleMatch(char *text, char *p) -{ -int last, matched, reverse; - - for(; *p; text++, p++){ - if(*text == 0 && *p != '*') - return MATCH_ABORT; - switch(*p){ - case '\\': - /* Literal match with following character. */ - p++; - /* FALLTHROUGH */ - default: - if(*text != *p) - return MATCH_FAILED; - continue; - case '?': - /* Match anything. */ - continue; - case '*': - while(*++p == '*') - /* Consecutive stars act just like one. */ - continue; - if(*p == 0) - /* Trailing star matches everything. */ - return MATCH_SUCCESS; - while(*text) - if((matched = _shellStyleMatch(text++, p)) != MATCH_FAILED) - return matched; - return MATCH_ABORT; - case '[': - reverse = p[1] == '^'; - if(reverse) /* Inverted character class. */ - p++; - matched = MATCH_FAILED; - if(p[1] == ']' || p[1] == '-') - if(*++p == *text) - matched = MATCH_SUCCESS; - for(last = *p; *++p && *p != ']'; last = *p) - if (*p == '-' && p[1] != ']' ? *text <= *++p && *text >= last : *text == *p) - matched = MATCH_SUCCESS; - if(matched == reverse) - return MATCH_FAILED; - continue; - } - } - return *text == 0; -} - -/* public interface for shell style matching: returns 0 if fails, 1 if matches */ -static int shellStyleMatch(char *text, char *pattern) -{ - if(pattern == NULL) /* NULL pattern is synonymous to "*" */ - return 1; - return _shellStyleMatch(text, pattern) == MATCH_SUCCESS; -} - -/* ------------------------------------------------------------------------- */ - -int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen) -{ -char buffer[256]; -int rval, i; - - if((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use libusb version if it works */ - return rval; - if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, 0x0409, buffer, sizeof(buffer), 5000)) < 0) - return rval; - if(buffer[1] != USB_DT_STRING){ - *buf = 0; - return 0; - } - if((unsigned char)buffer[0] < rval) - rval = (unsigned char)buffer[0]; - rval /= 2; - /* lossy conversion to ISO Latin1: */ - for(i=1;i buflen) /* destination buffer overflow */ - break; - buf[i-1] = buffer[2 * i]; - if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */ - buf[i-1] = '?'; - } - buf[i-1] = 0; - return i-1; -} - -/* ------------------------------------------------------------------------- */ - -int usbOpenDevice(usb_dev_handle **device, int vendorID, char *vendorNamePattern, int productID, char *productNamePattern, char *serialNamePattern, FILE *printMatchingDevicesFp, FILE *warningsFp) -{ -struct usb_bus *bus; -struct usb_device *dev; -usb_dev_handle *handle = NULL; -int errorCode = USBOPEN_ERR_NOTFOUND; - - usb_find_busses(); - usb_find_devices(); - for(bus = usb_get_busses(); bus; bus = bus->next){ - for(dev = bus->devices; dev; dev = dev->next){ /* iterate over all devices on all busses */ - if((vendorID == 0 || dev->descriptor.idVendor == vendorID) - && (productID == 0 || dev->descriptor.idProduct == productID)){ - char vendor[256], product[256], serial[256]; - int len; - handle = usb_open(dev); /* we need to open the device in order to query strings */ - if(!handle){ - errorCode = USBOPEN_ERR_ACCESS; - if(warningsFp != NULL) - fprintf(warningsFp, "Warning: cannot open VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); - continue; - } - /* now check whether the names match: */ - len = vendor[0] = 0; - if(dev->descriptor.iManufacturer > 0){ - len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, vendor, sizeof(vendor)); - } - if(len < 0){ - errorCode = USBOPEN_ERR_ACCESS; - if(warningsFp != NULL) - fprintf(warningsFp, "Warning: cannot query manufacturer for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); - }else{ - errorCode = USBOPEN_ERR_NOTFOUND; - /* printf("seen device from vendor ->%s<-\n", vendor); */ - if(shellStyleMatch(vendor, vendorNamePattern)){ - len = product[0] = 0; - if(dev->descriptor.iProduct > 0){ - len = usbGetStringAscii(handle, dev->descriptor.iProduct, product, sizeof(product)); - } - if(len < 0){ - errorCode = USBOPEN_ERR_ACCESS; - if(warningsFp != NULL) - fprintf(warningsFp, "Warning: cannot query product for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); - }else{ - errorCode = USBOPEN_ERR_NOTFOUND; - /* printf("seen product ->%s<-\n", product); */ - if(shellStyleMatch(product, productNamePattern)){ - len = serial[0] = 0; - if(dev->descriptor.iSerialNumber > 0){ - len = usbGetStringAscii(handle, dev->descriptor.iSerialNumber, serial, sizeof(serial)); - } - if(len < 0){ - errorCode = USBOPEN_ERR_ACCESS; - if(warningsFp != NULL) - fprintf(warningsFp, "Warning: cannot query serial for VID=0x%04x PID=0x%04x: %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, usb_strerror()); - } - if(shellStyleMatch(serial, serialNamePattern)){ - if(printMatchingDevicesFp != NULL){ - if(serial[0] == 0){ - fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product); - }else{ - fprintf(printMatchingDevicesFp, "VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\" serial=\"%s\"\n", dev->descriptor.idVendor, dev->descriptor.idProduct, vendor, product, serial); - } - }else{ - break; - } - } - } - } - } - } - usb_close(handle); - handle = NULL; - } - } - if(handle) /* we have found a deice */ - break; - } - if(handle != NULL){ - errorCode = 0; - *device = handle; - } - if(printMatchingDevicesFp != NULL) /* never return an error for listing only */ - errorCode = 0; - return errorCode; -} - -/* ------------------------------------------------------------------------- */ diff --git a/tools/avrusb/libs-host/opendevice.h b/tools/avrusb/libs-host/opendevice.h deleted file mode 100644 index 5e9b68b..0000000 --- a/tools/avrusb/libs-host/opendevice.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Name: opendevice.h - * Project: AVR-USB host-side library - * Author: Christian Starkjohann - * Creation Date: 2008-04-10 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: opendevice.h 692 2008-11-07 15:07:40Z cs $ - */ - -/* -General Description: -This module offers additional functionality for host side drivers based on -libusb or libusb-win32. It includes a function to find and open a device -based on numeric IDs and textual description. It also includes a function to -obtain textual descriptions from a device. - -To use this functionality, simply copy opendevice.c and opendevice.h into your -project and add them to your Makefile. You may modify and redistribute these -files according to the GNU General Public License (GPL) version 2 or 3. -*/ - -#ifndef __OPENDEVICE_H_INCLUDED__ -#define __OPENDEVICE_H_INCLUDED__ - -#include /* this is libusb, see http://libusb.sourceforge.net/ */ -#include - -int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen); -/* This function gets a string descriptor from the device. 'index' is the - * string descriptor index. The string is returned in ISO Latin 1 encoding in - * 'buf' and it is terminated with a 0-character. The buffer size must be - * passed in 'buflen' to prevent buffer overflows. A libusb device handle - * must be given in 'dev'. - * Returns: The length of the string (excluding the terminating 0) or - * a negative number in case of an error. If there was an error, use - * usb_strerror() to obtain the error message. - */ - -int usbOpenDevice(usb_dev_handle **device, int vendorID, char *vendorNamePattern, int productID, char *productNamePattern, char *serialNamePattern, FILE *printMatchingDevicesFp, FILE *warningsFp); -/* This function iterates over all devices on all USB busses and searches for - * a device. Matching is done first by means of Vendor- and Product-ID (passed - * in 'vendorID' and 'productID'. An ID of 0 matches any numeric ID (wildcard). - * When a device matches by its IDs, matching by names is performed. Name - * matching can be done on textual vendor name ('vendorNamePattern'), product - * name ('productNamePattern') and serial number ('serialNamePattern'). A - * device matches only if all non-null pattern match. If you don't care about - * a string, pass NULL for the pattern. Patterns are Unix shell style pattern: - * '*' stands for 0 or more characters, '?' for one single character, a list - * of characters in square brackets for a single character from the list - * (dashes are allowed to specify a range) and if the lis of characters begins - * with a caret ('^'), it matches one character which is NOT in the list. - * Other parameters to the function: If 'warningsFp' is not NULL, warning - * messages are printed to this file descriptor with fprintf(). If - * 'printMatchingDevicesFp' is not NULL, no device is opened but matching - * devices are printed to the given file descriptor with fprintf(). - * If a device is opened, the resulting USB handle is stored in '*device'. A - * pointer to a "usb_dev_handle *" type variable must be passed here. - * Returns: 0 on success, an error code (see defines below) on failure. - */ - -/* usbOpenDevice() error codes: */ -#define USBOPEN_SUCCESS 0 /* no error */ -#define USBOPEN_ERR_ACCESS 1 /* not enough permissions to open device */ -#define USBOPEN_ERR_IO 2 /* I/O error */ -#define USBOPEN_ERR_NOTFOUND 3 /* device not found */ - - -/* Obdev's free USB IDs, see USBID-License.txt for details */ - -#define USB_VID_OBDEV_SHARED 5824 /* obdev's shared vendor ID */ -#define USB_PID_OBDEV_SHARED_CUSTOM 1500 /* shared PID for custom class devices */ -#define USB_PID_OBDEV_SHARED_HID 1503 /* shared PID for HIDs except mice & keyboards */ -#define USB_PID_OBDEV_SHARED_CDCACM 1505 /* shared PID for CDC Modem devices */ -#define USB_PID_OBDEV_SHARED_MIDI 1508 /* shared PID for MIDI class devices */ - -#endif /* __OPENDEVICE_H_INCLUDED__ */ diff --git a/tools/avrusb/tests/Makefile b/tools/avrusb/tests/Makefile deleted file mode 100644 index 74b2518..0000000 --- a/tools/avrusb/tests/Makefile +++ /dev/null @@ -1,127 +0,0 @@ -# Name: Makefile -# Project: custom-class example -# Author: Christian Starkjohann -# Creation Date: 2008-04-07 -# Tabsize: 4 -# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH -# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) -# This Revision: $Id: Makefile 719 2009-03-16 18:51:56Z cs $ - -DEVICE = attiny2313 -F_CPU = 16000000 # in Hz -DEFINES = - -CFLAGS = $(DEFINES) -Iusbdrv -I. -DDEBUG_LEVEL=0 -OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o - -COMPILE = avr-gcc -Wall -Os -DF_CPU=$(F_CPU) $(CFLAGS) -mmcu=$(DEVICE) - -SIZES_TMP = /tmp/sizetmp.txt - -# symbolic targets: -help: - @echo "This Makefile has no default rule. Use one of the following:" - @echo "make clean ..... to delete objects and hex file" - @echo "make sizes ..... compute code and RAM sizes for various options" - @echo "make test ...... test with all features whether everything compiles" - -sizes sizes.txt: - rm -f $(SIZES_TMP) sizes.txt - $(MAKE) null.elf - avr-size null.elf | tail -1 | awk '{print "null", $$1+$$2, $$3+$$2}' >$(SIZES_TMP) - $(MAKE) clean; $(MAKE) main.elf - avr-size main.elf | tail -1 | awk '{print "Minimum_with_16_MHz", $$1+$$2, $$3+$$2}' >>$(SIZES_TMP) - $(MAKE) clean; $(MAKE) main.elf F_CPU=12000000 - avr-size main.elf | tail -1 | awk '{print "Minimum_with_12_MHz", $$1+$$2, $$3+$$2}' >>$(SIZES_TMP) - $(MAKE) clean; $(MAKE) main.elf F_CPU=12800000 - avr-size main.elf | tail -1 | awk '{print "Minimum_with_12_8_MHz", $$1+$$2, $$3+$$2}' >>$(SIZES_TMP) - $(MAKE) clean; $(MAKE) main.elf F_CPU=15000000 - avr-size main.elf | tail -1 | awk '{print "Minimum_with_15_MHz", $$1+$$2, $$3+$$2}' >>$(SIZES_TMP) - $(MAKE) clean; $(MAKE) main.elf F_CPU=16500000 - avr-size main.elf | tail -1 | awk '{print "Minimum_with_16_5_MHz", $$1+$$2, $$3+$$2}' >>$(SIZES_TMP) - $(MAKE) clean; $(MAKE) main.elf F_CPU=18000000 - avr-size main.elf | tail -1 | awk '{print "Minimum_with_18_MHz+CRC", $$1+$$2, $$3+$$2}' >>$(SIZES_TMP) - $(MAKE) clean; $(MAKE) main.elf F_CPU=20000000 - avr-size main.elf | tail -1 | awk '{print "Minimum_with_20_MHz", $$1+$$2, $$3+$$2}' >>$(SIZES_TMP) - $(MAKE) clean; $(MAKE) main.elf DEFINES=-DUSB_CFG_IMPLEMENT_FN_WRITE=1 - avr-size main.elf | tail -1 | awk '{print "With_usbFunctionWrite", $$1+$$2, $$3+$$2}' >>$(SIZES_TMP) - $(MAKE) clean; $(MAKE) main.elf DEFINES=-DUSB_CFG_IMPLEMENT_FN_READ=1 - avr-size main.elf | tail -1 | awk '{print "With_usbFunctionRead", $$1+$$2, $$3+$$2}' >>$(SIZES_TMP) - $(MAKE) clean; $(MAKE) main.elf "DEFINES=-DUSB_CFG_IMPLEMENT_FN_READ=1 -DUSB_CFG_IMPLEMENT_FN_WRITE=1" - avr-size main.elf | tail -1 | awk '{print "With_usbFunctionRead_and_Write", $$1+$$2, $$3+$$2}' >>$(SIZES_TMP) - $(MAKE) clean; $(MAKE) main.elf "DEFINES=-DUSB_CFG_IMPLEMENT_FN_WRITEOUT=1" - avr-size main.elf | tail -1 | awk '{print "With_usbFunctionWriteOut", $$1+$$2, $$3+$$2}' >>$(SIZES_TMP) - $(MAKE) clean; $(MAKE) main.elf "DEFINES=-DUSB_CFG_HAVE_INTRIN_ENDPOINT=1" - avr-size main.elf | tail -1 | awk '{print "With_Interrupt_In_Endpoint_1", $$1+$$2, $$3+$$2}' >>$(SIZES_TMP) - $(MAKE) clean; $(MAKE) main.elf "DEFINES=-DUSB_CFG_IMPLEMENT_HALT=1 -DUSB_CFG_HAVE_INTRIN_ENDPOINT=1" - avr-size main.elf | tail -1 | awk '{print "With_Interrupt_In_Endpoint_1_and_Halt", $$1+$$2, $$3+$$2}' >>$(SIZES_TMP) - $(MAKE) clean; $(MAKE) main.elf "DEFINES=-DUSB_CFG_HAVE_INTRIN_ENDPOINT3=1" - avr-size main.elf | tail -1 | awk '{print "With_Interrupt_In_Endpoint_1_and_3", $$1+$$2, $$3+$$2}' >>$(SIZES_TMP) - $(MAKE) clean; $(MAKE) main.elf "DEFINES=-DUSE_DYNAMIC_DESCRIPTOR=1" - avr-size main.elf | tail -1 | awk '{print "With_Dynamic_Descriptor", $$1+$$2, $$3+$$2}' >>$(SIZES_TMP) - $(MAKE) clean; $(MAKE) main.elf "DEFINES=-DUSB_CFG_LONG_TRANSFERS=1" - avr-size main.elf | tail -1 | awk '{print "With_Long_Transfers", $$1+$$2, $$3+$$2}' >>$(SIZES_TMP) - cat $(SIZES_TMP) | awk 'BEGIN{printf("%39s %5s %5s %5s %5s\n"), "Variation", "Flash", "RAM", "+F", "+RAM"}\ - /^null/{nullRom=$$2; nullRam=$$3; next} \ - {rom=$$2-nullRom; ram=$$3-nullRam; if(!refRom){refRom=rom; refRam=ram} \ - printf("%39s %5d %5d %+5d %+5d\n", $$1, rom, ram, rom-refRom, ram-refRam)}' | tee sizes.txt - rm $(SIZES_TMP) - -test: - for freq in 12000000 12800000 15000000 16000000 16500000 18000000 20000000; do \ - for opt in USB_COUNT_SOF USB_CFG_HAVE_INTRIN_ENDPOINT USB_CFG_HAVE_INTRIN_ENDPOINT3 USB_CFG_HAVE_MEASURE_FRAME_LENGTH USB_CFG_LONG_TRANSFERS; do \ - $(MAKE) clean; $(MAKE) main.elf F_CPU=$$freq "DEFINES=-D$$opt=1" || exit 1; \ - $(MAKE) clean; $(MAKE) main.elf F_CPU=$$freq "DEFINES=-D$$opt=1 -DDUSB_CFG_IMPLEMENT_FN_WRITEOUT=1" || exit 1; \ - done \ - done - -# The following rule is used to check the compiler -devices: #exclude devices without RAM for stack and atmega603 for gcc 3 - excludes="at90s1200 attiny11 attiny12 attiny15 attiny28"; \ - for gccVersion in 3 4; do \ - avr-gcc-select $$gccVersion; \ - for device in `echo | avr-gcc -xc -mmcu=x - 2>&1 | egrep '^ *at[a-zA-Z0-9_-]+$$'`; do \ - if echo "$$excludes" | grep "$$device" >/dev/null; then continue; fi; \ - if [ "$$gccVersion" = 3 -a "$$device" = atmega603 ]; then continue; fi; \ - $(MAKE) clean; $(MAKE) null.elf DEVICE=$$device || exit 1; \ - done \ - done - $(MAKE) clean - avr-gcc-select 3 - @echo "+++ Device test succeeded!" - -# rule for deleting dependent files (those which can be built by Make): -clean: - rm -f *.hex *.lst *.map *.elf *.o - rm -rf usbdrv - -# Generic rule for compiling C files: -.c.o: - $(COMPILE) -c $< -o $@ - -# Generic rule for assembling Assembler source files: -.S.o: - $(COMPILE) -x assembler-with-cpp -c $< -o $@ -# "-x assembler-with-cpp" should not be necessary since this is the default -# file type for the .S (with capital S) extension. However, upper case -# characters are not always preserved on Windows. To ensure WinAVR -# compatibility define the file type manually. - -# Generic rule for compiling C to assembler, used for debugging only. -.c.s: - $(COMPILE) -S $< -o $@ - -# file targets: - -# Since we don't want to ship the driver multipe times, we copy it into this project: -usbdrv: - cp -r ../usbdrv . - -main.elf: usbdrv $(OBJECTS) # usbdrv dependency only needed because we copy it - $(COMPILE) -o main.elf $(OBJECTS) - -main_i.elf: usbdrv main.o usbdrv/usbdrvasm.o # usbdrv dependency only needed because we copy it - $(COMPILE) -o main_i.elf main.o usbdrv/usbdrvasm.o - -null.elf: null.o - $(COMPILE) -o null.elf null.o diff --git a/tools/avrusb/tests/Readme.txt b/tools/avrusb/tests/Readme.txt deleted file mode 100644 index f9fdeda..0000000 --- a/tools/avrusb/tests/Readme.txt +++ /dev/null @@ -1,13 +0,0 @@ -This is the Readme file for the directory "tests" of AVR-USB, a firmware-only -USB driver for AVR microcontrollers. - -WHAT IS IN THIS DIRECTORY? -========================== -This directory is for driver development only. It contains tests to check -whether all branches of #ifdef code compile as they should and whether the -code size of the driver increased. - - ----------------------------------------------------------------------------- -(c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH. -http://www.obdev.at/ diff --git a/tools/avrusb/tests/compare-sizes.awk b/tools/avrusb/tests/compare-sizes.awk deleted file mode 100644 index 659599e..0000000 --- a/tools/avrusb/tests/compare-sizes.awk +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/awk -f -# Name: compare-sizes.awk -# Project: avr-usb -# Author: Christian Starkjohann -# Creation Date: 2008-04-29 -# Tabsize: 4 -# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH -# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) -# This Revision: $Id$ - -BEGIN{ - opt = 0; - if(ARGC != 3){ - printf("usage: compare-sizes.awk file1 file2\n"); - printf(" computes size differences between two size lists\n"); - exit 1; - } - file1 = ARGV[1]; - file2 = ARGV[2]; -} - -{ - if(($2 + 0) != 0){ - if(!hadOption[$1]){ - hadOption[$1] = 1; - options[opt++] = $1; - } - flash[FILENAME, $1] = $2; - ram[FILENAME, $1] = $3; - } -} - -END{ - if(opt > 0){ - printf ("%39s %6s %5s\n", "Variation", "+Flash", "+RAM"); - } - for(i = 0; i < opt; i++){ - option = options[i]; - if(!flash[file2, option] || !flash[file1, option]){ - printf("%39s %6s %5s\n", option, "n/a", "n/a"); - }else{ - printf("%39s %+6d %+5d\n", option, flash[file2, option] - flash[file1, option], ram[file2, option] - ram[file1, option]); - } - } -} diff --git a/tools/avrusb/tests/main.c b/tools/avrusb/tests/main.c deleted file mode 100644 index f1beb87..0000000 --- a/tools/avrusb/tests/main.c +++ /dev/null @@ -1,159 +0,0 @@ -/* Name: main.c - * Project: Testing driver features - * Author: Christian Starkjohann - * Creation Date: 2008-04-29 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: main.c 692 2008-11-07 15:07:40Z cs $ - */ - -/* -This module is a do-nothing test code linking against (or including) the USB -driver. It is used to determine the code size for various options and to -check whether the code compiles with all options. -*/ -#include -#include /* for sei() */ -#include /* required by usbdrv.h */ -#include /* for _delay_ms() */ -#include "usbdrv.h" -#if USE_INCLUDE -#include "usbdrv.c" -#endif - -/* ------------------------------------------------------------------------- */ -/* ----------------------------- USB interface ----------------------------- */ -/* ------------------------------------------------------------------------- */ - -#if USB_CFG_IMPLEMENT_FN_WRITE -uchar usbFunctionWrite(uchar *data, uchar len) -{ - return 1; -} -#endif - -#if USB_CFG_IMPLEMENT_FN_READ -uchar usbFunctionRead(uchar *data, uchar len) -{ - return len; -} -#endif - -#if USB_CFG_IMPLEMENT_FN_WRITEOUT -void usbFunctionWriteOut(uchar *data, uchar len) -{ -} -#endif - -#if USE_DYNAMIC_DESCRIPTOR - -static PROGMEM char myDescriptorDevice[] = { /* USB device descriptor */ - 18, /* sizeof(usbDescriptorDevice): length of descriptor in bytes */ - USBDESCR_DEVICE, /* descriptor type */ - 0x10, 0x01, /* USB version supported */ - USB_CFG_DEVICE_CLASS, - USB_CFG_DEVICE_SUBCLASS, - 0, /* protocol */ - 8, /* max packet size */ - /* the following two casts affect the first byte of the constant only, but - * that's sufficient to avoid a warning with the default values. - */ - (char)USB_CFG_VENDOR_ID,/* 2 bytes */ - (char)USB_CFG_DEVICE_ID,/* 2 bytes */ - USB_CFG_DEVICE_VERSION, /* 2 bytes */ - USB_CFG_DESCR_PROPS_STRING_VENDOR != 0 ? 1 : 0, /* manufacturer string index */ - USB_CFG_DESCR_PROPS_STRING_PRODUCT != 0 ? 2 : 0, /* product string index */ - USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER != 0 ? 3 : 0, /* serial number string index */ - 1, /* number of configurations */ -}; - -static PROGMEM char myDescriptorConfiguration[] = { /* USB configuration descriptor */ - 9, /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */ - USBDESCR_CONFIG, /* descriptor type */ - 18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + (USB_CFG_DESCR_PROPS_HID & 0xff), 0, - /* total length of data returned (including inlined descriptors) */ - 1, /* number of interfaces in this configuration */ - 1, /* index of this configuration */ - 0, /* configuration name string index */ -#if USB_CFG_IS_SELF_POWERED - USBATTR_SELFPOWER, /* attributes */ -#else - (char)USBATTR_BUSPOWER, /* attributes */ -#endif - USB_CFG_MAX_BUS_POWER/2, /* max USB current in 2mA units */ -/* interface descriptor follows inline: */ - 9, /* sizeof(usbDescrInterface): length of descriptor in bytes */ - USBDESCR_INTERFACE, /* descriptor type */ - 0, /* index of this interface */ - 0, /* alternate setting for this interface */ - USB_CFG_HAVE_INTRIN_ENDPOINT, /* endpoints excl 0: number of endpoint descriptors to follow */ - USB_CFG_INTERFACE_CLASS, - USB_CFG_INTERFACE_SUBCLASS, - USB_CFG_INTERFACE_PROTOCOL, - 0, /* string index for interface */ -#if (USB_CFG_DESCR_PROPS_HID & 0xff) /* HID descriptor */ - 9, /* sizeof(usbDescrHID): length of descriptor in bytes */ - USBDESCR_HID, /* descriptor type: HID */ - 0x01, 0x01, /* BCD representation of HID version */ - 0x00, /* target country code */ - 0x01, /* number of HID Report (or other HID class) Descriptor infos to follow */ - 0x22, /* descriptor type: report */ - USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH, 0, /* total length of report descriptor */ -#endif -#if USB_CFG_HAVE_INTRIN_ENDPOINT /* endpoint descriptor for endpoint 1 */ - 7, /* sizeof(usbDescrEndpoint) */ - USBDESCR_ENDPOINT, /* descriptor type = endpoint */ - (char)0x81, /* IN endpoint number 1 */ - 0x03, /* attrib: Interrupt endpoint */ - 8, 0, /* maximum packet size */ - USB_CFG_INTR_POLL_INTERVAL, /* in ms */ -#endif -}; - -USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(usbRequest_t *rq) -{ -uchar *p = 0, len = 0; - - if(rq->wValue.bytes[1] == USBDESCR_DEVICE){ - p = (uchar *)myDescriptorDevice; - len = sizeof(myDescriptorDevice); - }else{ /* must be configuration descriptor */ - p = (uchar *)(myDescriptorConfiguration); - len = sizeof(myDescriptorConfiguration); - } - usbMsgPtr = p; - return len; -} -#endif - -USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) -{ -usbRequest_t *rq = (void *)data; - - if(rq->bRequest == 0) /* request using usbFunctionRead()/usbFunctionWrite() */ - return 0xff; - return 0; /* default for not implemented requests: return no data back to host */ -} - -/* ------------------------------------------------------------------------- */ - -int main(void) -{ -uchar i; - - usbInit(); - usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */ - i = 0; - while(--i){ /* fake USB disconnect for > 250 ms */ - _delay_ms(1); - } - usbDeviceConnect(); - sei(); - for(;;){ /* main event loop */ - usbPoll(); - } - return 0; -} - -/* ------------------------------------------------------------------------- */ diff --git a/tools/avrusb/tests/null.c b/tools/avrusb/tests/null.c deleted file mode 100644 index dc6848d..0000000 --- a/tools/avrusb/tests/null.c +++ /dev/null @@ -1,26 +0,0 @@ -/* Name: null.c - * Project: Testing driver features - * Author: Christian Starkjohann - * Creation Date: 2008-04-29 - * Tabsize: 4 - * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: null.c 692 2008-11-07 15:07:40Z cs $ - */ - -/* -This is a NULL main() function to find out the code size required by libusb's -startup code, interrupt vectors etc. -*/ -#include - - -/* ------------------------------------------------------------------------- */ - -int main(void) -{ - for(;;); - return 0; -} - -/* ------------------------------------------------------------------------- */ diff --git a/tools/avrusb/tests/sizes-reference/sizes-20080418-gcc3.4.6.txt b/tools/avrusb/tests/sizes-reference/sizes-20080418-gcc3.4.6.txt deleted file mode 100644 index 2257e89..0000000 --- a/tools/avrusb/tests/sizes-reference/sizes-20080418-gcc3.4.6.txt +++ /dev/null @@ -1,13 +0,0 @@ - Variation Flash RAM +F +RAM - Minimum_with_16_MHz 1154 45 +0 +0 - Minimum_with_12_MHz 1274 45 +120 +0 - Minimum_with_15_MHz 1260 45 +106 +0 - Minimum_with_16_5_MHz 1276 45 +122 +0 - With_usbFunctionWrite 1214 45 +60 +0 - With_usbFunctionRead 1200 45 +46 +0 - With_usbFunctionRead_and_Write 1246 45 +92 +0 - With_usbFunctionWriteOut 1178 45 +24 +0 - With_Interrupt_In_Endpoint_1 1284 58 +130 +13 - With_Interrupt_In_Endpoint_1_and_Halt 1372 58 +218 +13 - With_Interrupt_In_Endpoint_1_and_3 1386 69 +232 +24 - With_Dynamic_Descriptor 1186 45 +32 +0 diff --git a/tools/avrusb/tests/sizes-reference/sizes-20080418-gcc4.2.2.txt b/tools/avrusb/tests/sizes-reference/sizes-20080418-gcc4.2.2.txt deleted file mode 100644 index f776893..0000000 --- a/tools/avrusb/tests/sizes-reference/sizes-20080418-gcc4.2.2.txt +++ /dev/null @@ -1,13 +0,0 @@ - Variation Flash RAM +F +RAM - Minimum_with_16_MHz 1208 45 +0 +0 - Minimum_with_12_MHz 1328 45 +120 +0 - Minimum_with_15_MHz 1314 45 +106 +0 - Minimum_with_16_5_MHz 1330 45 +122 +0 - With_usbFunctionWrite 1268 45 +60 +0 - With_usbFunctionRead 1264 45 +56 +0 - With_usbFunctionRead_and_Write 1314 45 +106 +0 - With_usbFunctionWriteOut 1218 45 +10 +0 - With_Interrupt_In_Endpoint_1 1340 58 +132 +13 - With_Interrupt_In_Endpoint_1_and_Halt 1414 58 +206 +13 - With_Interrupt_In_Endpoint_1_and_3 1426 69 +218 +24 - With_Dynamic_Descriptor 1238 45 +30 +0 diff --git a/tools/avrusb/tests/sizes-reference/sizes-20080513-gcc3.4.6.txt b/tools/avrusb/tests/sizes-reference/sizes-20080513-gcc3.4.6.txt deleted file mode 100644 index d292bfb..0000000 --- a/tools/avrusb/tests/sizes-reference/sizes-20080513-gcc3.4.6.txt +++ /dev/null @@ -1,15 +0,0 @@ - Variation Flash RAM +F +RAM - Minimum_with_16_MHz 1154 45 +0 +0 - Minimum_with_12_MHz 1274 45 +120 +0 - Minimum_with_15_MHz 1260 45 +106 +0 - Minimum_with_16_5_MHz 1276 45 +122 +0 - Minimum_with_20_MHz 1136 45 -18 +0 - With_usbFunctionWrite 1214 45 +60 +0 - With_usbFunctionRead 1192 45 +38 +0 - With_usbFunctionRead_and_Write 1234 45 +80 +0 - With_usbFunctionWriteOut 1178 45 +24 +0 - With_Interrupt_In_Endpoint_1 1280 57 +126 +12 - With_Interrupt_In_Endpoint_1_and_Halt 1370 57 +216 +12 - With_Interrupt_In_Endpoint_1_and_3 1346 69 +192 +24 - With_Dynamic_Descriptor 1182 45 +28 +0 - With_Long_Transfers 1200 47 +46 +2 diff --git a/tools/avrusb/tests/sizes-reference/sizes-20080513-gcc4.3.0.txt b/tools/avrusb/tests/sizes-reference/sizes-20080513-gcc4.3.0.txt deleted file mode 100644 index e3218b4..0000000 --- a/tools/avrusb/tests/sizes-reference/sizes-20080513-gcc4.3.0.txt +++ /dev/null @@ -1,15 +0,0 @@ - Variation Flash RAM +F +RAM - Minimum_with_16_MHz 1192 45 +0 +0 - Minimum_with_12_MHz 1312 45 +120 +0 - Minimum_with_15_MHz 1298 45 +106 +0 - Minimum_with_16_5_MHz 1314 45 +122 +0 - Minimum_with_20_MHz 1174 45 -18 +0 - With_usbFunctionWrite 1246 45 +54 +0 - With_usbFunctionRead 1242 45 +50 +0 - With_usbFunctionRead_and_Write 1280 45 +88 +0 - With_usbFunctionWriteOut 1208 45 +16 +0 - With_Interrupt_In_Endpoint_1 1320 57 +128 +12 - With_Interrupt_In_Endpoint_1_and_Halt 1410 57 +218 +12 - With_Interrupt_In_Endpoint_1_and_3 1428 69 +236 +24 - With_Dynamic_Descriptor 1212 45 +20 +0 - With_Long_Transfers 1270 47 +78 +2 diff --git a/tools/avrusb/tests/sizes-reference/sizes-20081022-gcc3.4.6.txt b/tools/avrusb/tests/sizes-reference/sizes-20081022-gcc3.4.6.txt deleted file mode 100644 index 0dfafa7..0000000 --- a/tools/avrusb/tests/sizes-reference/sizes-20081022-gcc3.4.6.txt +++ /dev/null @@ -1,16 +0,0 @@ - Variation Flash RAM +F +RAM - Minimum_with_16_MHz 1152 45 +0 +0 - Minimum_with_12_MHz 1202 45 +50 +0 - Minimum_with_12_8_MHz 1522 45 +370 +0 - Minimum_with_15_MHz 1258 45 +106 +0 - Minimum_with_16_5_MHz 1274 45 +122 +0 - Minimum_with_20_MHz 1134 45 -18 +0 - With_usbFunctionWrite 1212 45 +60 +0 - With_usbFunctionRead 1190 45 +38 +0 - With_usbFunctionRead_and_Write 1232 45 +80 +0 - With_usbFunctionWriteOut 1176 45 +24 +0 - With_Interrupt_In_Endpoint_1 1278 57 +126 +12 - With_Interrupt_In_Endpoint_1_and_Halt 1368 57 +216 +12 - With_Interrupt_In_Endpoint_1_and_3 1344 69 +192 +24 - With_Dynamic_Descriptor 1180 45 +28 +0 - With_Long_Transfers 1198 47 +46 +2 diff --git a/tools/avrusb/tests/sizes-reference/sizes-20081022-gcc4.3.0.txt b/tools/avrusb/tests/sizes-reference/sizes-20081022-gcc4.3.0.txt deleted file mode 100644 index 42e2ba9..0000000 --- a/tools/avrusb/tests/sizes-reference/sizes-20081022-gcc4.3.0.txt +++ /dev/null @@ -1,16 +0,0 @@ - Variation Flash RAM +F +RAM - Minimum_with_16_MHz 1194 45 +0 +0 - Minimum_with_12_MHz 1244 45 +50 +0 - Minimum_with_12_8_MHz 1564 45 +370 +0 - Minimum_with_15_MHz 1300 45 +106 +0 - Minimum_with_16_5_MHz 1316 45 +122 +0 - Minimum_with_20_MHz 1176 45 -18 +0 - With_usbFunctionWrite 1248 45 +54 +0 - With_usbFunctionRead 1244 45 +50 +0 - With_usbFunctionRead_and_Write 1282 45 +88 +0 - With_usbFunctionWriteOut 1210 45 +16 +0 - With_Interrupt_In_Endpoint_1 1322 57 +128 +12 - With_Interrupt_In_Endpoint_1_and_Halt 1412 57 +218 +12 - With_Interrupt_In_Endpoint_1_and_3 1430 69 +236 +24 - With_Dynamic_Descriptor 1214 45 +20 +0 - With_Long_Transfers 1272 47 +78 +2 diff --git a/tools/avrusb/tests/sizes-reference/sizes-20081126-gcc3.4.6.txt b/tools/avrusb/tests/sizes-reference/sizes-20081126-gcc3.4.6.txt deleted file mode 100644 index 0dfafa7..0000000 --- a/tools/avrusb/tests/sizes-reference/sizes-20081126-gcc3.4.6.txt +++ /dev/null @@ -1,16 +0,0 @@ - Variation Flash RAM +F +RAM - Minimum_with_16_MHz 1152 45 +0 +0 - Minimum_with_12_MHz 1202 45 +50 +0 - Minimum_with_12_8_MHz 1522 45 +370 +0 - Minimum_with_15_MHz 1258 45 +106 +0 - Minimum_with_16_5_MHz 1274 45 +122 +0 - Minimum_with_20_MHz 1134 45 -18 +0 - With_usbFunctionWrite 1212 45 +60 +0 - With_usbFunctionRead 1190 45 +38 +0 - With_usbFunctionRead_and_Write 1232 45 +80 +0 - With_usbFunctionWriteOut 1176 45 +24 +0 - With_Interrupt_In_Endpoint_1 1278 57 +126 +12 - With_Interrupt_In_Endpoint_1_and_Halt 1368 57 +216 +12 - With_Interrupt_In_Endpoint_1_and_3 1344 69 +192 +24 - With_Dynamic_Descriptor 1180 45 +28 +0 - With_Long_Transfers 1198 47 +46 +2 diff --git a/tools/avrusb/tests/sizes-reference/sizes-20081126-gcc4.3.0.txt b/tools/avrusb/tests/sizes-reference/sizes-20081126-gcc4.3.0.txt deleted file mode 100644 index 42e2ba9..0000000 --- a/tools/avrusb/tests/sizes-reference/sizes-20081126-gcc4.3.0.txt +++ /dev/null @@ -1,16 +0,0 @@ - Variation Flash RAM +F +RAM - Minimum_with_16_MHz 1194 45 +0 +0 - Minimum_with_12_MHz 1244 45 +50 +0 - Minimum_with_12_8_MHz 1564 45 +370 +0 - Minimum_with_15_MHz 1300 45 +106 +0 - Minimum_with_16_5_MHz 1316 45 +122 +0 - Minimum_with_20_MHz 1176 45 -18 +0 - With_usbFunctionWrite 1248 45 +54 +0 - With_usbFunctionRead 1244 45 +50 +0 - With_usbFunctionRead_and_Write 1282 45 +88 +0 - With_usbFunctionWriteOut 1210 45 +16 +0 - With_Interrupt_In_Endpoint_1 1322 57 +128 +12 - With_Interrupt_In_Endpoint_1_and_Halt 1412 57 +218 +12 - With_Interrupt_In_Endpoint_1_and_3 1430 69 +236 +24 - With_Dynamic_Descriptor 1214 45 +20 +0 - With_Long_Transfers 1272 47 +78 +2 diff --git a/tools/avrusb/tests/sizes-reference/sizes-20090323-gcc3.4.6.txt b/tools/avrusb/tests/sizes-reference/sizes-20090323-gcc3.4.6.txt deleted file mode 100644 index 18e72a6..0000000 --- a/tools/avrusb/tests/sizes-reference/sizes-20090323-gcc3.4.6.txt +++ /dev/null @@ -1,17 +0,0 @@ - Variation Flash RAM +F +RAM - Minimum_with_16_MHz 1152 45 +0 +0 - Minimum_with_12_MHz 1202 45 +50 +0 - Minimum_with_12_8_MHz 1522 45 +370 +0 - Minimum_with_15_MHz 1258 45 +106 +0 - Minimum_with_16_5_MHz 1274 45 +122 +0 - Minimum_with_18_MHz+CRC 2268 45 +1116 +0 - Minimum_with_20_MHz 1134 45 -18 +0 - With_usbFunctionWrite 1212 45 +60 +0 - With_usbFunctionRead 1190 45 +38 +0 - With_usbFunctionRead_and_Write 1232 45 +80 +0 - With_usbFunctionWriteOut 1176 45 +24 +0 - With_Interrupt_In_Endpoint_1 1278 57 +126 +12 - With_Interrupt_In_Endpoint_1_and_Halt 1368 57 +216 +12 - With_Interrupt_In_Endpoint_1_and_3 1344 69 +192 +24 - With_Dynamic_Descriptor 1180 45 +28 +0 - With_Long_Transfers 1198 47 +46 +2 diff --git a/tools/avrusb/tests/sizes-reference/sizes-20090323-gcc4.3.2.txt b/tools/avrusb/tests/sizes-reference/sizes-20090323-gcc4.3.2.txt deleted file mode 100644 index 9b4f4ee..0000000 --- a/tools/avrusb/tests/sizes-reference/sizes-20090323-gcc4.3.2.txt +++ /dev/null @@ -1,17 +0,0 @@ - Variation Flash RAM +F +RAM - Minimum_with_16_MHz 1224 45 +0 +0 - Minimum_with_12_MHz 1274 45 +50 +0 - Minimum_with_12_8_MHz 1594 45 +370 +0 - Minimum_with_15_MHz 1330 45 +106 +0 - Minimum_with_16_5_MHz 1346 45 +122 +0 - Minimum_with_18_MHz+CRC 2298 45 +1074 +0 - Minimum_with_20_MHz 1206 45 -18 +0 - With_usbFunctionWrite 1284 45 +60 +0 - With_usbFunctionRead 1280 45 +56 +0 - With_usbFunctionRead_and_Write 1318 45 +94 +0 - With_usbFunctionWriteOut 1246 45 +22 +0 - With_Interrupt_In_Endpoint_1 1358 57 +134 +12 - With_Interrupt_In_Endpoint_1_and_Halt 1448 57 +224 +12 - With_Interrupt_In_Endpoint_1_and_3 1466 69 +242 +24 - With_Dynamic_Descriptor 1250 45 +26 +0 - With_Long_Transfers 1302 47 +78 +2 diff --git a/tools/avrusb/tests/usbconfig.h b/tools/avrusb/tests/usbconfig.h deleted file mode 100644 index 83e8c78..0000000 --- a/tools/avrusb/tests/usbconfig.h +++ /dev/null @@ -1,317 +0,0 @@ -/* Name: usbconfig.h - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2005-04-01 - * Tabsize: 4 - * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: usbconfig.h 719 2009-03-16 18:51:56Z cs $ - */ - -#ifndef __usbconfig_h_included__ -#define __usbconfig_h_included__ - -/* -General Description: -This file is an example configuration (with inline documentation) for the USB -driver. It configures AVR-USB for USB D+ connected to Port D bit 2 (which is -also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may -wire the lines to any other port, as long as D+ is also wired to INT0 (or any -other hardware interrupt, as long as it is the highest level interrupt, see -section at the end of this file). -*/ - -/* ---------------------------- Hardware Config ---------------------------- */ - -#define USB_CFG_IOPORTNAME D -/* This is the port where the USB bus is connected. When you configure it to - * "B", the registers PORTB, PINB and DDRB will be used. - */ -#define USB_CFG_DMINUS_BIT 4 -/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected. - * This may be any bit in the port. - */ -#define USB_CFG_DPLUS_BIT 2 -/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected. - * This may be any bit in the port. Please note that D+ must also be connected - * to interrupt pin INT0! [You can also use other interrupts, see section - * "Optional MCU Description" below, or you can connect D- to the interrupt, as - * it is required if you use the USB_COUNT_SOF feature. If you use D- for the - * interrupt, the USB interrupt will also be triggered at Start-Of-Frame - * markers every millisecond.] - */ -#define USB_CFG_CLOCK_KHZ (F_CPU/1000) -/* Clock rate of the AVR in MHz. Legal values are 12000, 15000, 16000 or 16500. - * The 16.5 MHz version of the code requires no crystal, it tolerates +/- 1% - * deviation from the nominal frequency. All other rates require a precision - * of 2000 ppm and thus a crystal! - * Default if not specified: 12 MHz - */ -#define USB_CFG_CHECK_CRC (USB_CFG_CLOCK_KHZ == 18000) -/* Define this to 1 if you want that the driver checks data integrity of data - * packets (CRC checks). CRC checks cost quite a bit of code size and are - * currently only available for 18 MHz crystal clock. You must choose - * USB_CFG_CLOCK_KHZ = 18000 if you enable this option. - */ - - -/* ----------------------- Optional Hardware Config ------------------------ */ - -/* #define USB_CFG_PULLUP_IOPORTNAME D */ -/* If you connect the 1.5k pullup resistor from D- to a port pin instead of - * V+, you can connect and disconnect the device from firmware by calling - * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h). - * This constant defines the port on which the pullup resistor is connected. - */ -/* #define USB_CFG_PULLUP_BIT 4 */ -/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined - * above) where the 1.5k pullup resistor is connected. See description - * above for details. - */ - -/* --------------------------- Functional Range ---------------------------- */ - -#ifndef USB_CFG_HAVE_INTRIN_ENDPOINT3 -#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0 -#endif -/* Define this to 1 if you want to compile a version with three endpoints: The - * default control endpoint 0, an interrupt-in endpoint 3 (or the number - * configured below) and a catch-all default interrupt-in endpoint as above. - * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature. - */ -#ifndef USB_CFG_HAVE_INTRIN_ENDPOINT -#define USB_CFG_HAVE_INTRIN_ENDPOINT USB_CFG_HAVE_INTRIN_ENDPOINT3 -#endif -/* Define this to 1 if you want to compile a version with two endpoints: The - * default control endpoint 0 and an interrupt-in endpoint (any other endpoint - * number). - */ -#define USB_CFG_EP3_NUMBER 3 -/* If the so-called endpoint 3 is used, it can now be configured to any other - * endpoint number (except 0) with this macro. Default if undefined is 3. - */ -/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */ -/* The above macro defines the startup condition for data toggling on the - * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1. - * Since the token is toggled BEFORE sending any data, the first packet is - * sent with the oposite value of this configuration! - */ -//#define USB_CFG_IMPLEMENT_HALT 0 -/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature - * for endpoint 1 (interrupt endpoint). Although you may not need this feature, - * it is required by the standard. We have made it a config option because it - * bloats the code considerably. - */ -#define USB_CFG_INTR_POLL_INTERVAL 10 -/* If you compile a version with endpoint 1 (interrupt-in), this is the poll - * interval. The value is in milliseconds and must not be less than 10 ms for - * low speed devices. - */ -#define USB_CFG_IS_SELF_POWERED 0 -/* Define this to 1 if the device has its own power supply. Set it to 0 if the - * device is powered from the USB bus. - */ -#define USB_CFG_MAX_BUS_POWER 40 -/* Set this variable to the maximum USB bus power consumption of your device. - * The value is in milliamperes. [It will be divided by two since USB - * communicates power requirements in units of 2 mA.] - */ -//#define USB_CFG_IMPLEMENT_FN_WRITE 0 -/* Set this to 1 if you want usbFunctionWrite() to be called for control-out - * transfers. Set it to 0 if you don't need it and want to save a couple of - * bytes. - */ -//#define USB_CFG_IMPLEMENT_FN_READ 0 -/* Set this to 1 if you need to send control replies which are generated - * "on the fly" when usbFunctionRead() is called. If you only want to send - * data from a static buffer, set it to 0 and return the data from - * usbFunctionSetup(). This saves a couple of bytes. - */ -//#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0 -/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints. - * You must implement the function usbFunctionWriteOut() which receives all - * interrupt/bulk data sent to any endpoint other than 0. The endpoint number - * can be found in 'usbRxToken'. - */ -#define USB_CFG_HAVE_FLOWCONTROL 0 -/* Define this to 1 if you want flowcontrol over USB data. See the definition - * of the macros usbDisableAllRequests() and usbEnableAllRequests() in - * usbdrv.h. - */ -//#define USB_CFG_LONG_TRANSFERS 0 -/* Define this to 1 if you want to send/receive blocks of more than 254 bytes - * in a single control-in or control-out transfer. Note that the capability - * for long transfers increases the driver size. - */ -/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */ -/* This macro is a hook if you want to do unconventional things. If it is - * defined, it's inserted at the beginning of received message processing. - * If you eat the received message and don't want default processing to - * proceed, do a return after doing your things. One possible application - * (besides debugging) is to flash a status LED on each packet. - */ -/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */ -/* This macro is a hook if you need to know when an USB RESET occurs. It has - * one parameter which distinguishes between the start of RESET state and its - * end. - */ -/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */ -/* This macro (if defined) is executed when a USB SET_ADDRESS request was - * received. - */ -//#define USB_COUNT_SOF 0 -/* define this macro to 1 if you need the global variable "usbSofCount" which - * counts SOF packets. This feature requires that the hardware interrupt is - * connected to D- instead of D+. - */ -//#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0 -/* define this macro to 1 if you want the function usbMeasureFrameLength() - * compiled in. This function can be used to calibrate the AVR's RC oscillator. - */ - -/* -------------------------- Device Description --------------------------- */ - -#define USB_CFG_VENDOR_ID 0xc0, 0x16 -/* USB vendor ID for the device, low byte first. If you have registered your - * own Vendor ID, define it here. Otherwise you use one of obdev's free shared - * VID/PID pairs. Be sure to read USBID-License.txt for rules! - */ -#define USB_CFG_DEVICE_ID 0x08, 0x3e /* 1000 dec, "free for lab use" */ -/* This is the ID of the product, low byte first. It is interpreted in the - * scope of the vendor ID. If you have registered your own VID with usb.org - * or if you have licensed a PID from somebody else, define it here. Otherwise - * you use obdev's free shared VID/PID pair. Be sure to read the rules in - * USBID-License.txt! - */ -#define USB_CFG_DEVICE_VERSION 0x00, 0x01 -/* Version number of the device: Minor number first, then major number. - */ -#define USB_CFG_VENDOR_NAME 'o', 'b', 'd', 'e', 'v', '.', 'a', 't' -#define USB_CFG_VENDOR_NAME_LEN 8 -/* These two values define the vendor name returned by the USB device. The name - * must be given as a list of characters under single quotes. The characters - * are interpreted as Unicode (UTF-16) entities. - * If you don't want a vendor name string, undefine these macros. - * ALWAYS define a vendor name containing your Internet domain name if you use - * obdev's free shared VID/PID pair. See the file USBID-License.txt for - * details. - */ -#define USB_CFG_DEVICE_NAME 'T', 'e', 's', 't' -#define USB_CFG_DEVICE_NAME_LEN 4 -/* Same as above for the device name. If you don't want a device name, undefine - * the macros. See the file USBID-License.txt before you assign a name if you - * use a shared VID/PID. - */ -/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */ -/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */ -/* Same as above for the serial number. If you don't want a serial number, - * undefine the macros. - * It may be useful to provide the serial number through other means than at - * compile time. See the section about descriptor properties below for how - * to fine tune control over USB descriptors such as the string descriptor - * for the serial number. - */ -#define USB_CFG_DEVICE_CLASS 0xff /* set to 0 if deferred to interface */ -#define USB_CFG_DEVICE_SUBCLASS 0 -/* See USB specification if you want to conform to an existing device class. - * Class 0xff is "vendor specific". - */ -#define USB_CFG_INTERFACE_CLASS 0 /* define class here if not at device level */ -#define USB_CFG_INTERFACE_SUBCLASS 0 -#define USB_CFG_INTERFACE_PROTOCOL 0 -/* See USB specification if you want to conform to an existing device class or - * protocol. The following classes must be set at interface level: - * HID class is 3, no subclass and protocol required (but may be useful!) - * CDC class is 2, use subclass 2 and protocol 1 for ACM - */ -/* #define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 42 */ -/* Define this to the length of the HID report descriptor, if you implement - * an HID device. Otherwise don't define it or define it to 0. - * If you use this define, you must add a PROGMEM character array named - * "usbHidReportDescriptor" to your code which contains the report descriptor. - * Don't forget to keep the array and this define in sync! - */ - -/* #define USB_PUBLIC static */ -/* Use the define above if you #include usbdrv.c instead of linking against it. - * This technique saves a couple of bytes in flash memory. - */ - -/* ------------------- Fine Control over USB Descriptors ------------------- */ -/* If you don't want to use the driver's default USB descriptors, you can - * provide our own. These can be provided as (1) fixed length static data in - * flash memory, (2) fixed length static data in RAM or (3) dynamically at - * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more - * information about this function. - * Descriptor handling is configured through the descriptor's properties. If - * no properties are defined or if they are 0, the default descriptor is used. - * Possible properties are: - * + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched - * at runtime via usbFunctionDescriptor(). - * + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found - * in static memory is in RAM, not in flash memory. - * + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash), - * the driver must know the descriptor's length. The descriptor itself is - * found at the address of a well known identifier (see below). - * List of static descriptor names (must be declared PROGMEM if in flash): - * char usbDescriptorDevice[]; - * char usbDescriptorConfiguration[]; - * char usbDescriptorHidReport[]; - * char usbDescriptorString0[]; - * int usbDescriptorStringVendor[]; - * int usbDescriptorStringDevice[]; - * int usbDescriptorStringSerialNumber[]; - * Other descriptors can't be provided statically, they must be provided - * dynamically at runtime. - * - * Descriptor properties are or-ed or added together, e.g.: - * #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18)) - * - * The following descriptors are defined: - * USB_CFG_DESCR_PROPS_DEVICE - * USB_CFG_DESCR_PROPS_CONFIGURATION - * USB_CFG_DESCR_PROPS_STRINGS - * USB_CFG_DESCR_PROPS_STRING_0 - * USB_CFG_DESCR_PROPS_STRING_VENDOR - * USB_CFG_DESCR_PROPS_STRING_PRODUCT - * USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER - * USB_CFG_DESCR_PROPS_HID - * USB_CFG_DESCR_PROPS_HID_REPORT - * USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver) - * - */ - -#if USE_DYNAMIC_DESCRIPTOR -#define USB_CFG_DESCR_PROPS_DEVICE USB_PROP_IS_DYNAMIC -#define USB_CFG_DESCR_PROPS_CONFIGURATION USB_PROP_IS_DYNAMIC -#else -#define USB_CFG_DESCR_PROPS_DEVICE 0 -#define USB_CFG_DESCR_PROPS_CONFIGURATION 0 -#endif -#define USB_CFG_DESCR_PROPS_STRINGS 0 -#define USB_CFG_DESCR_PROPS_STRING_0 0 -#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0 -#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0 -#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0 -#define USB_CFG_DESCR_PROPS_HID 0 -#define USB_CFG_DESCR_PROPS_HID_REPORT 0 -#define USB_CFG_DESCR_PROPS_UNKNOWN 0 - -/* ----------------------- Optional MCU Description ------------------------ */ - -/* The following configurations have working defaults in usbdrv.h. You - * usually don't need to set them explicitly. Only if you want to run - * the driver on a device which is not yet supported or with a compiler - * which is not fully supported (such as IAR C) or if you use a differnt - * interrupt than INT0, you may have to define some of these. - */ -/* #define USB_INTR_CFG MCUCR */ -/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */ -/* #define USB_INTR_CFG_CLR 0 */ -/* #define USB_INTR_ENABLE GIMSK */ -/* #define USB_INTR_ENABLE_BIT INT0 */ -/* #define USB_INTR_PENDING GIFR */ -/* #define USB_INTR_PENDING_BIT INTF0 */ -/* #define USB_INTR_VECTOR SIG_INTERRUPT0 */ - -#endif /* __usbconfig_h_included__ */ diff --git a/tools/avrusb/usbdrv/Changelog.txt b/tools/avrusb/usbdrv/Changelog.txt deleted file mode 100644 index c07bca9..0000000 --- a/tools/avrusb/usbdrv/Changelog.txt +++ /dev/null @@ -1,270 +0,0 @@ -This file documents changes in the firmware-only USB driver for atmel's AVR -microcontrollers. New entries are always appended to the end of the file. -Scroll down to the bottom to see the most recent changes. - -2005-04-01: - - Implemented endpoint 1 as interrupt-in endpoint. - - Moved all configuration options to usbconfig.h which is not part of the - driver. - - Changed interface for usbVendorSetup(). - - Fixed compatibility with ATMega8 device. - - Various minor optimizations. - -2005-04-11: - - Changed interface to application: Use usbFunctionSetup(), usbFunctionRead() - and usbFunctionWrite() now. Added configuration options to choose which - of these functions to compile in. - - Assembler module delivers receive data non-inverted now. - - Made register and bit names compatible with more AVR devices. - -2005-05-03: - - Allow address of usbRxBuf on any memory page as long as the buffer does - not cross 256 byte page boundaries. - - Better device compatibility: works with Mega88 now. - - Code optimization in debugging module. - - Documentation updates. - -2006-01-02: - - Added (free) default Vendor- and Product-IDs bought from voti.nl. - - Added USBID-License.txt file which defines the rules for using the free - shared VID/PID pair. - - Added Readme.txt to the usbdrv directory which clarifies administrative - issues. - -2006-01-25: - - Added "configured state" to become more standards compliant. - - Added "HALT" state for interrupt endpoint. - - Driver passes the "USB Command Verifier" test from usb.org now. - - Made "serial number" a configuration option. - - Minor optimizations, we now recommend compiler option "-Os" for best - results. - - Added a version number to usbdrv.h - -2006-02-03: - - New configuration variable USB_BUFFER_SECTION for the memory section where - the USB rx buffer will go. This defaults to ".bss" if not defined. Since - this buffer MUST NOT cross 256 byte pages (not even touch a page at the - end), the user may want to pass a linker option similar to - "-Wl,--section-start=.mybuffer=0x800060". - - Provide structure for usbRequest_t. - - New defines for USB constants. - - Prepared for HID implementations. - - Increased data size limit for interrupt transfers to 8 bytes. - - New macro usbInterruptIsReady() to query interrupt buffer state. - -2006-02-18: - - Ensure that the data token which is sent as an ack to an OUT transfer is - always zero sized. This fixes a bug where the host reports an error after - sending an out transfer to the device, although all data arrived at the - device. - - Updated docs in usbdrv.h to reflect changed API in usbFunctionWrite(). - -* Release 2006-02-20 - - - Give a compiler warning when compiling with debugging turned on. - - Added Oleg Semyonov's changes for IAR-cc compatibility. - - Added new (optional) functions usbDeviceConnect() and usbDeviceDisconnect() - (also thanks to Oleg!). - - Rearranged tests in usbPoll() to save a couple of instructions in the most - likely case that no actions are pending. - - We need a delay between the SET ADDRESS request until the new address - becomes active. This delay was handled in usbPoll() until now. Since the - spec says that the delay must not exceed 2ms, previous versions required - aggressive polling during the enumeration phase. We have now moved the - handling of the delay into the interrupt routine. - - We must not reply with NAK to a SETUP transaction. We can only achieve this - by making sure that the rx buffer is empty when SETUP tokens are expected. - We therefore don't pass zero sized data packets from the status phase of - a transfer to usbPoll(). This change MAY cause troubles if you rely on - receiving a less than 8 bytes long packet in usbFunctionWrite() to - identify the end of a transfer. usbFunctionWrite() will NEVER be called - with a zero length. - -* Release 2006-03-14 - - - Improved IAR C support: tiny memory model, more devices - - Added template usbconfig.h file under the name usbconfig-prototype.h - -* Release 2006-03-26 - - - Added provision for one more interrupt-in endpoint (endpoint 3). - - Added provision for one interrupt-out endpoint (endpoint 1). - - Added flowcontrol macros for USB. - - Added provision for custom configuration descriptor. - - Allow ANY two port bits for D+ and D-. - - Merged (optional) receive endpoint number into global usbRxToken variable. - - Use USB_CFG_IOPORTNAME instead of USB_CFG_IOPORT. We now construct the - variable name from the single port letter instead of computing the address - of related ports from the output-port address. - -* Release 2006-06-26 - - - Updated documentation in usbdrv.h and usbconfig-prototype.h to reflect the - new features. - - Removed "#warning" directives because IAR does not understand them. Use - unused static variables instead to generate a warning. - - Do not include when compiling with IAR. - - Introduced USB_CFG_DESCR_PROPS_* in usbconfig.h to configure how each - USB descriptor should be handled. It is now possible to provide descriptor - data in Flash, RAM or dynamically at runtime. - - STALL is now a status in usbTxLen* instead of a message. We can now conform - to the spec and leave the stall status pending until it is cleared. - - Made usbTxPacketCnt1 and usbTxPacketCnt3 public. This allows the - application code to reset data toggling on interrupt pipes. - -* Release 2006-07-18 - - - Added an #if !defined __ASSEMBLER__ to the warning in usbdrv.h. This fixes - an assembler error. - - usbDeviceDisconnect() takes pull-up resistor to high impedance now. - -* Release 2007-02-01 - - - Merged in some code size improvements from usbtiny (thanks to Dick - Streefland for these optimizations!) - - Special alignment requirement for usbRxBuf not required any more. Thanks - again to Dick Streefland for this hint! - - Reverted to "#warning" instead of unused static variables -- new versions - of IAR CC should handle this directive. - - Changed Open Source license to GNU GPL v2 in order to make linking against - other free libraries easier. We no longer require publication of the - circuit diagrams, but we STRONGLY encourage it. If you improve the driver - itself, PLEASE grant us a royalty free license to your changes for our - commercial license. - -* Release 2007-03-29 - - - New configuration option "USB_PUBLIC" in usbconfig.h. - - Set USB version number to 1.10 instead of 1.01. - - Code used USB_CFG_DESCR_PROPS_STRING_DEVICE and - USB_CFG_DESCR_PROPS_STRING_PRODUCT inconsistently. Changed all occurrences - to USB_CFG_DESCR_PROPS_STRING_PRODUCT. - - New assembler module for 16.5 MHz RC oscillator clock with PLL in receiver - code. - - New assembler module for 16 MHz crystal. - - usbdrvasm.S contains common code only, clock-specific parts have been moved - to usbdrvasm12.S, usbdrvasm16.S and usbdrvasm165.S respectively. - -* Release 2007-06-25 - - - 16 MHz module: Do SE0 check in stuffed bits as well. - -* Release 2007-07-07 - - - Define hi8(x) for IAR compiler to limit result to 8 bits. This is necessary - for negative values. - - Added 15 MHz module contributed by V. Bosch. - - Interrupt vector name can now be configured. This is useful if somebody - wants to use a different hardware interrupt than INT0. - -* Release 2007-08-07 - - - Moved handleIn3 routine in usbdrvasm16.S so that relative jump range is - not exceeded. - - More config options: USB_RX_USER_HOOK(), USB_INITIAL_DATATOKEN, - USB_COUNT_SOF - - USB_INTR_PENDING can now be a memory address, not just I/O - -* Release 2007-09-19 - - - Split out common parts of assembler modules into separate include file - - Made endpoint numbers configurable so that given interface definitions - can be matched. See USB_CFG_EP3_NUMBER in usbconfig-prototype.h. - - Store endpoint number for interrupt/bulk-out so that usbFunctionWriteOut() - can handle any number of endpoints. - - Define usbDeviceConnect() and usbDeviceDisconnect() even if no - USB_CFG_PULLUP_IOPORTNAME is defined. Directly set D+ and D- to 0 in this - case. - -* Release 2007-12-01 - - - Optimize usbDeviceConnect() and usbDeviceDisconnect() for less code size - when USB_CFG_PULLUP_IOPORTNAME is not defined. - -* Release 2007-12-13 - - - Renamed all include-only assembler modules from *.S to *.inc so that - people don't add them to their project sources. - - Distribute leap bits in tx loop more evenly for 16 MHz module. - - Use "macro" and "endm" instead of ".macro" and ".endm" for IAR - - Avoid compiler warnings for constant expr range by casting some values in - USB descriptors. - -* Release 2008-01-21 - - - Fixed bug in 15 and 16 MHz module where the new address set with - SET_ADDRESS was already accepted at the next NAK or ACK we send, not at - the next data packet we send. This caused problems when the host polled - too fast. Thanks to Alexander Neumann for his help and patience debugging - this issue! - -* Release 2008-02-05 - - - Fixed bug in 16.5 MHz module where a register was used in the interrupt - handler before it was pushed. This bug was introduced with version - 2007-09-19 when common parts were moved to a separate file. - - Optimized CRC routine (thanks to Reimar Doeffinger). - -* Release 2008-02-16 - - - Removed outdated IAR compatibility stuff (code sections). - - Added hook macros for USB_RESET_HOOK() and USB_SET_ADDRESS_HOOK(). - - Added optional routine usbMeasureFrameLength() for calibration of the - internal RC oscillator. - -* Release 2008-02-28 - - - USB_INITIAL_DATATOKEN defaults to USBPID_DATA1 now, which means that we - start with sending USBPID_DATA0. - - Changed defaults in usbconfig-prototype.h - - Added free USB VID/PID pair for MIDI class devices - - Restructured AVR-USB as separate package, not part of PowerSwitch any more. - -* Release 2008-04-18 - - - Restructured usbdrv.c so that it is easier to read and understand. - - Better code optimization with gcc 4. - - If a second interrupt in endpoint is enabled, also add it to config - descriptor. - - Added config option for long transfers (above 254 bytes), see - USB_CFG_LONG_TRANSFERS in usbconfig.h. - - Added 20 MHz module contributed by Jeroen Benschop. - -* Release 2008-05-13 - - - Fixed bug in libs-host/hiddata.c function usbhidGetReport(): length - was not incremented, pointer to length was incremented instead. - - Added code to command line tool(s) which claims an interface. This code - is disabled by default, but may be necessary on newer Linux kernels. - - Added usbconfig.h option "USB_CFG_CHECK_DATA_TOGGLING". - - New header "usbportability.h" prepares ports to other development - environments. - - Long transfers (above 254 bytes) did not work when usbFunctionRead() was - used to supply the data. Fixed this bug. [Thanks to Alexander Neumann!] - - In hiddata.c (example code for sending/receiving data over HID), use - USB_RECIP_DEVICE instead of USB_RECIP_INTERFACE for control transfers so - that we need not claim the interface. - - in usbPoll() loop 20 times polling for RESET state instead of 10 times. - This accounts for the higher clock rates we now support. - - Added a module for 12.8 MHz RC oscillator with PLL in receiver loop. - - Added hook to SOF code so that oscillator can be tuned to USB frame clock. - - Added timeout to waitForJ loop. Helps preventing unexpected hangs. - - Added example code for oscillator tuning to libs-device (thanks to - Henrik Haftmann for the idea to this routine). - - Implemented option USB_CFG_SUPPRESS_INTR_CODE. - -* Release 2008-10-22 - - - Fixed libs-device/osctune.h: OSCCAL is memory address on ATMega88 and - similar, not offset of 0x20 needs to be added. - - Allow distribution under GPLv3 for those who have to link against other - code distributed under GPLv3. - -* Release 2008-11-26 - - - Removed libusb-win32 dependency for hid-data example in Makefile.windows. - It was never required and confused many people. - - Added extern uchar usbRxToken to usbdrv.h. - - Integrated a module with CRC checks at 18 MHz by Lukas Schrittwieser. - -* Release 2009-03-23 diff --git a/tools/avrusb/usbdrv/CommercialLicense.txt b/tools/avrusb/usbdrv/CommercialLicense.txt deleted file mode 100644 index 6d8bf39..0000000 --- a/tools/avrusb/usbdrv/CommercialLicense.txt +++ /dev/null @@ -1,156 +0,0 @@ -AVR-USB Driver Software License Agreement -Version 2008-10-07 - -THIS LICENSE AGREEMENT GRANTS YOU CERTAIN RIGHTS IN A SOFTWARE. YOU CAN -ENTER INTO THIS AGREEMENT AND ACQUIRE THE RIGHTS OUTLINED BELOW BY PAYING -THE AMOUNT ACCORDING TO SECTION 4 ("PAYMENT") TO OBJECTIVE DEVELOPMENT. - - -1 DEFINITIONS - -1.1 "OBJECTIVE DEVELOPMENT" shall mean OBJECTIVE DEVELOPMENT Software GmbH, -Grosse Schiffgasse 1A/7, 1020 Wien, AUSTRIA. - -1.2 "You" shall mean the Licensee. - -1.3 "AVR-USB" shall mean all files included in the package distributed under -the name "avrusb" by OBJECTIVE DEVELOPMENT (http://www.obdev.at/avrusb/) -unless otherwise noted. This includes the firmware-only USB device -implementation for Atmel AVR microcontrollers, some simple device examples -and host side software examples and libraries. - - -2 LICENSE GRANTS - -2.1 Source Code. OBJECTIVE DEVELOPMENT shall furnish you with the source -code of AVR-USB. - -2.2 Distribution and Use. OBJECTIVE DEVELOPMENT grants you the -non-exclusive right to use, copy and distribute AVR-USB with your hardware -product(s), restricted by the limitations in section 3 below. - -2.3 Modifications. OBJECTIVE DEVELOPMENT grants you the right to modify -the source code and your copy of AVR-USB according to your needs. - -2.4 USB IDs. OBJECTIVE DEVELOPMENT grants you the exclusive rights to use -USB Product ID(s) sent to you in e-mail after receiving your payment in -conjunction with USB Vendor ID 5824. OBJECTIVE DEVELOPMENT has acquired an -exclusive license for this pair of USB identifiers from Wouter van Ooijen -(www.voti.nl), who has licensed the VID from the USB Implementers Forum, -Inc. (www.usb.org). - - -3 LICENSE RESTRICTIONS - -3.1 Number of Units. Only one of the following three definitions is -applicable. Which one is determined by the amount you pay to OBJECTIVE -DEVELOPMENT, see section 4 ("Payment") below. - -Hobby License: You may use AVR-USB according to section 2 above in no more -than 5 hardware units. These units must not be sold for profit. - -Entry Level License: You may use AVR-USB according to section 2 above in no -more than 150 hardware units. - -Professional License: You may use AVR-USB according to section 2 above in -any number of hardware units, except for large scale production ("unlimited -fair use"). Quantities below 10,000 units are not considered large scale -production. If your reach quantities which are obviously large scale -production, you must pay a license fee of 0.10 EUR per unit for all units -above 10,000. - -3.2 Rental. You may not rent, lease, or lend AVR-USB or otherwise encumber -any copy of AVR-USB, or any of the rights granted herein. - -3.3 Transfer. You may not transfer your rights under this Agreement to -another party without OBJECTIVE DEVELOPMENT's prior written consent. If -such consent is obtained, you may permanently transfer this License to -another party. The recipient of such transfer must agree to all terms and -conditions of this Agreement. - -3.4 Reservation of Rights. OBJECTIVE DEVELOPMENT retains all rights not -expressly granted. - -3.5 Non-Exclusive Rights. Your license rights under this Agreement are -non-exclusive. - -3.6 Third Party Rights. This Agreement cannot grant you rights controlled -by third parties. In particular, you are not allowed to use the USB logo or -other trademarks owned by the USB Implementers Forum, Inc. without their -consent. Since such consent depends on USB certification, it should be -noted that AVR-USB will not pass certification because it does not -implement checksum verification and the microcontroller ports do not meet -the electrical specifications. - - -4 PAYMENT - -The payment amount depends on the variation of this agreement (according to -section 3.1) into which you want to enter. Concrete prices are listed on -OBJECTIVE DEVELOPMENT's web site, usually at -http://www.obdev.at/avrusb/license.html. You agree to pay the amount listed -there to OBJECTIVE DEVELOPMENT or OBJECTIVE DEVELOPMENT's payment processor -or reseller. - - -5 COPYRIGHT AND OWNERSHIP - -AVR-USB is protected by copyright laws and international copyright -treaties, as well as other intellectual property laws and treaties. AVR-USB -is licensed, not sold. - - -6 TERM AND TERMINATION - -6.1 Term. This Agreement shall continue indefinitely. However, OBJECTIVE -DEVELOPMENT may terminate this Agreement and revoke the granted license and -USB-IDs if you fail to comply with any of its terms and conditions. - -6.2 Survival of Terms. All provisions regarding secrecy, confidentiality -and limitation of liability shall survive termination of this agreement. - - -7 DISCLAIMER OF WARRANTY AND LIABILITY - -LIMITED WARRANTY. AVR-USB IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -KIND. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, OBJECTIVE -DEVELOPMENT AND ITS SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES, EITHER -EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND -NON-INFRINGEMENT, WITH REGARD TO AVR-USB, AND THE PROVISION OF OR FAILURE -TO PROVIDE SUPPORT SERVICES. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL -RIGHTS. YOU MAY HAVE OTHERS, WHICH VARY FROM STATE/JURISDICTION TO -STATE/JURISDICTION. - -LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, -IN NO EVENT SHALL OBJECTIVE DEVELOPMENT OR ITS SUPPLIERS BE LIABLE FOR ANY -SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER -(INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, -BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY -LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE AVR-USB OR THE -PROVISION OF OR FAILURE TO PROVIDE SUPPORT SERVICES, EVEN IF OBJECTIVE -DEVELOPMENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY -CASE, OBJECTIVE DEVELOPMENT'S ENTIRE LIABILITY UNDER ANY PROVISION OF THIS -AGREEMENT SHALL BE LIMITED TO THE AMOUNT ACTUALLY PAID BY YOU FOR AVR-USB. - - -8 MISCELLANEOUS TERMS - -8.1 Marketing. OBJECTIVE DEVELOPMENT has the right to mention for marketing -purposes that you entered into this agreement. - -8.2 Entire Agreement. This document represents the entire agreement between -OBJECTIVE DEVELOPMENT and you. It may only be modified in writing signed by -an authorized representative of both, OBJECTIVE DEVELOPMENT and you. - -8.3 Severability. In case a provision of these terms and conditions should -be or become partly or entirely invalid, ineffective, or not executable, -the validity of all other provisions shall not be affected. - -8.4 Applicable Law. This agreement is governed by the laws of the Republic -of Austria. - -8.5 Responsible Courts. The responsible courts in Vienna/Austria will have -exclusive jurisdiction regarding all disputes in connection with this -agreement. - diff --git a/tools/avrusb/usbdrv/License.txt b/tools/avrusb/usbdrv/License.txt deleted file mode 100644 index e9b2752..0000000 --- a/tools/avrusb/usbdrv/License.txt +++ /dev/null @@ -1,361 +0,0 @@ -OBJECTIVE DEVELOPMENT GmbH's AVR-USB driver software is distributed under the -terms and conditions of the GNU GPL version 2 or the GNU GPL version 3. It is -your choice whether you apply the terms of version 2 or version 3. The full -text of GPLv2 is included below. In addition to the requirements in the GPL, -we STRONGLY ENCOURAGE you to do the following: - -(1) Publish your entire project on a web site and drop us a note with the URL. -Use the form at http://www.obdev.at/avrusb/feedback.html for your submission. - -(2) Adhere to minimum publication standards. Please include AT LEAST: - - a circuit diagram in PDF, PNG or GIF format - - full source code for the host software - - a Readme.txt file in ASCII format which describes the purpose of the - project and what can be found in which directories and which files - - a reference to http://www.obdev.at/avrusb/ - -(3) If you improve the driver firmware itself, please give us a free license -to your modifications for our commercial license offerings. - - - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/tools/avrusb/usbdrv/Readme.txt b/tools/avrusb/usbdrv/Readme.txt deleted file mode 100644 index a7aad3e..0000000 --- a/tools/avrusb/usbdrv/Readme.txt +++ /dev/null @@ -1,158 +0,0 @@ -This is the Readme file to Objective Development's firmware-only USB driver -for Atmel AVR microcontrollers. For more information please visit -http://www.obdev.at/avrusb/ - -This directory contains the USB firmware only. Copy it as-is to your own -project and add all .c and .S files to your project (these files are marked -with an asterisk in the list below). Then copy usbconfig-prototype.h as -usbconfig.h to your project and edit it according to your configuration. - - -TECHNICAL DOCUMENTATION -======================= -The technical documentation (API) for the firmware driver is contained in the -file "usbdrv.h". Please read all of it carefully! Configuration options are -documented in "usbconfig-prototype.h". - -The driver consists of the following files: - Readme.txt ............. The file you are currently reading. - Changelog.txt .......... Release notes for all versions of the driver. - usbdrv.h ............... Driver interface definitions and technical docs. -* usbdrv.c ............... High level language part of the driver. Link this - module to your code! -* usbdrvasm.S ............ Assembler part of the driver. This module is mostly - a stub and includes one of the usbdrvasm*.S files - depending on processor clock. Link this module to - your code! - usbdrvasm*.inc ......... Assembler routines for particular clock frequencies. - Included by usbdrvasm.S, don't link it directly! - asmcommon.inc .......... Common assembler routines. Included by - usbdrvasm*.inc, don't link it directly! - usbconfig-prototype.h .. Prototype for your own usbdrv.h file. -* oddebug.c .............. Debug functions. Only used when DEBUG_LEVEL is - defined to a value greater than 0. Link this module - to your code! - oddebug.h .............. Interface definitions of the debug module. - usbportability.h ....... Header with compiler-dependent stuff. - usbdrvasm.asm .......... Compatibility stub for IAR-C-compiler. Use this - module instead of usbdrvasm.S when you assembler - with IAR's tools. - License.txt ............ Open Source license for this driver. - CommercialLicense.txt .. Optional commercial license for this driver. - USBID-License.txt ...... Terms and conditions for using particular USB ID - values for particular purposes. - -(*) ... These files should be linked to your project. - - -CPU CORE CLOCK FREQUENCY -======================== -We supply assembler modules for clock frequencies of 12 MHz, 12.8 MHz, 15 MHz, -16 MHz, 16.5 MHz 18 MHz and 20 MHz. Other clock rates are not supported. The -actual clock rate must be configured in usbdrv.h unless you use the default -12 MHz. - -12 MHz Clock -This is the traditional clock rate of AVR-USB because it's the lowest clock -rate where the timing constraints of the USB spec can be met. - -15 MHz Clock -Similar to 12 MHz, but some NOPs inserted. On the other hand, the higher clock -rate allows for some loops which make the resulting code size somewhat smaller -than the 12 MHz version. - -16 MHz Clock -This clock rate has been added for users of the Arduino board and other -ready-made boards which come with a fixed 16 MHz crystal. It's also an option -if you need the slightly higher clock rate for performance reasons. Since -16 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code -is somewhat tricky and has to insert a leap cycle every third byte. - -12.8 MHz and 16.5 MHz Clock -The assembler modules for these clock rates differ from the other modules -because they have been built for an RC oscillator with only 1% precision. The -receiver code inserts leap cycles to compensate for clock deviations. 1% is -also the precision which can be achieved by calibrating the internal RC -oscillator of the AVR. Please note that only AVRs with internal 64 MHz PLL -oscillator can reach 16.5 MHz with the RC oscillator. This includes the very -popular ATTiny25, ATTiny45, ATTiny85 series as well as the ATTiny26. Almost -all AVRs can reach 12.8 MHz, although this is outside the specified range. - -See the EasyLogger example at http://www.obdev.at/avrusb/easylogger.html for -code which calibrates the RC oscillator based on the USB frame clock. - -18 MHz Clock -This module is closer to the USB specification because it performs an on the -fly CRC check for incoming packets. Packets with invalid checksum are -discarded as required by the spec. If you also implement checks for data -PID toggling on application level (see option USB_CFG_CHECK_DATA_TOGGLING -in usbconfig.h for more info), this ensures data integrity. Due to the CRC -tables and alignment requirements, this code is bigger than modules for other -clock rates. To activate this module, you must define USB_CFG_CHECK_CRC to 1 -and USB_CFG_CLOCK_KHZ to 18000 in usbconfig.h. - -20 MHz Clock -This module is for people who won't do it with less than the maximum. Since -20 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code -uses similar tricks as the 16 MHz module to insert leap cycles. - - -USB IDENTIFIERS -=============== -Every USB device needs a vendor- and a product-identifier (VID and PID). VIDs -are obtained from usb.org for a price of 1,500 USD. Once you have a VID, you -can assign PIDs at will. - -Since an entry level cost of 1,500 USD is too high for most small companies -and hobbyists, we provide some VID/PID pairs for free. See the file -USBID-License.txt for details. - -Objective Development also has some license offerings which include product -IDs. See http://www.obdev.at/avrusb/ for details. - - -DEVELOPMENT SYSTEM -================== -This driver has been developed and optimized for the GNU compiler version 3 -(gcc 3). It does work well with gcc 4, but with bigger code size. We recommend -that you use the GNU compiler suite because it is freely available. AVR-USB -has also been ported to the IAR compiler and assembler. It has been tested -with IAR 4.10B/W32 and 4.12A/W32 on an ATmega8 with the "small" and "tiny" -memory model. Not every release is tested with IAR CC and the driver may -therefore fail to compile with IAR. Please note that gcc is more efficient for -usbdrv.c because this module has been deliberately optimized for gcc. - - -USING AVR-USB FOR FREE -====================== -The AVR firmware driver is published under the GNU General Public License -Version 2 (GPL2) and the GNU General Public License Version 3 (GPL3). It is -your choice whether you apply the terms of version 2 or version 3. - -If you decide for the free GPL2 or GPL3, we STRONGLY ENCOURAGE you to do the -following things IN ADDITION to the obligations from the GPL: - -(1) Publish your entire project on a web site and drop us a note with the URL. -Use the form at http://www.obdev.at/avrusb/feedback.html for your submission. -If you don't have a web site, you can publish the project in obdev's -documentation wiki at -http://www.obdev.at/goto.php?t=avrusb-wiki&p=hosted-projects. - -(2) Adhere to minimum publication standards. Please include AT LEAST: - - a circuit diagram in PDF, PNG or GIF format - - full source code for the host software - - a Readme.txt file in ASCII format which describes the purpose of the - project and what can be found in which directories and which files - - a reference to http://www.obdev.at/avrusb/ - -(3) If you improve the driver firmware itself, please give us a free license -to your modifications for our commercial license offerings. - - -COMMERCIAL LICENSES FOR AVR-USB -=============================== -If you don't want to publish your source code under the terms of the GPL, -you can simply pay money for AVR-USB. As an additional benefit you get -USB PIDs for free, licensed exclusively to you. See the file -"CommercialLicense.txt" for details. - diff --git a/tools/avrusb/usbdrv/USBID-License.txt b/tools/avrusb/usbdrv/USBID-License.txt deleted file mode 100644 index 984c9ee..0000000 --- a/tools/avrusb/usbdrv/USBID-License.txt +++ /dev/null @@ -1,146 +0,0 @@ -Royalty-Free Non-Exclusive License USB Product-ID -================================================= - -Version 2008-04-07 - -OBJECTIVE DEVELOPMENT Software GmbH hereby grants you the non-exclusive -right to use three USB.org vendor-ID (VID) / product-ID (PID) pairs with -products based on Objective Development's firmware-only USB driver for -Atmel AVR microcontrollers: - - * VID = 5824 (=0x16c0) / PID = 1500 (=0x5dc) for devices implementing no - USB device class (vendor-class devices with USB class = 0xff). Devices - using this pair will be referred to as "VENDOR CLASS" devices. - - * VID = 5824 (=0x16c0) / PID = 1503 (=0x5df) for HID class devices - (excluding mice and keyboards). Devices using this pair will be referred - to as "HID CLASS" devices. - - * VID = 5824 (=0x16c0) / PID = 1505 (=0x5e1) for CDC class modem devices - Devices using this pair will be referred to as "CDC-ACM CLASS" devices. - - * VID = 5824 (=0x16c0) / PID = 1508 (=0x5e4) for MIDI class devices - Devices using this pair will be referred to as "MIDI CLASS" devices. - -Since the granted right is non-exclusive, the same VID/PID pairs may be -used by many companies and individuals for different products. To avoid -conflicts, your device and host driver software MUST adhere to the rules -outlined below. - -OBJECTIVE DEVELOPMENT Software GmbH has licensed these VID/PID pairs from -Wouter van Ooijen (see www.voti.nl), who has licensed the VID from the USB -Implementers Forum, Inc. (see www.usb.org). The VID is registered for the -company name "Van Ooijen Technische Informatica". - - -RULES AND RESTRICTIONS -====================== - -(1) The USB device MUST provide a textual representation of the -manufacturer and product identification. The manufacturer identification -MUST be available at least in USB language 0x0409 (English/US). - -(2) The textual manufacturer identification MUST contain either an Internet -domain name (e.g. "mycompany.com") registered and owned by you, or an -e-mail address under your control (e.g. "myname@gmx.net"). You can embed -the domain name or e-mail address in any string you like, e.g. "Objective -Development http://www.obdev.at/avrusb/". - -(3) You are responsible for retaining ownership of the domain or e-mail -address for as long as any of your products are in use. - -(4) You may choose any string for the textual product identification, as -long as this string is unique within the scope of your textual manufacturer -identification. - -(5) Matching of device-specific drivers MUST be based on the textual -manufacturer and product identification in addition to the usual VID/PID -matching. This means that operating system features which are based on -VID/PID matching only (e.g. Windows kernel level drivers, automatic actions -when the device is plugged in etc) MUST NOT be used. The driver matching -MUST be a comparison of the entire strings, NOT a sub-string match. For -CDC-ACM CLASS and MIDI CLASS devices, a generic class driver should be used -and the matching is based on the USB device class. - -(6) The extent to which VID/PID matching is allowed for non device-specific -drivers or features depends on the operating system and particular VID/PID -pair used: - - * Mac OS X, Linux, FreeBSD and other Unixes: No VID/PID matching is - required and hence no VID/PID-only matching is allowed at all. - - * Windows: The operating system performs VID/PID matching for the kernel - level driver. You are REQUIRED to use libusb-win32 (see - http://libusb-win32.sourceforge.net/) as the kernel level driver for - VENDOR CLASS devices. HID CLASS devices all use the generic HID class - driver shipped with Windows, except mice and keyboards. You therefore - MUST NOT use any of the shared VID/PID pairs for mice or keyboards. - CDC-ACM CLASS devices require a ".inf" file which matches on the VID/PID - pair. This ".inf" file MUST load the "usbser" driver to configure the - device as modem (COM-port). - -(7) OBJECTIVE DEVELOPMENT Software GmbH disclaims all liability for any -problems which are caused by the shared use of these VID/PID pairs. You -have been warned that the sharing of VID/PID pairs may cause problems. If -you want to avoid them, get your own VID/PID pair for exclusive use. - - -HOW TO IMPLEMENT THESE RULES -============================ - -The following rules are for VENDOR CLASS and HID CLASS devices. CDC-ACM -CLASS and MIDI CLASS devices use the operating system's class driver and -don't need a custom driver. - -The host driver MUST iterate over all devices with the given VID/PID -numbers in their device descriptors and query the string representation for -the manufacturer name in USB language 0x0409 (English/US). It MUST compare -the ENTIRE string with your textual manufacturer identification chosen in -(2) above. A substring search for your domain or e-mail address is NOT -acceptable. The driver MUST NOT touch the device (other than querying the -descriptors) unless the strings match. - -For all USB devices with matching VID/PID and textual manufacturer -identification, the host driver must query the textual product -identification and string-compare it with the name of the product it can -control. It may only initialize the device if the product matches exactly. - -Objective Development provides examples for these matching rules with the -"PowerSwitch" project (using libusb) and with the "Automator" project -(using Windows calls on Windows and libusb on Unix). - - -Technical Notes: -================ - -Sharing the same VID/PID pair among devices is possible as long as ALL -drivers which match the VID/PID also perform matching on the textual -identification strings. This is easy on all operating systems except -Windows, since Windows establishes a static connection between the VID/PID -pair and a kernel level driver. All devices with the same VID/PID pair must -therefore use THE SAME kernel level driver. - -We therefore demand that you use libusb-win32 for VENDOR CLASS devices. -This is a generic kernel level driver which allows all types of USB access -for user space applications. This is only a partial solution of the -problem, though, because different device drivers may come with different -versions of libusb-win32 and they may not work with the libusb version of -the respective other driver. You are therefore encouraged to test your -driver against a broad range of libusb-win32 versions. Do not use new -features in new versions, or check for their existence before you use them. -When a new libusb-win32 becomes available, make sure that your driver is -compatible with it. - -For HID CLASS devices it is necessary that all those devices bind to the -same kernel driver: Microsoft's generic USB HID driver. This is true for -all HID devices except those with a specialized driver. Currently, the only -HIDs with specialized drivers are mice and keyboards. You therefore MUST -NOT use a shared VID/PID with mouse and keyboard devices. - -Sharing the same VID/PID among different products is unusual and probably -violates the USB specification. If you do it, you do it at your own risk. - -To avoid possible incompatibilities, we highly recommend that you get your -own VID/PID pair if you intend to sell your product. Objective -Development's commercial licenses for AVR-USB include a PID for -unrestricted exclusive use. diff --git a/tools/avrusb/usbdrv/asmcommon.inc b/tools/avrusb/usbdrv/asmcommon.inc deleted file mode 100644 index 457de3b..0000000 --- a/tools/avrusb/usbdrv/asmcommon.inc +++ /dev/null @@ -1,188 +0,0 @@ -/* Name: asmcommon.inc - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2007-11-05 - * Tabsize: 4 - * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * Revision: $Id$ - */ - -/* Do not link this file! Link usbdrvasm.S instead, which includes the - * appropriate implementation! - */ - -/* -General Description: -This file contains assembler code which is shared among the USB driver -implementations for different CPU cocks. Since the code must be inserted -in the middle of the module, it's split out into this file and #included. - -Jump destinations called from outside: - sofError: Called when no start sequence was found. - se0: Called when a package has been successfully received. - overflow: Called when receive buffer overflows. - doReturn: Called after sending data. - -Outside jump destinations used by this module: - waitForJ: Called to receive an already arriving packet. - sendAckAndReti: - sendNakAndReti: - sendCntAndReti: - usbSendAndReti: - -The following macros must be defined before this file is included: - .macro POP_STANDARD - .endm - .macro POP_RETI - .endm -*/ - -#define token x1 - -overflow: - ldi x2, 1< 0 - -#warning "Never compile production devices with debugging enabled" - -static void uartPutc(char c) -{ - while(!(ODDBG_USR & (1 << ODDBG_UDRE))); /* wait for data register empty */ - ODDBG_UDR = c; -} - -static uchar hexAscii(uchar h) -{ - h &= 0xf; - if(h >= 10) - h += 'a' - (uchar)10 - '0'; - h += '0'; - return h; -} - -static void printHex(uchar c) -{ - uartPutc(hexAscii(c >> 4)); - uartPutc(hexAscii(c)); -} - -void odDebug(uchar prefix, uchar *data, uchar len) -{ - printHex(prefix); - uartPutc(':'); - while(len--){ - uartPutc(' '); - printHex(*data++); - } - uartPutc('\r'); - uartPutc('\n'); -} - -#endif diff --git a/tools/avrusb/usbdrv/oddebug.h b/tools/avrusb/usbdrv/oddebug.h deleted file mode 100644 index d61309d..0000000 --- a/tools/avrusb/usbdrv/oddebug.h +++ /dev/null @@ -1,123 +0,0 @@ -/* Name: oddebug.h - * Project: AVR library - * Author: Christian Starkjohann - * Creation Date: 2005-01-16 - * Tabsize: 4 - * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: oddebug.h 692 2008-11-07 15:07:40Z cs $ - */ - -#ifndef __oddebug_h_included__ -#define __oddebug_h_included__ - -/* -General Description: -This module implements a function for debug logs on the serial line of the -AVR microcontroller. Debugging can be configured with the define -'DEBUG_LEVEL'. If this macro is not defined or defined to 0, all debugging -calls are no-ops. If it is 1, DBG1 logs will appear, but not DBG2. If it is -2, DBG1 and DBG2 logs will be printed. - -A debug log consists of a label ('prefix') to indicate which debug log created -the output and a memory block to dump in hex ('data' and 'len'). -*/ - - -#ifndef F_CPU -# define F_CPU 12000000 /* 12 MHz */ -#endif - -/* make sure we have the UART defines: */ -#include "usbportability.h" - -#ifndef uchar -# define uchar unsigned char -#endif - -#if DEBUG_LEVEL > 0 && !(defined TXEN || defined TXEN0) /* no UART in device */ -# warning "Debugging disabled because device has no UART" -# undef DEBUG_LEVEL -#endif - -#ifndef DEBUG_LEVEL -# define DEBUG_LEVEL 0 -#endif - -/* ------------------------------------------------------------------------- */ - -#if DEBUG_LEVEL > 0 -# define DBG1(prefix, data, len) odDebug(prefix, data, len) -#else -# define DBG1(prefix, data, len) -#endif - -#if DEBUG_LEVEL > 1 -# define DBG2(prefix, data, len) odDebug(prefix, data, len) -#else -# define DBG2(prefix, data, len) -#endif - -/* ------------------------------------------------------------------------- */ - -#if DEBUG_LEVEL > 0 -extern void odDebug(uchar prefix, uchar *data, uchar len); - -/* Try to find our control registers; ATMEL likes to rename these */ - -#if defined UBRR -# define ODDBG_UBRR UBRR -#elif defined UBRRL -# define ODDBG_UBRR UBRRL -#elif defined UBRR0 -# define ODDBG_UBRR UBRR0 -#elif defined UBRR0L -# define ODDBG_UBRR UBRR0L -#endif - -#if defined UCR -# define ODDBG_UCR UCR -#elif defined UCSRB -# define ODDBG_UCR UCSRB -#elif defined UCSR0B -# define ODDBG_UCR UCSR0B -#endif - -#if defined TXEN -# define ODDBG_TXEN TXEN -#else -# define ODDBG_TXEN TXEN0 -#endif - -#if defined USR -# define ODDBG_USR USR -#elif defined UCSRA -# define ODDBG_USR UCSRA -#elif defined UCSR0A -# define ODDBG_USR UCSR0A -#endif - -#if defined UDRE -# define ODDBG_UDRE UDRE -#else -# define ODDBG_UDRE UDRE0 -#endif - -#if defined UDR -# define ODDBG_UDR UDR -#elif defined UDR0 -# define ODDBG_UDR UDR0 -#endif - -static inline void odDebugInit(void) -{ - ODDBG_UCR |= (1<len & 0x10){ /* packet buffer was empty */ - txStatus->buffer[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* toggle token */ - }else{ - txStatus->len = USBPID_NAK; /* avoid sending outdated (overwritten) interrupt data */ - } - p = txStatus->buffer + 1; - i = len; - do{ /* if len == 0, we still copy 1 byte, but that's no problem */ - *p++ = *data++; - }while(--i > 0); /* loop control at the end is 2 bytes shorter than at beginning */ - usbCrc16Append(&txStatus->buffer[1], len); - txStatus->len = len + 4; /* len must be given including sync byte */ - DBG2(0x21 + (((int)txStatus >> 3) & 3), txStatus->buffer, len + 3); -} - -USB_PUBLIC void usbSetInterrupt(uchar *data, uchar len) -{ - usbGenericSetInterrupt(data, len, &usbTxStatus1); -} -#endif - -#if USB_CFG_HAVE_INTRIN_ENDPOINT3 -USB_PUBLIC void usbSetInterrupt3(uchar *data, uchar len) -{ - usbGenericSetInterrupt(data, len, &usbTxStatus3); -} -#endif -#endif /* USB_CFG_SUPPRESS_INTR_CODE */ - -/* ------------------ utilities for code following below ------------------- */ - -/* Use defines for the switch statement so that we can choose between an - * if()else if() and a switch/case based implementation. switch() is more - * efficient for a LARGE set of sequential choices, if() is better in all other - * cases. - */ -#if USB_CFG_USE_SWITCH_STATEMENT -# define SWITCH_START(cmd) switch(cmd){{ -# define SWITCH_CASE(value) }break; case (value):{ -# define SWITCH_CASE2(v1,v2) }break; case (v1): case(v2):{ -# define SWITCH_CASE3(v1,v2,v3) }break; case (v1): case(v2): case(v3):{ -# define SWITCH_DEFAULT }break; default:{ -# define SWITCH_END }} -#else -# define SWITCH_START(cmd) {uchar _cmd = cmd; if(0){ -# define SWITCH_CASE(value) }else if(_cmd == (value)){ -# define SWITCH_CASE2(v1,v2) }else if(_cmd == (v1) || _cmd == (v2)){ -# define SWITCH_CASE3(v1,v2,v3) }else if(_cmd == (v1) || _cmd == (v2) || (_cmd == v3)){ -# define SWITCH_DEFAULT }else{ -# define SWITCH_END }} -#endif - -#ifndef USB_RX_USER_HOOK -#define USB_RX_USER_HOOK(data, len) -#endif -#ifndef USB_SET_ADDRESS_HOOK -#define USB_SET_ADDRESS_HOOK() -#endif - -/* ------------------------------------------------------------------------- */ - -/* We use if() instead of #if in the macro below because #if can't be used - * in macros and the compiler optimizes constant conditions anyway. - * This may cause problems with undefined symbols if compiled without - * optimizing! - */ -#define GET_DESCRIPTOR(cfgProp, staticName) \ - if(cfgProp){ \ - if((cfgProp) & USB_PROP_IS_RAM) \ - flags = 0; \ - if((cfgProp) & USB_PROP_IS_DYNAMIC){ \ - len = usbFunctionDescriptor(rq); \ - }else{ \ - len = USB_PROP_LENGTH(cfgProp); \ - usbMsgPtr = (uchar *)(staticName); \ - } \ - } - -/* usbDriverDescriptor() is similar to usbFunctionDescriptor(), but used - * internally for all types of descriptors. - */ -static inline usbMsgLen_t usbDriverDescriptor(usbRequest_t *rq) -{ -usbMsgLen_t len = 0; -uchar flags = USB_FLG_MSGPTR_IS_ROM; - - SWITCH_START(rq->wValue.bytes[1]) - SWITCH_CASE(USBDESCR_DEVICE) /* 1 */ - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_DEVICE, usbDescriptorDevice) - SWITCH_CASE(USBDESCR_CONFIG) /* 2 */ - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_CONFIGURATION, usbDescriptorConfiguration) - SWITCH_CASE(USBDESCR_STRING) /* 3 */ -#if USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC - if(USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_RAM) - flags = 0; - len = usbFunctionDescriptor(rq); -#else /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */ - SWITCH_START(rq->wValue.bytes[0]) - SWITCH_CASE(0) - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_0, usbDescriptorString0) - SWITCH_CASE(1) - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_VENDOR, usbDescriptorStringVendor) - SWITCH_CASE(2) - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_PRODUCT, usbDescriptorStringDevice) - SWITCH_CASE(3) - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER, usbDescriptorStringSerialNumber) - SWITCH_DEFAULT - if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){ - len = usbFunctionDescriptor(rq); - } - SWITCH_END -#endif /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */ -#if USB_CFG_DESCR_PROPS_HID_REPORT /* only support HID descriptors if enabled */ - SWITCH_CASE(USBDESCR_HID) /* 0x21 */ - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID, usbDescriptorConfiguration + 18) - SWITCH_CASE(USBDESCR_HID_REPORT)/* 0x22 */ - GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID_REPORT, usbDescriptorHidReport) -#endif - SWITCH_DEFAULT - if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){ - len = usbFunctionDescriptor(rq); - } - SWITCH_END - usbMsgFlags = flags; - return len; -} - -/* ------------------------------------------------------------------------- */ - -/* usbDriverSetup() is similar to usbFunctionSetup(), but it's used for - * standard requests instead of class and custom requests. - */ -static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq) -{ -uchar len = 0, *dataPtr = usbTxBuf + 9; /* there are 2 bytes free space at the end of the buffer */ -uchar value = rq->wValue.bytes[0]; -#if USB_CFG_IMPLEMENT_HALT -uchar index = rq->wIndex.bytes[0]; -#endif - - dataPtr[0] = 0; /* default reply common to USBRQ_GET_STATUS and USBRQ_GET_INTERFACE */ - SWITCH_START(rq->bRequest) - SWITCH_CASE(USBRQ_GET_STATUS) /* 0 */ - uchar recipient = rq->bmRequestType & USBRQ_RCPT_MASK; /* assign arith ops to variables to enforce byte size */ - if(USB_CFG_IS_SELF_POWERED && recipient == USBRQ_RCPT_DEVICE) - dataPtr[0] = USB_CFG_IS_SELF_POWERED; -#if USB_CFG_IMPLEMENT_HALT - if(recipient == USBRQ_RCPT_ENDPOINT && index == 0x81) /* request status for endpoint 1 */ - dataPtr[0] = usbTxLen1 == USBPID_STALL; -#endif - dataPtr[1] = 0; - len = 2; -#if USB_CFG_IMPLEMENT_HALT - SWITCH_CASE2(USBRQ_CLEAR_FEATURE, USBRQ_SET_FEATURE) /* 1, 3 */ - if(value == 0 && index == 0x81){ /* feature 0 == HALT for endpoint == 1 */ - usbTxLen1 = rq->bRequest == USBRQ_CLEAR_FEATURE ? USBPID_NAK : USBPID_STALL; - usbResetDataToggling(); - } -#endif - SWITCH_CASE(USBRQ_SET_ADDRESS) /* 5 */ - usbNewDeviceAddr = value; - USB_SET_ADDRESS_HOOK(); - SWITCH_CASE(USBRQ_GET_DESCRIPTOR) /* 6 */ - len = usbDriverDescriptor(rq); - goto skipMsgPtrAssignment; - SWITCH_CASE(USBRQ_GET_CONFIGURATION) /* 8 */ - dataPtr = &usbConfiguration; /* send current configuration value */ - len = 1; - SWITCH_CASE(USBRQ_SET_CONFIGURATION) /* 9 */ - usbConfiguration = value; - usbResetStall(); - SWITCH_CASE(USBRQ_GET_INTERFACE) /* 10 */ - len = 1; -#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE - SWITCH_CASE(USBRQ_SET_INTERFACE) /* 11 */ - usbResetDataToggling(); - usbResetStall(); -#endif - SWITCH_DEFAULT /* 7=SET_DESCRIPTOR, 12=SYNC_FRAME */ - /* Should we add an optional hook here? */ - SWITCH_END - usbMsgPtr = dataPtr; -skipMsgPtrAssignment: - return len; -} - -/* ------------------------------------------------------------------------- */ - -/* usbProcessRx() is called for every message received by the interrupt - * routine. It distinguishes between SETUP and DATA packets and processes - * them accordingly. - */ -static inline void usbProcessRx(uchar *data, uchar len) -{ -usbRequest_t *rq = (void *)data; - -/* usbRxToken can be: - * 0x2d 00101101 (USBPID_SETUP for setup data) - * 0xe1 11100001 (USBPID_OUT: data phase of setup transfer) - * 0...0x0f for OUT on endpoint X - */ - DBG2(0x10 + (usbRxToken & 0xf), data, len + 2); /* SETUP=1d, SETUP-DATA=11, OUTx=1x */ - USB_RX_USER_HOOK(data, len) -#if USB_CFG_IMPLEMENT_FN_WRITEOUT - if(usbRxToken < 0x10){ /* OUT to endpoint != 0: endpoint number in usbRxToken */ - usbFunctionWriteOut(data, len); - return; - } -#endif - if(usbRxToken == (uchar)USBPID_SETUP){ - if(len != 8) /* Setup size must be always 8 bytes. Ignore otherwise. */ - return; - usbMsgLen_t replyLen; - usbTxBuf[0] = USBPID_DATA0; /* initialize data toggling */ - usbTxLen = USBPID_NAK; /* abort pending transmit */ - usbMsgFlags = 0; - uchar type = rq->bmRequestType & USBRQ_TYPE_MASK; - if(type != USBRQ_TYPE_STANDARD){ /* standard requests are handled by driver */ - replyLen = usbFunctionSetup(data); - }else{ - replyLen = usbDriverSetup(rq); - } -#if USB_CFG_IMPLEMENT_FN_READ || USB_CFG_IMPLEMENT_FN_WRITE - if(replyLen == USB_NO_MSG){ /* use user-supplied read/write function */ - /* do some conditioning on replyLen, but on IN transfers only */ - if((rq->bmRequestType & USBRQ_DIR_MASK) != USBRQ_DIR_HOST_TO_DEVICE){ - if(sizeof(replyLen) < sizeof(rq->wLength.word)){ /* help compiler with optimizing */ - replyLen = rq->wLength.bytes[0]; - }else{ - replyLen = rq->wLength.word; - } - } - usbMsgFlags = USB_FLG_USE_USER_RW; - }else /* The 'else' prevents that we limit a replyLen of USB_NO_MSG to the maximum transfer len. */ -#endif - if(sizeof(replyLen) < sizeof(rq->wLength.word)){ /* help compiler with optimizing */ - if(!rq->wLength.bytes[1] && replyLen > rq->wLength.bytes[0]) /* limit length to max */ - replyLen = rq->wLength.bytes[0]; - }else{ - if(replyLen > rq->wLength.word) /* limit length to max */ - replyLen = rq->wLength.word; - } - usbMsgLen = replyLen; - }else{ /* usbRxToken must be USBPID_OUT, which means data phase of setup (control-out) */ -#if USB_CFG_IMPLEMENT_FN_WRITE - if(usbMsgFlags & USB_FLG_USE_USER_RW){ - uchar rval = usbFunctionWrite(data, len); - if(rval == 0xff){ /* an error occurred */ - usbTxLen = USBPID_STALL; - }else if(rval != 0){ /* This was the final package */ - usbMsgLen = 0; /* answer with a zero-sized data packet */ - } - } -#endif - } -} - -/* ------------------------------------------------------------------------- */ - -/* This function is similar to usbFunctionRead(), but it's also called for - * data handled automatically by the driver (e.g. descriptor reads). - */ -static uchar usbDeviceRead(uchar *data, uchar len) -{ - if(len > 0){ /* don't bother app with 0 sized reads */ -#if USB_CFG_IMPLEMENT_FN_READ - if(usbMsgFlags & USB_FLG_USE_USER_RW){ - len = usbFunctionRead(data, len); - }else -#endif - { - uchar i = len, *r = usbMsgPtr; - if(usbMsgFlags & USB_FLG_MSGPTR_IS_ROM){ /* ROM data */ - do{ - uchar c = USB_READ_FLASH(r); /* assign to char size variable to enforce byte ops */ - *data++ = c; - r++; - }while(--i); - }else{ /* RAM data */ - do{ - *data++ = *r++; - }while(--i); - } - usbMsgPtr = r; - } - } - return len; -} - -/* ------------------------------------------------------------------------- */ - -/* usbBuildTxBlock() is called when we have data to transmit and the - * interrupt routine's transmit buffer is empty. - */ -static inline void usbBuildTxBlock(void) -{ -usbMsgLen_t wantLen; -uchar len; - - wantLen = usbMsgLen; - if(wantLen > 8) - wantLen = 8; - usbMsgLen -= wantLen; - usbTxBuf[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* DATA toggling */ - len = usbDeviceRead(usbTxBuf + 1, wantLen); - if(len <= 8){ /* valid data packet */ - usbCrc16Append(&usbTxBuf[1], len); - len += 4; /* length including sync byte */ - if(len < 12) /* a partial package identifies end of message */ - usbMsgLen = USB_NO_MSG; - }else{ - len = USBPID_STALL; /* stall the endpoint */ - usbMsgLen = USB_NO_MSG; - } - usbTxLen = len; - DBG2(0x20, usbTxBuf, len-1); -} - -/* ------------------------------------------------------------------------- */ - -static inline void usbHandleResetHook(uchar notResetState) -{ -#ifdef USB_RESET_HOOK -static uchar wasReset; -uchar isReset = !notResetState; - - if(wasReset != isReset){ - USB_RESET_HOOK(isReset); - wasReset = isReset; - } -#endif -} - -/* ------------------------------------------------------------------------- */ - -USB_PUBLIC void usbPoll(void) -{ -schar len; -uchar i; - - len = usbRxLen - 3; - if(len >= 0){ -/* We could check CRC16 here -- but ACK has already been sent anyway. If you - * need data integrity checks with this driver, check the CRC in your app - * code and report errors back to the host. Since the ACK was already sent, - * retries must be handled on application level. - * unsigned crc = usbCrc16(buffer + 1, usbRxLen - 3); - */ - usbProcessRx(usbRxBuf + USB_BUFSIZE + 1 - usbInputBufOffset, len); -#if USB_CFG_HAVE_FLOWCONTROL - if(usbRxLen > 0) /* only mark as available if not inactivated */ - usbRxLen = 0; -#else - usbRxLen = 0; /* mark rx buffer as available */ -#endif - } - if(usbTxLen & 0x10){ /* transmit system idle */ - if(usbMsgLen != USB_NO_MSG){ /* transmit data pending? */ - usbBuildTxBlock(); - } - } - for(i = 20; i > 0; i--){ - uchar usbLineStatus = USBIN & USBMASK; - if(usbLineStatus != 0) /* SE0 has ended */ - goto isNotReset; - } - /* RESET condition, called multiple times during reset */ - usbNewDeviceAddr = 0; - usbDeviceAddr = 0; - usbResetStall(); - DBG1(0xff, 0, 0); -isNotReset: - usbHandleResetHook(i); -} - -/* ------------------------------------------------------------------------- */ - -USB_PUBLIC void usbInit(void) -{ -#if USB_INTR_CFG_SET != 0 - USB_INTR_CFG |= USB_INTR_CFG_SET; -#endif -#if USB_INTR_CFG_CLR != 0 - USB_INTR_CFG &= ~(USB_INTR_CFG_CLR); -#endif - USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT); - usbResetDataToggling(); -#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE - usbTxLen1 = USBPID_NAK; -#if USB_CFG_HAVE_INTRIN_ENDPOINT3 - usbTxLen3 = USBPID_NAK; -#endif -#endif -} - -/* ------------------------------------------------------------------------- */ diff --git a/tools/avrusb/usbdrv/usbdrv.h b/tools/avrusb/usbdrv/usbdrv.h deleted file mode 100644 index c5cefe9..0000000 --- a/tools/avrusb/usbdrv/usbdrv.h +++ /dev/null @@ -1,733 +0,0 @@ -/* Name: usbdrv.h - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2004-12-29 - * Tabsize: 4 - * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: usbdrv.h 738 2009-03-23 11:13:24Z cs $ - */ - -#ifndef __usbdrv_h_included__ -#define __usbdrv_h_included__ -#include "usbconfig.h" -#include "usbportability.h" - -/* -Hardware Prerequisites: -======================= -USB lines D+ and D- MUST be wired to the same I/O port. We recommend that D+ -triggers the interrupt (best achieved by using INT0 for D+), but it is also -possible to trigger the interrupt from D-. If D- is used, interrupts are also -triggered by SOF packets. D- requires a pull-up of 1.5k to +3.5V (and the -device must be powered at 3.5V) to identify as low-speed USB device. A -pull-down or pull-up of 1M SHOULD be connected from D+ to +3.5V to prevent -interference when no USB master is connected. If you use Zener diodes to limit -the voltage on D+ and D-, you MUST use a pull-down resistor, not a pull-up. -We use D+ as interrupt source and not D- because it does not trigger on -keep-alive and RESET states. If you want to count keep-alive events with -USB_COUNT_SOF, you MUST use D- as an interrupt source. - -As a compile time option, the 1.5k pull-up resistor on D- can be made -switchable to allow the device to disconnect at will. See the definition of -usbDeviceConnect() and usbDeviceDisconnect() further down in this file. - -Please adapt the values in usbconfig.h according to your hardware! - -The device MUST be clocked at exactly 12 MHz, 15 MHz, 16 MHz or 20 MHz -or at 12.8 MHz resp. 16.5 MHz +/- 1%. See usbconfig-prototype.h for details. - - -Limitations: -============ -Robustness with respect to communication errors: -The driver assumes error-free communication. It DOES check for errors in -the PID, but does NOT check bit stuffing errors, SE0 in middle of a byte, -token CRC (5 bit) and data CRC (16 bit). CRC checks can not be performed due -to timing constraints: We must start sending a reply within 7 bit times. -Bit stuffing and misplaced SE0 would have to be checked in real-time, but CPU -performance does not permit that. The driver does not check Data0/Data1 -toggling, but application software can implement the check. - -Input characteristics: -Since no differential receiver circuit is used, electrical interference -robustness may suffer. The driver samples only one of the data lines with -an ordinary I/O pin's input characteristics. However, since this is only a -low speed USB implementation and the specification allows for 8 times the -bit rate over the same hardware, we should be on the safe side. Even the spec -requires detection of asymmetric states at high bit rate for SE0 detection. - -Number of endpoints: -The driver supports the following endpoints: - -- Endpoint 0, the default control endpoint. -- Any number of interrupt- or bulk-out endpoints. The data is sent to - usbFunctionWriteOut() and USB_CFG_IMPLEMENT_FN_WRITEOUT must be defined - to 1 to activate this feature. The endpoint number can be found in the - global variable 'usbRxToken'. -- One default interrupt- or bulk-in endpoint. This endpoint is used for - interrupt- or bulk-in transfers which are not handled by any other endpoint. - You must define USB_CFG_HAVE_INTRIN_ENDPOINT in order to activate this - feature and call usbSetInterrupt() to send interrupt/bulk data. -- One additional interrupt- or bulk-in endpoint. This was endpoint 3 in - previous versions of this driver but can now be configured to any endpoint - number. You must define USB_CFG_HAVE_INTRIN_ENDPOINT3 in order to activate - this feature and call usbSetInterrupt3() to send interrupt/bulk data. The - endpoint number can be set with USB_CFG_EP3_NUMBER. - -Please note that the USB standard forbids bulk endpoints for low speed devices! -Most operating systems allow them anyway, but the AVR will spend 90% of the CPU -time in the USB interrupt polling for bulk data. - -Maximum data payload: -Data payload of control in and out transfers may be up to 254 bytes. In order -to accept payload data of out transfers, you need to implement -'usbFunctionWrite()'. - -USB Suspend Mode supply current: -The USB standard limits power consumption to 500uA when the bus is in suspend -mode. This is not a problem for self-powered devices since they don't need -bus power anyway. Bus-powered devices can achieve this only by putting the -CPU in sleep mode. The driver does not implement suspend handling by itself. -However, the application may implement activity monitoring and wakeup from -sleep. The host sends regular SE0 states on the bus to keep it active. These -SE0 states can be detected by using D- as the interrupt source. Define -USB_COUNT_SOF to 1 and use the global variable usbSofCount to check for bus -activity. - -Operation without an USB master: -The driver behaves neutral without connection to an USB master if D- reads -as 1. To avoid spurious interrupts, we recommend a high impedance (e.g. 1M) -pull-down or pull-up resistor on D+ (interrupt). If Zener diodes are used, -use a pull-down. If D- becomes statically 0, the driver may block in the -interrupt routine. - -Interrupt latency: -The application must ensure that the USB interrupt is not disabled for more -than 25 cycles (this is for 12 MHz, faster clocks allow longer latency). -This implies that all interrupt routines must either be declared as "INTERRUPT" -instead of "SIGNAL" (see "avr/signal.h") or that they are written in assembler -with "sei" as the first instruction. - -Maximum interrupt duration / CPU cycle consumption: -The driver handles all USB communication during the interrupt service -routine. The routine will not return before an entire USB message is received -and the reply is sent. This may be up to ca. 1200 cycles @ 12 MHz (= 100us) if -the host conforms to the standard. The driver will consume CPU cycles for all -USB messages, even if they address another (low-speed) device on the same bus. - -*/ - -/* ------------------------------------------------------------------------- */ -/* --------------------------- Module Interface ---------------------------- */ -/* ------------------------------------------------------------------------- */ - -#define USBDRV_VERSION 20090323 -/* This define uniquely identifies a driver version. It is a decimal number - * constructed from the driver's release date in the form YYYYMMDD. If the - * driver's behavior or interface changes, you can use this constant to - * distinguish versions. If it is not defined, the driver's release date is - * older than 2006-01-25. - */ - - -#ifndef USB_PUBLIC -#define USB_PUBLIC -#endif -/* USB_PUBLIC is used as declaration attribute for all functions exported by - * the USB driver. The default is no attribute (see above). You may define it - * to static either in usbconfig.h or from the command line if you include - * usbdrv.c instead of linking against it. Including the C module of the driver - * directly in your code saves a couple of bytes in flash memory. - */ - -#ifndef __ASSEMBLER__ -#ifndef uchar -#define uchar unsigned char -#endif -#ifndef schar -#define schar signed char -#endif -/* shortcuts for well defined 8 bit integer types */ - -#if USB_CFG_LONG_TRANSFERS /* if more than 254 bytes transfer size required */ -# define usbMsgLen_t unsigned -#else -# define usbMsgLen_t uchar -#endif -/* usbMsgLen_t is the data type used for transfer lengths. By default, it is - * defined to uchar, allowing a maximum of 254 bytes (255 is reserved for - * USB_NO_MSG below). If the usbconfig.h defines USB_CFG_LONG_TRANSFERS to 1, - * a 16 bit data type is used, allowing up to 16384 bytes (the rest is used - * for flags in the descriptor configuration). - */ -#define USB_NO_MSG ((usbMsgLen_t)-1) /* constant meaning "no message" */ - -struct usbRequest; /* forward declaration */ - -USB_PUBLIC void usbInit(void); -/* This function must be called before interrupts are enabled and the main - * loop is entered. - */ -USB_PUBLIC void usbPoll(void); -/* This function must be called at regular intervals from the main loop. - * Maximum delay between calls is somewhat less than 50ms (USB timeout for - * accepting a Setup message). Otherwise the device will not be recognized. - * Please note that debug outputs through the UART take ~ 0.5ms per byte - * at 19200 bps. - */ -extern uchar *usbMsgPtr; -/* This variable may be used to pass transmit data to the driver from the - * implementation of usbFunctionWrite(). It is also used internally by the - * driver for standard control requests. - */ -USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]); -/* This function is called when the driver receives a SETUP transaction from - * the host which is not answered by the driver itself (in practice: class and - * vendor requests). All control transfers start with a SETUP transaction where - * the host communicates the parameters of the following (optional) data - * transfer. The SETUP data is available in the 'data' parameter which can - * (and should) be casted to 'usbRequest_t *' for a more user-friendly access - * to parameters. - * - * If the SETUP indicates a control-in transfer, you should provide the - * requested data to the driver. There are two ways to transfer this data: - * (1) Set the global pointer 'usbMsgPtr' to the base of the static RAM data - * block and return the length of the data in 'usbFunctionSetup()'. The driver - * will handle the rest. Or (2) return USB_NO_MSG in 'usbFunctionSetup()'. The - * driver will then call 'usbFunctionRead()' when data is needed. See the - * documentation for usbFunctionRead() for details. - * - * If the SETUP indicates a control-out transfer, the only way to receive the - * data from the host is through the 'usbFunctionWrite()' call. If you - * implement this function, you must return USB_NO_MSG in 'usbFunctionSetup()' - * to indicate that 'usbFunctionWrite()' should be used. See the documentation - * of this function for more information. If you just want to ignore the data - * sent by the host, return 0 in 'usbFunctionSetup()'. - * - * Note that calls to the functions usbFunctionRead() and usbFunctionWrite() - * are only done if enabled by the configuration in usbconfig.h. - */ -USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq); -/* You need to implement this function ONLY if you provide USB descriptors at - * runtime (which is an expert feature). It is very similar to - * usbFunctionSetup() above, but it is called only to request USB descriptor - * data. See the documentation of usbFunctionSetup() above for more info. - */ -#if USB_CFG_HAVE_INTRIN_ENDPOINT -USB_PUBLIC void usbSetInterrupt(uchar *data, uchar len); -/* This function sets the message which will be sent during the next interrupt - * IN transfer. The message is copied to an internal buffer and must not exceed - * a length of 8 bytes. The message may be 0 bytes long just to indicate the - * interrupt status to the host. - * If you need to transfer more bytes, use a control read after the interrupt. - */ -#define usbInterruptIsReady() (usbTxLen1 & 0x10) -/* This macro indicates whether the last interrupt message has already been - * sent. If you set a new interrupt message before the old was sent, the - * message already buffered will be lost. - */ -#if USB_CFG_HAVE_INTRIN_ENDPOINT3 -USB_PUBLIC void usbSetInterrupt3(uchar *data, uchar len); -#define usbInterruptIsReady3() (usbTxLen3 & 0x10) -/* Same as above for endpoint 3 */ -#endif -#endif /* USB_CFG_HAVE_INTRIN_ENDPOINT */ -#if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH /* simplified interface for backward compatibility */ -#define usbHidReportDescriptor usbDescriptorHidReport -/* should be declared as: PROGMEM char usbHidReportDescriptor[]; */ -/* If you implement an HID device, you need to provide a report descriptor. - * The HID report descriptor syntax is a bit complex. If you understand how - * report descriptors are constructed, we recommend that you use the HID - * Descriptor Tool from usb.org, see http://www.usb.org/developers/hidpage/. - * Otherwise you should probably start with a working example. - */ -#endif /* USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH */ -#if USB_CFG_IMPLEMENT_FN_WRITE -USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len); -/* This function is called by the driver to provide a control transfer's - * payload data (control-out). It is called in chunks of up to 8 bytes. The - * total count provided in the current control transfer can be obtained from - * the 'length' property in the setup data. If an error occurred during - * processing, return 0xff (== -1). The driver will answer the entire transfer - * with a STALL token in this case. If you have received the entire payload - * successfully, return 1. If you expect more data, return 0. If you don't - * know whether the host will send more data (you should know, the total is - * provided in the usbFunctionSetup() call!), return 1. - * NOTE: If you return 0xff for STALL, 'usbFunctionWrite()' may still be called - * for the remaining data. You must continue to return 0xff for STALL in these - * calls. - * In order to get usbFunctionWrite() called, define USB_CFG_IMPLEMENT_FN_WRITE - * to 1 in usbconfig.h and return 0xff in usbFunctionSetup().. - */ -#endif /* USB_CFG_IMPLEMENT_FN_WRITE */ -#if USB_CFG_IMPLEMENT_FN_READ -USB_PUBLIC uchar usbFunctionRead(uchar *data, uchar len); -/* This function is called by the driver to ask the application for a control - * transfer's payload data (control-in). It is called in chunks of up to 8 - * bytes each. You should copy the data to the location given by 'data' and - * return the actual number of bytes copied. If you return less than requested, - * the control-in transfer is terminated. If you return 0xff, the driver aborts - * the transfer with a STALL token. - * In order to get usbFunctionRead() called, define USB_CFG_IMPLEMENT_FN_READ - * to 1 in usbconfig.h and return 0xff in usbFunctionSetup().. - */ -#endif /* USB_CFG_IMPLEMENT_FN_READ */ - -extern uchar usbRxToken; /* may be used in usbFunctionWriteOut() below */ -#if USB_CFG_IMPLEMENT_FN_WRITEOUT -USB_PUBLIC void usbFunctionWriteOut(uchar *data, uchar len); -/* This function is called by the driver when data is received on an interrupt- - * or bulk-out endpoint. The endpoint number can be found in the global - * variable usbRxToken. You must define USB_CFG_IMPLEMENT_FN_WRITEOUT to 1 in - * usbconfig.h to get this function called. - */ -#endif /* USB_CFG_IMPLEMENT_FN_WRITEOUT */ -#ifdef USB_CFG_PULLUP_IOPORTNAME -#define usbDeviceConnect() ((USB_PULLUP_DDR |= (1<device, 1=device->host - * t ..... type: 0=standard, 1=class, 2=vendor, 3=reserved - * r ..... recipient: 0=device, 1=interface, 2=endpoint, 3=other - */ - -/* USB setup recipient values */ -#define USBRQ_RCPT_MASK 0x1f -#define USBRQ_RCPT_DEVICE 0 -#define USBRQ_RCPT_INTERFACE 1 -#define USBRQ_RCPT_ENDPOINT 2 - -/* USB request type values */ -#define USBRQ_TYPE_MASK 0x60 -#define USBRQ_TYPE_STANDARD (0<<5) -#define USBRQ_TYPE_CLASS (1<<5) -#define USBRQ_TYPE_VENDOR (2<<5) - -/* USB direction values: */ -#define USBRQ_DIR_MASK 0x80 -#define USBRQ_DIR_HOST_TO_DEVICE (0<<7) -#define USBRQ_DIR_DEVICE_TO_HOST (1<<7) - -/* USB Standard Requests */ -#define USBRQ_GET_STATUS 0 -#define USBRQ_CLEAR_FEATURE 1 -#define USBRQ_SET_FEATURE 3 -#define USBRQ_SET_ADDRESS 5 -#define USBRQ_GET_DESCRIPTOR 6 -#define USBRQ_SET_DESCRIPTOR 7 -#define USBRQ_GET_CONFIGURATION 8 -#define USBRQ_SET_CONFIGURATION 9 -#define USBRQ_GET_INTERFACE 10 -#define USBRQ_SET_INTERFACE 11 -#define USBRQ_SYNCH_FRAME 12 - -/* USB descriptor constants */ -#define USBDESCR_DEVICE 1 -#define USBDESCR_CONFIG 2 -#define USBDESCR_STRING 3 -#define USBDESCR_INTERFACE 4 -#define USBDESCR_ENDPOINT 5 -#define USBDESCR_HID 0x21 -#define USBDESCR_HID_REPORT 0x22 -#define USBDESCR_HID_PHYS 0x23 - -#define USBATTR_BUSPOWER 0x80 -#define USBATTR_SELFPOWER 0x40 -#define USBATTR_REMOTEWAKE 0x20 - -/* USB HID Requests */ -#define USBRQ_HID_GET_REPORT 0x01 -#define USBRQ_HID_GET_IDLE 0x02 -#define USBRQ_HID_GET_PROTOCOL 0x03 -#define USBRQ_HID_SET_REPORT 0x09 -#define USBRQ_HID_SET_IDLE 0x0a -#define USBRQ_HID_SET_PROTOCOL 0x0b - -/* ------------------------------------------------------------------------- */ - -#endif /* __usbdrv_h_included__ */ diff --git a/tools/avrusb/usbdrv/usbdrvasm.S b/tools/avrusb/usbdrv/usbdrvasm.S deleted file mode 100644 index 52c3d98..0000000 --- a/tools/avrusb/usbdrv/usbdrvasm.S +++ /dev/null @@ -1,305 +0,0 @@ -/* Name: usbdrvasm.S - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2007-06-13 - * Tabsize: 4 - * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * Revision: $Id: usbdrvasm.S 722 2009-03-16 19:03:57Z cs $ - */ - -/* -General Description: -This module is the assembler part of the USB driver. This file contains -general code (preprocessor acrobatics and CRC computation) and then includes -the file appropriate for the given clock rate. -*/ - -#define __SFR_OFFSET 0 /* used by avr-libc's register definitions */ -#include "usbportability.h" -#include "usbdrv.h" /* for common defs */ - -/* register names */ -#define x1 r16 -#define x2 r17 -#define shift r18 -#define cnt r19 -#define x3 r20 -#define x4 r21 -#define x5 r22 -#define bitcnt x5 -#define phase x4 -#define leap x4 - -/* Some assembler dependent definitions and declarations: */ - -#ifdef __IAR_SYSTEMS_ASM__ - extern usbRxBuf, usbDeviceAddr, usbNewDeviceAddr, usbInputBufOffset - extern usbCurrentTok, usbRxLen, usbRxToken, usbTxLen - extern usbTxBuf, usbTxStatus1, usbTxStatus3 -# if USB_COUNT_SOF - extern usbSofCount -# endif - public usbCrc16 - public usbCrc16Append - - COMMON INTVEC -# ifndef USB_INTR_VECTOR - ORG INT0_vect -# else /* USB_INTR_VECTOR */ - ORG USB_INTR_VECTOR -# undef USB_INTR_VECTOR -# endif /* USB_INTR_VECTOR */ -# define USB_INTR_VECTOR usbInterruptHandler - rjmp USB_INTR_VECTOR - RSEG CODE - -#else /* __IAR_SYSTEMS_ASM__ */ - -# ifndef USB_INTR_VECTOR /* default to hardware interrupt INT0 */ -# define USB_INTR_VECTOR SIG_INTERRUPT0 -# endif - .text - .global USB_INTR_VECTOR - .type USB_INTR_VECTOR, @function - .global usbCrc16 - .global usbCrc16Append -#endif /* __IAR_SYSTEMS_ASM__ */ - - -#if USB_INTR_PENDING < 0x40 /* This is an I/O address, use in and out */ -# define USB_LOAD_PENDING(reg) in reg, USB_INTR_PENDING -# define USB_STORE_PENDING(reg) out USB_INTR_PENDING, reg -#else /* It's a memory address, use lds and sts */ -# define USB_LOAD_PENDING(reg) lds reg, USB_INTR_PENDING -# define USB_STORE_PENDING(reg) sts USB_INTR_PENDING, reg -#endif - -#define usbTxLen1 usbTxStatus1 -#define usbTxBuf1 (usbTxStatus1 + 1) -#define usbTxLen3 usbTxStatus3 -#define usbTxBuf3 (usbTxStatus3 + 1) - - -;---------------------------------------------------------------------------- -; Utility functions -;---------------------------------------------------------------------------- - -#ifdef __IAR_SYSTEMS_ASM__ -/* Register assignments for usbCrc16 on IAR cc */ -/* Calling conventions on IAR: - * First parameter passed in r16/r17, second in r18/r19 and so on. - * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer) - * Result is passed in r16/r17 - * In case of the "tiny" memory model, pointers are only 8 bit with no - * padding. We therefore pass argument 1 as "16 bit unsigned". - */ -RTMODEL "__rt_version", "3" -/* The line above will generate an error if cc calling conventions change. - * The value "3" above is valid for IAR 4.10B/W32 - */ -# define argLen r18 /* argument 2 */ -# define argPtrL r16 /* argument 1 */ -# define argPtrH r17 /* argument 1 */ - -# define resCrcL r16 /* result */ -# define resCrcH r17 /* result */ - -# define ptrL ZL -# define ptrH ZH -# define ptr Z -# define byte r22 -# define bitCnt r19 -# define polyL r20 -# define polyH r21 -# define scratch r23 - -#else /* __IAR_SYSTEMS_ASM__ */ -/* Register assignments for usbCrc16 on gcc */ -/* Calling conventions on gcc: - * First parameter passed in r24/r25, second in r22/23 and so on. - * Callee must preserve r1-r17, r28/r29 - * Result is passed in r24/r25 - */ -# define argLen r22 /* argument 2 */ -# define argPtrL r24 /* argument 1 */ -# define argPtrH r25 /* argument 1 */ - -# define resCrcL r24 /* result */ -# define resCrcH r25 /* result */ - -# define ptrL XL -# define ptrH XH -# define ptr x -# define byte r18 -# define bitCnt r19 -# define polyL r20 -# define polyH r21 -# define scratch r23 - -#endif - -; extern unsigned usbCrc16(unsigned char *data, unsigned char len); -; data: r24/25 -; len: r22 -; temp variables: -; r18: data byte -; r19: bit counter -; r20/21: polynomial -; r23: scratch -; r24/25: crc-sum -; r26/27=X: ptr -usbCrc16: - mov ptrL, argPtrL - mov ptrH, argPtrH - ldi resCrcL, 0 - ldi resCrcH, 0 - ldi polyL, lo8(0xa001) - ldi polyH, hi8(0xa001) - com argLen ; argLen = -argLen - 1 -crcByteLoop: - subi argLen, -1 - brcc crcReady ; modified loop to ensure that carry is set below - ld byte, ptr+ - ldi bitCnt, -8 ; strange loop counter to ensure that carry is set where we need it - eor resCrcL, byte -crcBitLoop: - ror resCrcH ; carry is always set here - ror resCrcL - brcs crcNoXor - eor resCrcL, polyL - eor resCrcH, polyH -crcNoXor: - subi bitCnt, -1 - brcs crcBitLoop - rjmp crcByteLoop -crcReady: - ret -; Thanks to Reimar Doeffinger for optimizing this CRC routine! - -; extern unsigned usbCrc16Append(unsigned char *data, unsigned char len); -usbCrc16Append: - rcall usbCrc16 - st ptr+, resCrcL - st ptr+, resCrcH - ret - -#undef argLen -#undef argPtrL -#undef argPtrH -#undef resCrcL -#undef resCrcH -#undef ptrL -#undef ptrH -#undef ptr -#undef byte -#undef bitCnt -#undef polyL -#undef polyH -#undef scratch - - -#if USB_CFG_HAVE_MEASURE_FRAME_LENGTH -#ifdef __IAR_SYSTEMS_ASM__ -/* Register assignments for usbMeasureFrameLength on IAR cc */ -/* Calling conventions on IAR: - * First parameter passed in r16/r17, second in r18/r19 and so on. - * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer) - * Result is passed in r16/r17 - * In case of the "tiny" memory model, pointers are only 8 bit with no - * padding. We therefore pass argument 1 as "16 bit unsigned". - */ -# define resL r16 -# define resH r17 -# define cnt16L r30 -# define cnt16H r31 -# define cntH r18 - -#else /* __IAR_SYSTEMS_ASM__ */ -/* Register assignments for usbMeasureFrameLength on gcc */ -/* Calling conventions on gcc: - * First parameter passed in r24/r25, second in r22/23 and so on. - * Callee must preserve r1-r17, r28/r29 - * Result is passed in r24/r25 - */ -# define resL r24 -# define resH r25 -# define cnt16L r24 -# define cnt16H r25 -# define cntH r26 -#endif -# define cnt16 cnt16L - -; extern unsigned usbMeasurePacketLength(void); -; returns time between two idle strobes in multiples of 7 CPU clocks -.global usbMeasureFrameLength -usbMeasureFrameLength: - ldi cntH, 6 ; wait ~ 10 ms for D- == 0 - clr cnt16L - clr cnt16H -usbMFTime16: - dec cntH - breq usbMFTimeout -usbMFWaitStrobe: ; first wait for D- == 0 (idle strobe) - sbiw cnt16, 1 ;[0] [6] - breq usbMFTime16 ;[2] - sbic USBIN, USBMINUS ;[3] - rjmp usbMFWaitStrobe ;[4] -usbMFWaitIdle: ; then wait until idle again - sbis USBIN, USBMINUS ;1 wait for D- == 1 - rjmp usbMFWaitIdle ;2 - ldi cnt16L, 1 ;1 represents cycles so far - clr cnt16H ;1 -usbMFWaitLoop: - in cntH, USBIN ;[0] [7] - adiw cnt16, 1 ;[1] - breq usbMFTimeout ;[3] - andi cntH, USBMASK ;[4] - brne usbMFWaitLoop ;[5] -usbMFTimeout: -#if resL != cnt16L - mov resL, cnt16L - mov resH, cnt16H -#endif - ret - -#undef resL -#undef resH -#undef cnt16 -#undef cnt16L -#undef cnt16H -#undef cntH - -#endif /* USB_CFG_HAVE_MEASURE_FRAME_LENGTH */ - -;---------------------------------------------------------------------------- -; Now include the clock rate specific code -;---------------------------------------------------------------------------- - -#ifndef USB_CFG_CLOCK_KHZ -# define USB_CFG_CLOCK_KHZ 12000 -#endif - -#if USB_CFG_CHECK_CRC /* separate dispatcher for CRC type modules */ -# if USB_CFG_CLOCK_KHZ == 18000 -# include "usbdrvasm18-crc.inc" -# else -# error "USB_CFG_CLOCK_KHZ is not one of the supported crc-rates!" -# endif -#else /* USB_CFG_CHECK_CRC */ -# if USB_CFG_CLOCK_KHZ == 12000 -# include "usbdrvasm12.inc" -# elif USB_CFG_CLOCK_KHZ == 12800 -# include "usbdrvasm128.inc" -# elif USB_CFG_CLOCK_KHZ == 15000 -# include "usbdrvasm15.inc" -# elif USB_CFG_CLOCK_KHZ == 16000 -# include "usbdrvasm16.inc" -# elif USB_CFG_CLOCK_KHZ == 16500 -# include "usbdrvasm165.inc" -# elif USB_CFG_CLOCK_KHZ == 20000 -# include "usbdrvasm20.inc" -# else -# error "USB_CFG_CLOCK_KHZ is not one of the supported non-crc-rates!" -# endif -#endif /* USB_CFG_CHECK_CRC */ diff --git a/tools/avrusb/usbdrv/usbdrvasm.asm b/tools/avrusb/usbdrv/usbdrvasm.asm deleted file mode 100644 index a534b73..0000000 --- a/tools/avrusb/usbdrv/usbdrvasm.asm +++ /dev/null @@ -1,21 +0,0 @@ -/* Name: usbdrvasm.asm - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2006-03-01 - * Tabsize: 4 - * Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id$ - */ - -/* -General Description: -The IAR compiler/assembler system prefers assembler files with file extension -".asm". We simply provide this file as an alias for usbdrvasm.S. - -Thanks to Oleg Semyonov for his help with the IAR tools port! -*/ - -#include "usbdrvasm.S" - -end diff --git a/tools/avrusb/usbdrv/usbdrvasm12.inc b/tools/avrusb/usbdrv/usbdrvasm12.inc deleted file mode 100644 index 08dddd3..0000000 --- a/tools/avrusb/usbdrv/usbdrvasm12.inc +++ /dev/null @@ -1,393 +0,0 @@ -/* Name: usbdrvasm12.inc - * Project: AVR USB driver - * Author: Christian Starkjohann - * Creation Date: 2004-12-29 - * Tabsize: 4 - * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * This Revision: $Id: usbdrvasm12.inc 692 2008-11-07 15:07:40Z cs $ - */ - -/* Do not link this file! Link usbdrvasm.S instead, which includes the - * appropriate implementation! - */ - -/* -General Description: -This file is the 12 MHz version of the asssembler part of the USB driver. It -requires a 12 MHz crystal (not a ceramic resonator and not a calibrated RC -oscillator). - -See usbdrv.h for a description of the entire driver. - -Since almost all of this code is timing critical, don't change unless you -really know what you are doing! Many parts require not only a maximum number -of CPU cycles, but even an exact number of cycles! - - -Timing constraints according to spec (in bit times): -timing subject min max CPUcycles ---------------------------------------------------------------------------- -EOP of OUT/SETUP to sync pattern of DATA0 (both rx) 2 16 16-128 -EOP of IN to sync pattern of DATA0 (rx, then tx) 2 7.5 16-60 -DATAx (rx) to ACK/NAK/STALL (tx) 2 7.5 16-60 -*/ - -;Software-receiver engine. Strict timing! Don't change unless you can preserve timing! -;interrupt response time: 4 cycles + insn running = 7 max if interrupts always enabled -;max allowable interrupt latency: 34 cycles -> max 25 cycles interrupt disable -;max stack usage: [ret(2), YL, SREG, YH, shift, x1, x2, x3, cnt, x4] = 11 bytes -;Numbers in brackets are maximum cycles since SOF. -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt - push YL ;2 [35] push only what is necessary to sync with edge ASAP - in YL, SREG ;1 [37] - push YL ;2 [39] -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of 1/4 bit which meets the spec. - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -foundK: -;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling] -;we have 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push YH ;2 [2] - lds YL, usbInputBufOffset;2 [4] - clr YH ;1 [5] - subi YL, lo8(-(usbRxBuf));1 [6] - sbci YH, hi8(-(usbRxBuf));1 [7] - - sbis USBIN, USBMINUS ;1 [8] we want two bits K [sample 1 cycle too early] - rjmp haveTwoBitsK ;2 [10] - pop YH ;2 [11] undo the push from before - rjmp waitForK ;2 [13] this was not the end of sync, retry -haveTwoBitsK: -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- - push shift ;2 [16] - push x1 ;2 [12] - push x2 ;2 [14] - - in x1, USBIN ;1 [17] <-- sample bit 0 - ldi shift, 0xff ;1 [18] - bst x1, USBMINUS ;1 [19] - bld shift, 0 ;1 [20] - push x3 ;2 [22] - push cnt ;2 [24] - - in x2, USBIN ;1 [25] <-- sample bit 1 - ser x3 ;1 [26] [inserted init instruction] - eor x1, x2 ;1 [27] - bst x1, USBMINUS ;1 [28] - bld shift, 1 ;1 [29] - ldi cnt, USB_BUFSIZE;1 [30] [inserted init instruction] - rjmp rxbit2 ;2 [32] - -;---------------------------------------------------------------------------- -; Receiver loop (numbers in brackets are cycles within byte after instr) -;---------------------------------------------------------------------------- - -unstuff0: ;1 (branch taken) - andi x3, ~0x01 ;1 [15] - mov x1, x2 ;1 [16] x2 contains last sampled (stuffed) bit - in x2, USBIN ;1 [17] <-- sample bit 1 again - ori shift, 0x01 ;1 [18] - rjmp didUnstuff0 ;2 [20] - -unstuff1: ;1 (branch taken) - mov x2, x1 ;1 [21] x1 contains last sampled (stuffed) bit - andi x3, ~0x02 ;1 [22] - ori shift, 0x02 ;1 [23] - nop ;1 [24] - in x1, USBIN ;1 [25] <-- sample bit 2 again - rjmp didUnstuff1 ;2 [27] - -unstuff2: ;1 (branch taken) - andi x3, ~0x04 ;1 [29] - ori shift, 0x04 ;1 [30] - mov x1, x2 ;1 [31] x2 contains last sampled (stuffed) bit - nop ;1 [32] - in x2, USBIN ;1 [33] <-- sample bit 3 - rjmp didUnstuff2 ;2 [35] - -unstuff3: ;1 (branch taken) - in x2, USBIN ;1 [34] <-- sample stuffed bit 3 [one cycle too late] - andi x3, ~0x08 ;1 [35] - ori shift, 0x08 ;1 [36] - rjmp didUnstuff3 ;2 [38] - -unstuff4: ;1 (branch taken) - andi x3, ~0x10 ;1 [40] - in x1, USBIN ;1 [41] <-- sample stuffed bit 4 - ori shift, 0x10 ;1 [42] - rjmp didUnstuff4 ;2 [44] - -unstuff5: ;1 (branch taken) - andi x3, ~0x20 ;1 [48] - in x2, USBIN ;1 [49] <-- sample stuffed bit 5 - ori shift, 0x20 ;1 [50] - rjmp didUnstuff5 ;2 [52] - -unstuff6: ;1 (branch taken) - andi x3, ~0x40 ;1 [56] - in x1, USBIN ;1 [57] <-- sample stuffed bit 6 - ori shift, 0x40 ;1 [58] - rjmp didUnstuff6 ;2 [60] - -; extra jobs done during bit interval: -; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs] -; bit 1: se0 check -; bit 2: overflow check -; bit 3: recovery from delay [bit 0 tasks took too long] -; bit 4: none -; bit 5: none -; bit 6: none -; bit 7: jump, eor -rxLoop: - eor x3, shift ;1 [0] reconstruct: x3 is 0 at bit locations we changed, 1 at others - in x1, USBIN ;1 [1] <-- sample bit 0 - st y+, x3 ;2 [3] store data - ser x3 ;1 [4] - nop ;1 [5] - eor x2, x1 ;1 [6] - bst x2, USBMINUS;1 [7] - bld shift, 0 ;1 [8] - in x2, USBIN ;1 [9] <-- sample bit 1 (or possibly bit 0 stuffed) - andi x2, USBMASK ;1 [10] - breq se0 ;1 [11] SE0 check for bit 1 - andi shift, 0xf9 ;1 [12] -didUnstuff0: - breq unstuff0 ;1 [13] - eor x1, x2 ;1 [14] - bst x1, USBMINUS;1 [15] - bld shift, 1 ;1 [16] -rxbit2: - in x1, USBIN ;1 [17] <-- sample bit 2 (or possibly bit 1 stuffed) - andi shift, 0xf3 ;1 [18] - breq unstuff1 ;1 [19] do remaining work for bit 1 -didUnstuff1: - subi cnt, 1 ;1 [20] - brcs overflow ;1 [21] loop control - eor x2, x1 ;1 [22] - bst x2, USBMINUS;1 [23] - bld shift, 2 ;1 [24] - in x2, USBIN ;1 [25] <-- sample bit 3 (or possibly bit 2 stuffed) - andi shift, 0xe7 ;1 [26] - breq unstuff2 ;1 [27] -didUnstuff2: - eor x1, x2 ;1 [28] - bst x1, USBMINUS;1 [29] - bld shift, 3 ;1 [30] -didUnstuff3: - andi shift, 0xcf ;1 [31] - breq unstuff3 ;1 [32] - in x1, USBIN ;1 [33] <-- sample bit 4 - eor x2, x1 ;1 [34] - bst x2, USBMINUS;1 [35] - bld shift, 4 ;1 [36] -didUnstuff4: - andi shift, 0x9f ;1 [37] - breq unstuff4 ;1 [38] - nop2 ;2 [40] - in x2, USBIN ;1 [41] <-- sample bit 5 - eor x1, x2 ;1 [42] - bst x1, USBMINUS;1 [43] - bld shift, 5 ;1 [44] -didUnstuff5: - andi shift, 0x3f ;1 [45] - breq unstuff5 ;1 [46] - nop2 ;2 [48] - in x1, USBIN ;1 [49] <-- sample bit 6 - eor x2, x1 ;1 [50] - bst x2, USBMINUS;1 [51] - bld shift, 6 ;1 [52] -didUnstuff6: - cpi shift, 0x02 ;1 [53] - brlo unstuff6 ;1 [54] - nop2 ;2 [56] - in x2, USBIN ;1 [57] <-- sample bit 7 - eor x1, x2 ;1 [58] - bst x1, USBMINUS;1 [59] - bld shift, 7 ;1 [60] -didUnstuff7: - cpi shift, 0x04 ;1 [61] - brsh rxLoop ;2 [63] loop control -unstuff7: - andi x3, ~0x80 ;1 [63] - ori shift, 0x80 ;1 [64] - in x2, USBIN ;1 [65] <-- sample stuffed bit 7 - nop ;1 [66] - rjmp didUnstuff7 ;2 [68] - -macro POP_STANDARD ; 12 cycles - pop cnt - pop x3 - pop x2 - pop x1 - pop shift - pop YH - endm -macro POP_RETI ; 5 cycles - pop YL - out SREG, YL - pop YL - endm - -#include "asmcommon.inc" - -;---------------------------------------------------------------------------- -; Transmitting data -;---------------------------------------------------------------------------- - -txByteLoop: -txBitloop: -stuffN1Delay: ; [03] - ror shift ;[-5] [11] [59] - brcc doExorN1 ;[-4] [60] - subi x4, 1 ;[-3] - brne commonN1 ;[-2] - lsl shift ;[-1] compensate ror after rjmp stuffDelay - nop ;[00] stuffing consists of just waiting 8 cycles - rjmp stuffN1Delay ;[01] after ror, C bit is reliably clear - -sendNakAndReti: ;0 [-19] 19 cycles until SOP - ldi x3, USBPID_NAK ;1 [-18] - rjmp usbSendX3 ;2 [-16] -sendAckAndReti: ;0 [-19] 19 cycles until SOP - ldi x3, USBPID_ACK ;1 [-18] - rjmp usbSendX3 ;2 [-16] -sendCntAndReti: ;0 [-17] 17 cycles until SOP - mov x3, cnt ;1 [-16] -usbSendX3: ;0 [-16] - ldi YL, 20 ;1 [-15] 'x3' is R20 - ldi YH, 0 ;1 [-14] - ldi cnt, 2 ;1 [-13] -; rjmp usbSendAndReti fallthrough - -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) or USBOUT = 0x01 -; K = (D+ = 1), (D- = 0) or USBOUT = 0x02 -; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles) - -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte -;uses: x1...x2, x4, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x4 = bitstuff cnt] -;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction) -usbSendAndReti: - in x2, USBDDR ;[-12] 12 cycles until SOP - ori x2, USBMASK ;[-11] - sbi USBOUT, USBMINUS ;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) - out USBDDR, x2 ;[-8] <--- acquire bus - in x1, USBOUT ;[-7] port mirror for tx loop - ldi shift, 0x40 ;[-6] sync byte is first byte sent (we enter loop after ror) - ldi x2, USBMASK ;[-5] - push x4 ;[-4] -doExorN1: - eor x1, x2 ;[-2] [06] [62] - ldi x4, 6 ;[-1] [07] [63] -commonN1: -stuffN2Delay: - out USBOUT, x1 ;[00] [08] [64] <--- set bit - ror shift ;[01] - brcc doExorN2 ;[02] - subi x4, 1 ;[03] - brne commonN2 ;[04] - lsl shift ;[05] compensate ror after rjmp stuffDelay - rjmp stuffN2Delay ;[06] after ror, C bit is reliably clear -doExorN2: - eor x1, x2 ;[04] [12] - ldi x4, 6 ;[05] [13] -commonN2: - nop ;[06] [14] - subi cnt, 171 ;[07] [15] trick: (3 * 171) & 0xff = 1 - out USBOUT, x1 ;[08] [16] <--- set bit - brcs txBitloop ;[09] [25] [41] - -stuff6Delay: - ror shift ;[42] [50] - brcc doExor6 ;[43] - subi x4, 1 ;[44] - brne common6 ;[45] - lsl shift ;[46] compensate ror after rjmp stuffDelay - nop ;[47] stuffing consists of just waiting 8 cycles - rjmp stuff6Delay ;[48] after ror, C bit is reliably clear -doExor6: - eor x1, x2 ;[45] [53] - ldi x4, 6 ;[46] -common6: -stuff7Delay: - ror shift ;[47] [55] - out USBOUT, x1 ;[48] <--- set bit - brcc doExor7 ;[49] - subi x4, 1 ;[50] - brne common7 ;[51] - lsl shift ;[52] compensate ror after rjmp stuffDelay - rjmp stuff7Delay ;[53] after ror, C bit is reliably clear -doExor7: - eor x1, x2 ;[51] [59] - ldi x4, 6 ;[52] -common7: - ld shift, y+ ;[53] - tst cnt ;[55] - out USBOUT, x1 ;[56] <--- set bit - brne txByteLoop ;[57] - -;make SE0: - cbr x1, USBMASK ;[58] prepare SE0 [spec says EOP may be 15 to 18 cycles] - lds x2, usbNewDeviceAddr;[59] - lsl x2 ;[61] we compare with left shifted address - subi YL, 2 + 20 ;[62] Only assign address on data packets, not ACK/NAK in x3 - sbci YH, 0 ;[63] - out USBOUT, x1 ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - breq skipAddrAssign ;[01] - sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer -skipAddrAssign: -;end of usbDeviceAddress transfer - ldi x2, 1< 12.5625 MHz -max frequency: 69.286 cycles for 8 bit -> 12.99 MHz -nominal frequency: 12.77 MHz ( = sqrt(min * max)) - -sampling positions: (next even number in range [+/- 0.5]) -cycle index range: 0 ... 66 -bits: -.5, 8.875, 17.25, 25.625, 34, 42.375, 50.75, 59.125 -[0/1], [9], [17], [25/+26], [34], [+42/43], [51], [59] - -bit number: 0 1 2 3 4 5 6 7 -spare cycles 1 2 1 2 1 1 1 0 - -operations to perform: duration cycle - ---------------- - eor fix, shift 1 -> 00 - andi phase, USBMASK 1 -> 08 - breq se0 1 -> 16 (moved to 11) - st y+, data 2 -> 24, 25 - mov data, fix 1 -> 33 - ser data 1 -> 41 - subi cnt, 1 1 -> 49 - brcs overflow 1 -> 50 - -layout of samples and operations: -[##] = sample bit -<##> = sample phase -*##* = operation - -0: *00* [01] 02 03 04 <05> 06 07 -1: *08* [09] 10 11 12 <13> 14 15 *16* -2: [17] 18 19 20 <21> 22 23 -3: *24* *25* [26] 27 28 29 <30> 31 32 -4: *33* [34] 35 36 37 <38> 39 40 -5: *41* [42] 43 44 45 <46> 47 48 -6: *49* *50* [51] 52 53 54 <55> 56 57 58 -7: [59] 60 61 62 <63> 64 65 66 -*****************************************************************************/ - -/* we prefer positive expressions (do if condition) instead of negative - * (skip if condition), therefore use defines for skip instructions: - */ -#define ifioclr sbis -#define ifioset sbic -#define ifrclr sbrs -#define ifrset sbrc - -/* The registers "fix" and "data" swap their meaning during the loop. Use - * defines to keep their name constant. - */ -#define fix x2 -#define data x1 -#undef phase /* phase has a default definition to x4 */ -#define phase x3 - - -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt, r0 - push YL ;2 push only what is necessary to sync with edge ASAP - in YL, SREG ;1 - push YL ;2 -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of 1/4 bit which meets the spec. - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS ;[0] - rjmp foundK ;[1] -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError - -foundK: -;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling] -;we have 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push YH ;[2] - lds YL, usbInputBufOffset;[4] - clr YH ;[6] - subi YL, lo8(-(usbRxBuf));[7] - sbci YH, hi8(-(usbRxBuf));[8] - - sbis USBIN, USBMINUS ;[9] we want two bits K [we want to sample at 8 + 4 - 1.5 = 10.5] - rjmp haveTwoBitsK ;[10] - pop YH ;[11] undo the push from before - rjmp waitForK ;[13] this was not the end of sync, retry -haveTwoBitsK: -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -#define fix x2 -#define data x1 - - push shift ;[12] - push x1 ;[14] - push x2 ;[16] - ldi shift, 0x80 ;[18] prevent bit-unstuffing but init low bits to 0 - ifioset USBIN, USBMINUS ;[19] [01] <--- bit 0 [10.5 + 8 = 18.5] - ori shift, 1<<0 ;[02] - push x3 ;[03] - push cnt ;[05] - push r0 ;[07] - ifioset USBIN, USBMINUS ;[09] <--- bit 1 - ori shift, 1<<1 ;[10] - ser fix ;[11] - ldi cnt, USB_BUFSIZE ;[12] - mov data, shift ;[13] - lsl shift ;[14] - nop2 ;[15] - ifioset USBIN, USBMINUS ;[17] <--- bit 2 - ori data, 3<<2 ;[18] store in bit 2 AND bit 3 - eor shift, data ;[19] do nrzi decoding - andi data, 1<<3 ;[20] - in phase, USBIN ;[21] <- phase - brne jumpToEntryAfterSet ;[22] if USBMINS at bit 3 was 1 - nop ;[23] - rjmp entryAfterClr ;[24] -jumpToEntryAfterSet: - rjmp entryAfterSet ;[24] - -;---------------------------------------------------------------------------- -; Receiver loop (numbers in brackets are cycles within byte after instr) -;---------------------------------------------------------------------------- -#undef fix -#define fix x1 -#undef data -#define data x2 - -bit7IsSet: - ifrclr phase, USBMINUS ;[62] check phase only if D- changed - lpm ;[63] - in phase, USBIN ;[64] <- phase (one cycle too late) - ori shift, 1 << 7 ;[65] - nop ;[66] -;;;;rjmp bit0AfterSet ; -> [00] == [67] moved block up to save jump -bit0AfterSet: - eor fix, shift ;[00] -#undef fix -#define fix x2 -#undef data -#define data x1 /* we now have result in data, fix is reset to 0xff */ - ifioclr USBIN, USBMINUS ;[01] <--- sample 0 - rjmp bit0IsClr ;[02] - andi shift, ~(7 << 0) ;[03] - breq unstuff0s ;[04] - in phase, USBIN ;[05] <- phase - rjmp bit1AfterSet ;[06] -unstuff0s: - in phase, USBIN ;[06] <- phase (one cycle too late) - andi fix, ~(1 << 0) ;[07] - ifioclr USBIN, USBMINUS ;[00] - ifioset USBIN, USBPLUS ;[01] - rjmp bit0IsClr ;[02] executed if first expr false or second true -jumpToSe0AndStore: - rjmp se0AndStore ;[03] executed only if both bits 0 -bit0IsClr: - ifrset phase, USBMINUS ;[04] check phase only if D- changed - lpm ;[05] - in phase, USBIN ;[06] <- phase (one cycle too late) - ori shift, 1 << 0 ;[07] -bit1AfterClr: - andi phase, USBMASK ;[08] - ifioset USBIN, USBMINUS ;[09] <--- sample 1 - rjmp bit1IsSet ;[10] - breq jumpToSe0AndStore ;[11] - andi shift, ~(7 << 1) ;[12] - in phase, USBIN ;[13] <- phase - breq unstuff1c ;[14] - rjmp bit2AfterClr ;[15] -unstuff1c: - andi fix, ~(1 << 1) ;[16] - nop2 ;[08] - nop2 ;[10] -bit1IsSet: - ifrclr phase, USBMINUS ;[12] check phase only if D- changed - lpm ;[13] - in phase, USBIN ;[14] <- phase (one cycle too late) - ori shift, 1 << 1 ;[15] - nop ;[16] -bit2AfterSet: - ifioclr USBIN, USBMINUS ;[17] <--- sample 2 - rjmp bit2IsClr ;[18] - andi shift, ~(7 << 2) ;[19] - breq unstuff2s ;[20] - in phase, USBIN ;[21] <- phase - rjmp bit3AfterSet ;[22] -unstuff2s: - in phase, USBIN ;[22] <- phase (one cycle too late) - andi fix, ~(1 << 2) ;[23] - nop2 ;[16] - nop2 ;[18] -bit2IsClr: - ifrset phase, USBMINUS ;[20] check phase only if D- changed - lpm ;[21] - in phase, USBIN ;[22] <- phase (one cycle too late) - ori shift, 1 << 2 ;[23] -bit3AfterClr: - st y+, data ;[24] -entryAfterClr: - ifioset USBIN, USBMINUS ;[26] <--- sample 3 - rjmp bit3IsSet ;[27] - andi shift, ~(7 << 3) ;[28] - breq unstuff3c ;[29] - in phase, USBIN ;[30] <- phase - rjmp bit4AfterClr ;[31] -unstuff3c: - in phase, USBIN ;[31] <- phase (one cycle too late) - andi fix, ~(1 << 3) ;[32] - nop2 ;[25] - nop2 ;[27] -bit3IsSet: - ifrclr phase, USBMINUS ;[29] check phase only if D- changed - lpm ;[30] - in phase, USBIN ;[31] <- phase (one cycle too late) - ori shift, 1 << 3 ;[32] -bit4AfterSet: - mov data, fix ;[33] undo this move by swapping defines -#undef fix -#define fix x1 -#undef data -#define data x2 - ifioclr USBIN, USBMINUS ;[34] <--- sample 4 - rjmp bit4IsClr ;[35] - andi shift, ~(7 << 4) ;[36] - breq unstuff4s ;[37] - in phase, USBIN ;[38] <- phase - rjmp bit5AfterSet ;[39] -unstuff4s: - in phase, USBIN ;[39] <- phase (one cycle too late) - andi fix, ~(1 << 4) ;[40] - nop2 ;[33] - nop2 ;[35] -bit4IsClr: - ifrset phase, USBMINUS ;[37] check phase only if D- changed - lpm ;[38] - in phase, USBIN ;[39] <- phase (one cycle too late) - ori shift, 1 << 4 ;[40] -bit5AfterClr: - ser data ;[41] - ifioset USBIN, USBMINUS ;[42] <--- sample 5 - rjmp bit5IsSet ;[43] - andi shift, ~(7 << 5) ;[44] - breq unstuff5c ;[45] - in phase, USBIN ;[46] <- phase - rjmp bit6AfterClr ;[47] -unstuff5c: - in phase, USBIN ;[47] <- phase (one cycle too late) - andi fix, ~(1 << 5) ;[48] - nop2 ;[41] - nop2 ;[43] -bit5IsSet: - ifrclr phase, USBMINUS ;[45] check phase only if D- changed - lpm ;[46] - in phase, USBIN ;[47] <- phase (one cycle too late) - ori shift, 1 << 5 ;[48] -bit6AfterSet: - subi cnt, 1 ;[49] - brcs jumpToOverflow ;[50] - ifioclr USBIN, USBMINUS ;[51] <--- sample 6 - rjmp bit6IsClr ;[52] - andi shift, ~(3 << 6) ;[53] - cpi shift, 2 ;[54] - in phase, USBIN ;[55] <- phase - brlt unstuff6s ;[56] - rjmp bit7AfterSet ;[57] - -jumpToOverflow: - rjmp overflow - -unstuff6s: - andi fix, ~(1 << 6) ;[50] - lpm ;[51] -bit6IsClr: - ifrset phase, USBMINUS ;[54] check phase only if D- changed - lpm ;[55] - in phase, USBIN ;[56] <- phase (one cycle too late) - ori shift, 1 << 6 ;[57] - nop ;[58] -bit7AfterClr: - ifioset USBIN, USBMINUS ;[59] <--- sample 7 - rjmp bit7IsSet ;[60] - andi shift, ~(1 << 7) ;[61] - cpi shift, 4 ;[62] - in phase, USBIN ;[63] <- phase - brlt unstuff7c ;[64] - rjmp bit0AfterClr ;[65] -> [00] == [67] -unstuff7c: - andi fix, ~(1 << 7) ;[58] - nop ;[59] - rjmp bit7IsSet ;[60] - -se0AndStore: - st y+, x1 ;[15/17] cycles after start of byte - rjmp se0 ;[17/19] - -bit7IsClr: - ifrset phase, USBMINUS ;[62] check phase only if D- changed - lpm ;[63] - in phase, USBIN ;[64] <- phase (one cycle too late) - ori shift, 1 << 7 ;[65] - nop ;[66] -;;;;rjmp bit0AfterClr ; -> [00] == [67] moved block up to save jump -bit0AfterClr: - eor fix, shift ;[00] -#undef fix -#define fix x2 -#undef data -#define data x1 /* we now have result in data, fix is reset to 0xff */ - ifioset USBIN, USBMINUS ;[01] <--- sample 0 - rjmp bit0IsSet ;[02] - andi shift, ~(7 << 0) ;[03] - breq unstuff0c ;[04] - in phase, USBIN ;[05] <- phase - rjmp bit1AfterClr ;[06] -unstuff0c: - in phase, USBIN ;[06] <- phase (one cycle too late) - andi fix, ~(1 << 0) ;[07] - ifioclr USBIN, USBMINUS ;[00] - ifioset USBIN, USBPLUS ;[01] - rjmp bit0IsSet ;[02] executed if first expr false or second true - rjmp se0AndStore ;[03] executed only if both bits 0 -bit0IsSet: - ifrclr phase, USBMINUS ;[04] check phase only if D- changed - lpm ;[05] - in phase, USBIN ;[06] <- phase (one cycle too late) - ori shift, 1 << 0 ;[07] -bit1AfterSet: - andi phase, USBMASK ;[08] - ifioclr USBIN, USBMINUS ;[09] <--- sample 1 - rjmp bit1IsClr ;[10] - andi shift, ~(7 << 1) ;[11] - breq unstuff1s ;[12] - in phase, USBIN ;[13] <- phase - nop ;[14] - rjmp bit2AfterSet ;[15] -unstuff1s: - in phase, USBIN ;[14] <- phase (one cycle too late) - andi fix, ~(1 << 1) ;[15] - nop2 ;[08] - nop2 ;[10] -bit1IsClr: - ifrset phase, USBMINUS ;[12] check phase only if D- changed - lpm ;[13] - in phase, USBIN ;[14] <- phase (one cycle too late) - breq se0AndStore ;[15] if we come from unstuff1s, Z bit is never set - ori shift, 1 << 1 ;[16] -bit2AfterClr: - ifioset USBIN, USBMINUS ;[17] <--- sample 2 - rjmp bit2IsSet ;[18] - andi shift, ~(7 << 2) ;[19] - breq unstuff2c ;[20] - in phase, USBIN ;[21] <- phase - rjmp bit3AfterClr ;[22] -unstuff2c: - in phase, USBIN ;[22] <- phase (one cycle too late) - andi fix, ~(1 << 2) ;[23] - nop2 ;[16] - nop2 ;[18] -bit2IsSet: - ifrclr phase, USBMINUS ;[20] check phase only if D- changed - lpm ;[21] - in phase, USBIN ;[22] <- phase (one cycle too late) - ori shift, 1 << 2 ;[23] -bit3AfterSet: - st y+, data ;[24] -entryAfterSet: - ifioclr USBIN, USBMINUS ;[26] <--- sample 3 - rjmp bit3IsClr ;[27] - andi shift, ~(7 << 3) ;[28] - breq unstuff3s ;[29] - in phase, USBIN ;[30] <- phase - rjmp bit4AfterSet ;[31] -unstuff3s: - in phase, USBIN ;[31] <- phase (one cycle too late) - andi fix, ~(1 << 3) ;[32] - nop2 ;[25] - nop2 ;[27] -bit3IsClr: - ifrset phase, USBMINUS ;[29] check phase only if D- changed - lpm ;[30] - in phase, USBIN ;[31] <- phase (one cycle too late) - ori shift, 1 << 3 ;[32] -bit4AfterClr: - mov data, fix ;[33] undo this move by swapping defines -#undef fix -#define fix x1 -#undef data -#define data x2 - ifioset USBIN, USBMINUS ;[34] <--- sample 4 - rjmp bit4IsSet ;[35] - andi shift, ~(7 << 4) ;[36] - breq unstuff4c ;[37] - in phase, USBIN ;[38] <- phase - rjmp bit5AfterClr ;[39] -unstuff4c: - in phase, USBIN ;[39] <- phase (one cycle too late) - andi fix, ~(1 << 4) ;[40] - nop2 ;[33] - nop2 ;[35] -bit4IsSet: - ifrclr phase, USBMINUS ;[37] check phase only if D- changed - lpm ;[38] - in phase, USBIN ;[39] <- phase (one cycle too late) - ori shift, 1 << 4 ;[40] -bit5AfterSet: - ser data ;[41] - ifioclr USBIN, USBMINUS ;[42] <--- sample 5 - rjmp bit5IsClr ;[43] - andi shift, ~(7 << 5) ;[44] - breq unstuff5s ;[45] - in phase, USBIN ;[46] <- phase - rjmp bit6AfterSet ;[47] -unstuff5s: - in phase, USBIN ;[47] <- phase (one cycle too late) - andi fix, ~(1 << 5) ;[48] - nop2 ;[41] - nop2 ;[43] -bit5IsClr: - ifrset phase, USBMINUS ;[45] check phase only if D- changed - lpm ;[46] - in phase, USBIN ;[47] <- phase (one cycle too late) - ori shift, 1 << 5 ;[48] -bit6AfterClr: - subi cnt, 1 ;[49] - brcs overflow ;[50] - ifioset USBIN, USBMINUS ;[51] <--- sample 6 - rjmp bit6IsSet ;[52] - andi shift, ~(3 << 6) ;[53] - cpi shift, 2 ;[54] - in phase, USBIN ;[55] <- phase - brlt unstuff6c ;[56] - rjmp bit7AfterClr ;[57] -unstuff6c: - andi fix, ~(1 << 6) ;[50] - lpm ;[51] -bit6IsSet: - ifrclr phase, USBMINUS ;[54] check phase only if D- changed - lpm ;[55] - in phase, USBIN ;[56] <- phase (one cycle too late) - ori shift, 1 << 6 ;[57] -bit7AfterSet: - ifioclr USBIN, USBMINUS ;[59] <--- sample 7 - rjmp bit7IsClr ;[60] - andi shift, ~(1 << 7) ;[61] - cpi shift, 4 ;[62] - in phase, USBIN ;[63] <- phase - brlt unstuff7s ;[64] - rjmp bit0AfterSet ;[65] -> [00] == [67] -unstuff7s: - andi fix, ~(1 << 7) ;[58] - nop ;[59] - rjmp bit7IsClr ;[60] - -macro POP_STANDARD ; 14 cycles - pop r0 - pop cnt - pop x3 - pop x2 - pop x1 - pop shift - pop YH - endm -macro POP_RETI ; 5 cycles - pop YL - out SREG, YL - pop YL - endm - -#include "asmcommon.inc" - -;---------------------------------------------------------------------------- -; Transmitting data -;---------------------------------------------------------------------------- - -txByteLoop: -txBitloop: -stuffN1Delay: ; [03] - ror shift ;[-5] [11] [63] - brcc doExorN1 ;[-4] [64] - subi x3, 1 ;[-3] - brne commonN1 ;[-2] - lsl shift ;[-1] compensate ror after rjmp stuffDelay - nop ;[00] stuffing consists of just waiting 8 cycles - rjmp stuffN1Delay ;[01] after ror, C bit is reliably clear - -sendNakAndReti: - ldi cnt, USBPID_NAK ;[-19] - rjmp sendCntAndReti ;[-18] -sendAckAndReti: - ldi cnt, USBPID_ACK ;[-17] -sendCntAndReti: - mov r0, cnt ;[-16] - ldi YL, 0 ;[-15] R0 address is 0 - ldi YH, 0 ;[-14] - ldi cnt, 2 ;[-13] -; rjmp usbSendAndReti fallthrough - -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) or USBOUT = 0x01 -; K = (D+ = 1), (D- = 0) or USBOUT = 0x02 -; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles) - -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte -;uses: x1...x3, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x3 = bitstuff cnt] -;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction) -usbSendAndReti: - in x2, USBDDR ;[-10] 10 cycles until SOP - ori x2, USBMASK ;[-9] - sbi USBOUT, USBMINUS ;[-8] prepare idle state; D+ and D- must have been 0 (no pullups) - out USBDDR, x2 ;[-6] <--- acquire bus - in x1, USBOUT ;[-5] port mirror for tx loop - ldi shift, 0x40 ;[-4] sync byte is first byte sent (we enter loop after ror) - ldi x2, USBMASK ;[-3] -doExorN1: - eor x1, x2 ;[-2] [06] [62] - ldi x3, 6 ;[-1] [07] [63] -commonN1: -stuffN2Delay: - out USBOUT, x1 ;[00] [08] [64] <--- set bit - ror shift ;[01] - brcc doExorN2 ;[02] - subi x3, 1 ;[03] - brne commonN2 ;[04] - lsl shift ;[05] compensate ror after rjmp stuffDelay - rjmp stuffN2Delay ;[06] after ror, C bit is reliably clear -doExorN2: - eor x1, x2 ;[04] [12] - ldi x3, 6 ;[05] [13] -commonN2: - nop2 ;[06] [14] - subi cnt, 171 ;[08] [16] trick: (3 * 171) & 0xff = 1 - out USBOUT, x1 ;[09] [17] <--- set bit - brcs txBitloop ;[10] [27] [44] - -stuff6Delay: - ror shift ;[45] [53] - brcc doExor6 ;[46] - subi x3, 1 ;[47] - brne common6 ;[48] - lsl shift ;[49] compensate ror after rjmp stuffDelay - nop ;[50] stuffing consists of just waiting 8 cycles - rjmp stuff6Delay ;[51] after ror, C bit is reliably clear -doExor6: - eor x1, x2 ;[48] [56] - ldi x3, 6 ;[49] -common6: -stuff7Delay: - ror shift ;[50] [58] - out USBOUT, x1 ;[51] <--- set bit - brcc doExor7 ;[52] - subi x3, 1 ;[53] - brne common7 ;[54] - lsl shift ;[55] compensate ror after rjmp stuffDelay - rjmp stuff7Delay ;[56] after ror, C bit is reliably clear -doExor7: - eor x1, x2 ;[54] [62] - ldi x3, 6 ;[55] -common7: - ld shift, y+ ;[56] - nop ;[58] - tst cnt ;[59] - out USBOUT, x1 ;[60] [00]<--- set bit - brne txByteLoop ;[61] [01] -;make SE0: - cbr x1, USBMASK ;[02] prepare SE0 [spec says EOP may be 15 to 18 cycles] - lds x2, usbNewDeviceAddr;[03] - lsl x2 ;[05] we compare with left shifted address - subi YL, 2 + 0 ;[06] Only assign address on data packets, not ACK/NAK in r0 - sbci YH, 0 ;[07] - out USBOUT, x1 ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - breq skipAddrAssign ;[01] - sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer -skipAddrAssign: -;end of usbDeviceAddress transfer - ldi x2, 1< 0) - echo "$s\n"; - } -} - -function printBit($isAfterSet, $bitNum) -{ - ob_start(); - if($isAfterSet){ -?> - ifioclr USBIN, USBMINUS ;[00] <--- sample - rjmp bit#IsClr ;[01] - andi shift, ~(7 << #) ;[02] - breq unstuff#s ;[03] - in phase, USBIN ;[04] <- phase - rjmp bit@AfterSet ;[05] -unstuff#s: - in phase, USBIN ;[05] <- phase (one cycle too late) - andi fix, ~(1 << #) ;[06] - nop2 ;[-1] - nop2 ;[01] -bit#IsClr: - ifrset phase, USBMINUS ;[03] check phase only if D- changed - lpm ;[04] - in phase, USBIN ;[05] <- phase (one cycle too late) - ori shift, 1 << # ;[06] - - ifioset USBIN, USBMINUS ;[00] <--- sample - rjmp bit#IsSet ;[01] - andi shift, ~(7 << #) ;[02] - breq unstuff#c ;[03] - in phase, USBIN ;[04] <- phase - rjmp bit@AfterClr ;[05] -unstuff#c: - in phase, USBIN ;[05] <- phase (one cycle too late) - andi fix, ~(1 << #) ;[06] - nop2 ;[-1] - nop2 ;[01] -bit#IsSet: - ifrclr phase, USBMINUS ;[03] check phase only if D- changed - lpm ;[04] - in phase, USBIN ;[05] <- phase (one cycle too late) - ori shift, 1 << # ;[06] - -*****************************************************************************/ diff --git a/tools/avrusb/usbdrv/usbdrvasm15.inc b/tools/avrusb/usbdrv/usbdrvasm15.inc deleted file mode 100644 index 1016124..0000000 --- a/tools/avrusb/usbdrv/usbdrvasm15.inc +++ /dev/null @@ -1,423 +0,0 @@ -/* Name: usbdrvasm15.inc - * Project: AVR USB driver - * Author: contributed by V. Bosch - * Creation Date: 2007-08-06 - * Tabsize: 4 - * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * Revision: $Id: usbdrvasm15.inc 692 2008-11-07 15:07:40Z cs $ - */ - -/* Do not link this file! Link usbdrvasm.S instead, which includes the - * appropriate implementation! - */ - -/* -General Description: -This file is the 15 MHz version of the asssembler part of the USB driver. It -requires a 15 MHz crystal (not a ceramic resonator and not a calibrated RC -oscillator). - -See usbdrv.h for a description of the entire driver. - -Since almost all of this code is timing critical, don't change unless you -really know what you are doing! Many parts require not only a maximum number -of CPU cycles, but even an exact number of cycles! -*/ - -;max stack usage: [ret(2), YL, SREG, YH, bitcnt, shift, x1, x2, x3, x4, cnt] = 12 bytes -;nominal frequency: 15 MHz -> 10.0 cycles per bit, 80.0 cycles per byte -; Numbers in brackets are clocks counted from center of last sync bit -; when instruction starts - -;---------------------------------------------------------------------------- -; order of registers pushed: -; YL, SREG [sofError] YH, shift, x1, x2, x3, bitcnt, cnt, x4 -;---------------------------------------------------------------------------- -USB_INTR_VECTOR: - push YL ;2 push only what is necessary to sync with edge ASAP - in YL, SREG ;1 - push YL ;2 -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -; -; sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -; sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -;------------------------------------------------------------------------------- -; The following code results in a sampling window of < 1/4 bit -; which meets the spec. -;------------------------------------------------------------------------------- -waitForK: ;- - sbis USBIN, USBMINUS ;1 [00] <-- sample - rjmp foundK ;2 [01] - sbis USBIN, USBMINUS ; <-- sample - rjmp foundK - sbis USBIN, USBMINUS ; <-- sample - rjmp foundK - sbis USBIN, USBMINUS ; <-- sample - rjmp foundK - sbis USBIN, USBMINUS ; <-- sample - rjmp foundK - sbis USBIN, USBMINUS ; <-- sample - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -;------------------------------------------------------------------------------ -; {3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for -; center sampling] -; we have 1 bit time for setup purposes, then sample again. -; Numbers in brackets are cycles from center of first sync (double K) -; bit after the instruction -;------------------------------------------------------------------------------ -foundK: ;- [02] - lds YL, usbInputBufOffset;2 [03+04] tx loop - push YH ;2 [05+06] - clr YH ;1 [07] - subi YL, lo8(-(usbRxBuf)) ;1 [08] [rx loop init] - sbci YH, hi8(-(usbRxBuf)) ;1 [09] [rx loop init] - push shift ;2 [10+11] - ser shift ;1 [12] - sbis USBIN, USBMINUS ;1 [-1] [13] <--sample:we want two bits K (sample 1 cycle too early) - rjmp haveTwoBitsK ;2 [00] [14] - pop shift ;2 [15+16] undo the push from before - pop YH ;2 [17+18] undo the push from before - rjmp waitForK ;2 [19+20] this was not the end of sync, retry -; The entire loop from waitForK until rjmp waitForK above must not exceed two -; bit times (= 20 cycles). - -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -haveTwoBitsK: ;- [01] - push x1 ;2 [02+03] - push x2 ;2 [04+05] - push x3 ;2 [06+07] - push bitcnt ;2 [08+09] - in x1, USBIN ;1 [00] [10] <-- sample bit 0 - bst x1, USBMINUS ;1 [01] - bld shift, 0 ;1 [02] - push cnt ;2 [03+04] - ldi cnt, USB_BUFSIZE ;1 [05] - push x4 ;2 [06+07] tx loop - rjmp rxLoop ;2 [08] -;---------------------------------------------------------------------------- -; Receiver loop (numbers in brackets are cycles within byte after instr) -;---------------------------------------------------------------------------- -unstuff0: ;- [07] (branch taken) - andi x3, ~0x01 ;1 [08] - mov x1, x2 ;1 [09] x2 contains last sampled (stuffed) bit - in x2, USBIN ;1 [00] [10] <-- sample bit 1 again - andi x2, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 1 - ori shift, 0x01 ;1 [03] 0b00000001 - nop ;1 [04] - rjmp didUnstuff0 ;2 [05] -;----------------------------------------------------- -unstuff1: ;- [05] (branch taken) - mov x2, x1 ;1 [06] x1 contains last sampled (stuffed) bit - andi x3, ~0x02 ;1 [07] - ori shift, 0x02 ;1 [08] 0b00000010 - nop ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample bit 2 again - andi x1, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 2 - rjmp didUnstuff1 ;2 [03] -;----------------------------------------------------- -unstuff2: ;- [05] (branch taken) - andi x3, ~0x04 ;1 [06] - ori shift, 0x04 ;1 [07] 0b00000100 - mov x1, x2 ;1 [08] x2 contains last sampled (stuffed) bit - nop ;1 [09] - in x2, USBIN ;1 [00] [10] <-- sample bit 3 - andi x2, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 3 - rjmp didUnstuff2 ;2 [03] -;----------------------------------------------------- -unstuff3: ;- [00] [10] (branch taken) - in x2, USBIN ;1 [01] [11] <-- sample stuffed bit 3 one cycle too late - andi x2, USBMASK ;1 [02] - breq se0Hop ;1 [03] SE0 check for stuffed bit 3 - andi x3, ~0x08 ;1 [04] - ori shift, 0x08 ;1 [05] 0b00001000 - rjmp didUnstuff3 ;2 [06] -;---------------------------------------------------------------------------- -; extra jobs done during bit interval: -; -; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs], -; overflow check, jump to the head of rxLoop -; bit 1: SE0 check -; bit 2: SE0 check, recovery from delay [bit 0 tasks took too long] -; bit 3: SE0 check, recovery from delay [bit 0 tasks took too long] -; bit 4: SE0 check, none -; bit 5: SE0 check, none -; bit 6: SE0 check, none -; bit 7: SE0 check, reconstruct: x3 is 0 at bit locations we changed, 1 at others -;---------------------------------------------------------------------------- -rxLoop: ;- [09] - in x2, USBIN ;1 [00] [10] <-- sample bit 1 (or possibly bit 0 stuffed) - andi x2, USBMASK ;1 [01] - brne SkipSe0Hop ;1 [02] -se0Hop: ;- [02] - rjmp se0 ;2 [03] SE0 check for bit 1 -SkipSe0Hop: ;- [03] - ser x3 ;1 [04] - andi shift, 0xf9 ;1 [05] 0b11111001 - breq unstuff0 ;1 [06] -didUnstuff0: ;- [06] - eor x1, x2 ;1 [07] - bst x1, USBMINUS ;1 [08] - bld shift, 1 ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample bit 2 (or possibly bit 1 stuffed) - andi x1, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 2 - andi shift, 0xf3 ;1 [03] 0b11110011 - breq unstuff1 ;1 [04] do remaining work for bit 1 -didUnstuff1: ;- [04] - eor x2, x1 ;1 [05] - bst x2, USBMINUS ;1 [06] - bld shift, 2 ;1 [07] - nop2 ;2 [08+09] - in x2, USBIN ;1 [00] [10] <-- sample bit 3 (or possibly bit 2 stuffed) - andi x2, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 3 - andi shift, 0xe7 ;1 [03] 0b11100111 - breq unstuff2 ;1 [04] -didUnstuff2: ;- [04] - eor x1, x2 ;1 [05] - bst x1, USBMINUS ;1 [06] - bld shift, 3 ;1 [07] -didUnstuff3: ;- [07] - andi shift, 0xcf ;1 [08] 0b11001111 - breq unstuff3 ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample bit 4 - andi x1, USBMASK ;1 [01] - breq se0Hop ;1 [02] SE0 check for bit 4 - eor x2, x1 ;1 [03] - bst x2, USBMINUS ;1 [04] - bld shift, 4 ;1 [05] -didUnstuff4: ;- [05] - andi shift, 0x9f ;1 [06] 0b10011111 - breq unstuff4 ;1 [07] - nop2 ;2 [08+09] - in x2, USBIN ;1 [00] [10] <-- sample bit 5 - andi x2, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for bit 5 - eor x1, x2 ;1 [03] - bst x1, USBMINUS ;1 [04] - bld shift, 5 ;1 [05] -didUnstuff5: ;- [05] - andi shift, 0x3f ;1 [06] 0b00111111 - breq unstuff5 ;1 [07] - nop2 ;2 [08+09] - in x1, USBIN ;1 [00] [10] <-- sample bit 6 - andi x1, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for bit 6 - eor x2, x1 ;1 [03] - bst x2, USBMINUS ;1 [04] - bld shift, 6 ;1 [05] -didUnstuff6: ;- [05] - cpi shift, 0x02 ;1 [06] 0b00000010 - brlo unstuff6 ;1 [07] - nop2 ;2 [08+09] - in x2, USBIN ;1 [00] [10] <-- sample bit 7 - andi x2, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for bit 7 - eor x1, x2 ;1 [03] - bst x1, USBMINUS ;1 [04] - bld shift, 7 ;1 [05] -didUnstuff7: ;- [05] - cpi shift, 0x04 ;1 [06] 0b00000100 - brlo unstuff7 ;1 [07] - eor x3, shift ;1 [08] reconstruct: x3 is 0 at bit locations we changed, 1 at others - nop ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample bit 0 - st y+, x3 ;2 [01+02] store data - eor x2, x1 ;1 [03] - bst x2, USBMINUS ;1 [04] - bld shift, 0 ;1 [05] - subi cnt, 1 ;1 [06] - brcs overflow ;1 [07] - rjmp rxLoop ;2 [08] -;----------------------------------------------------- -unstuff4: ;- [08] - andi x3, ~0x10 ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 4 - andi x1, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for stuffed bit 4 - ori shift, 0x10 ;1 [03] - rjmp didUnstuff4 ;2 [04] -;----------------------------------------------------- -unstuff5: ;- [08] - ori shift, 0x20 ;1 [09] - in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 5 - andi x2, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for stuffed bit 5 - andi x3, ~0x20 ;1 [03] - rjmp didUnstuff5 ;2 [04] -;----------------------------------------------------- -unstuff6: ;- [08] - andi x3, ~0x40 ;1 [09] - in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 6 - andi x1, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for stuffed bit 6 - ori shift, 0x40 ;1 [03] - rjmp didUnstuff6 ;2 [04] -;----------------------------------------------------- -unstuff7: ;- [08] - andi x3, ~0x80 ;1 [09] - in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 7 - andi x2, USBMASK ;1 [01] - breq se0 ;1 [02] SE0 check for stuffed bit 7 - ori shift, 0x80 ;1 [03] - rjmp didUnstuff7 ;2 [04] - -macro POP_STANDARD ; 16 cycles - pop x4 - pop cnt - pop bitcnt - pop x3 - pop x2 - pop x1 - pop shift - pop YH - endm -macro POP_RETI ; 5 cycles - pop YL - out SREG, YL - pop YL - endm - -#include "asmcommon.inc" - -;--------------------------------------------------------------------------- -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) -; K = (D+ = 1), (D- = 0) -; Spec allows 7.5 bit times from EOP to SOP for replies -;--------------------------------------------------------------------------- -bitstuffN: ;- [04] - eor x1, x4 ;1 [05] - clr x2 ;1 [06] - nop ;1 [07] - rjmp didStuffN ;1 [08] -;--------------------------------------------------------------------------- -bitstuff6: ;- [04] - eor x1, x4 ;1 [05] - clr x2 ;1 [06] - rjmp didStuff6 ;1 [07] -;--------------------------------------------------------------------------- -bitstuff7: ;- [02] - eor x1, x4 ;1 [03] - clr x2 ;1 [06] - nop ;1 [05] - rjmp didStuff7 ;1 [06] -;--------------------------------------------------------------------------- -sendNakAndReti: ;- [-19] - ldi x3, USBPID_NAK ;1 [-18] - rjmp sendX3AndReti ;1 [-17] -;--------------------------------------------------------------------------- -sendAckAndReti: ;- [-17] - ldi cnt, USBPID_ACK ;1 [-16] -sendCntAndReti: ;- [-16] - mov x3, cnt ;1 [-15] -sendX3AndReti: ;- [-15] - ldi YL, 20 ;1 [-14] x3==r20 address is 20 - ldi YH, 0 ;1 [-13] - ldi cnt, 2 ;1 [-12] -; rjmp usbSendAndReti fallthrough -;--------------------------------------------------------------------------- -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] -;uses: x1...x4, btcnt, shift, cnt, Y -;Numbers in brackets are time since first bit of sync pattern is sent -;We need not to match the transfer rate exactly because the spec demands -;only 1.5% precision anyway. -usbSendAndReti: ;- [-13] 13 cycles until SOP - in x2, USBDDR ;1 [-12] - ori x2, USBMASK ;1 [-11] - sbi USBOUT, USBMINUS ;2 [-09-10] prepare idle state; D+ and D- must have been 0 (no pullups) - in x1, USBOUT ;1 [-08] port mirror for tx loop - out USBDDR, x2 ;1 [-07] <- acquire bus - ; need not init x2 (bitstuff history) because sync starts with 0 - ldi x4, USBMASK ;1 [-06] exor mask - ldi shift, 0x80 ;1 [-05] sync byte is first byte sent - ldi bitcnt, 6 ;1 [-04] -txBitLoop: ;- [-04] [06] - sbrs shift, 0 ;1 [-03] [07] - eor x1, x4 ;1 [-02] [08] - ror shift ;1 [-01] [09] -didStuffN: ;- [09] - out USBOUT, x1 ;1 [00] [10] <-- out N - ror x2 ;1 [01] - cpi x2, 0xfc ;1 [02] - brcc bitstuffN ;1 [03] - dec bitcnt ;1 [04] - brne txBitLoop ;1 [05] - sbrs shift, 0 ;1 [06] - eor x1, x4 ;1 [07] - ror shift ;1 [08] -didStuff6: ;- [08] - nop ;1 [09] - out USBOUT, x1 ;1 [00] [10] <-- out 6 - ror x2 ;1 [01] - cpi x2, 0xfc ;1 [02] - brcc bitstuff6 ;1 [03] - sbrs shift, 0 ;1 [04] - eor x1, x4 ;1 [05] - ror shift ;1 [06] - ror x2 ;1 [07] -didStuff7: ;- [07] - ldi bitcnt, 6 ;1 [08] - cpi x2, 0xfc ;1 [09] - out USBOUT, x1 ;1 [00] [10] <-- out 7 - brcc bitstuff7 ;1 [01] - ld shift, y+ ;2 [02+03] - dec cnt ;1 [04] - brne txBitLoop ;1 [05] -makeSE0: - cbr x1, USBMASK ;1 [06] prepare SE0 [spec says EOP may be 19 to 23 cycles] - lds x2, usbNewDeviceAddr;2 [07+08] - lsl x2 ;1 [09] we compare with left shifted address -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - out USBOUT, x1 ;1 [00] [10] <-- out SE0-- from now 2 bits==20 cycl. until bus idle - subi YL, 20 + 2 ;1 [01] Only assign address on data packets, not ACK/NAK in x3 - sbci YH, 0 ;1 [02] - breq skipAddrAssign ;1 [03] - sts usbDeviceAddr, x2 ;2 [04+05] if not skipped: SE0 is one cycle longer -;---------------------------------------------------------------------------- -;end of usbDeviceAddress transfer -skipAddrAssign: ;- [03/04] - ldi x2, 1< 10.6666666 cycles per bit, 85.333333333 cycles per byte -; Numbers in brackets are clocks counted from center of last sync bit -; when instruction starts - -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt - push YL ;[-25] push only what is necessary to sync with edge ASAP - in YL, SREG ;[-23] - push YL ;[-22] - push YH ;[-20] -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of < 1/4 bit which meets the spec. - sbis USBIN, USBMINUS ;[-15] - rjmp foundK ;[-14] - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -foundK: ;[-12] -;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling] -;we have 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push bitcnt ;[-12] -; [---] ;[-11] - lds YL, usbInputBufOffset;[-10] -; [---] ;[-9] - clr YH ;[-8] - subi YL, lo8(-(usbRxBuf));[-7] [rx loop init] - sbci YH, hi8(-(usbRxBuf));[-6] [rx loop init] - push shift ;[-5] -; [---] ;[-4] - ldi bitcnt, 0x55 ;[-3] [rx loop init] - sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early) - rjmp haveTwoBitsK ;[-1] - pop shift ;[0] undo the push from before - pop bitcnt ;[2] undo the push from before - rjmp waitForK ;[4] this was not the end of sync, retry -; The entire loop from waitForK until rjmp waitForK above must not exceed two -; bit times (= 21 cycles). - -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -haveTwoBitsK: - push x1 ;[1] - push x2 ;[3] - push x3 ;[5] - ldi shift, 0 ;[7] - ldi x3, 1<<4 ;[8] [rx loop init] first sample is inverse bit, compensate that - push x4 ;[9] == leap - - in x1, USBIN ;[11] <-- sample bit 0 - andi x1, USBMASK ;[12] - bst x1, USBMINUS ;[13] - bld shift, 7 ;[14] - push cnt ;[15] - ldi leap, 0 ;[17] [rx loop init] - ldi cnt, USB_BUFSIZE;[18] [rx loop init] - rjmp rxbit1 ;[19] arrives at [21] - -;---------------------------------------------------------------------------- -; Receiver loop (numbers in brackets are cycles within byte after instr) -;---------------------------------------------------------------------------- - -unstuff6: - andi x2, USBMASK ;[03] - ori x3, 1<<6 ;[04] will not be shifted any more - andi shift, ~0x80;[05] - mov x1, x2 ;[06] sampled bit 7 is actually re-sampled bit 6 - subi leap, 3 ;[07] since this is a short (10 cycle) bit, enforce leap bit - rjmp didUnstuff6 ;[08] - -unstuff7: - ori x3, 1<<7 ;[09] will not be shifted any more - in x2, USBIN ;[00] [10] re-sample bit 7 - andi x2, USBMASK ;[01] - andi shift, ~0x80;[02] - subi leap, 3 ;[03] since this is a short (10 cycle) bit, enforce leap bit - rjmp didUnstuff7 ;[04] - -unstuffEven: - ori x3, 1<<6 ;[09] will be shifted right 6 times for bit 0 - in x1, USBIN ;[00] [10] - andi shift, ~0x80;[01] - andi x1, USBMASK ;[02] - breq se0 ;[03] - subi leap, 3 ;[04] since this is a short (10 cycle) bit, enforce leap bit - nop ;[05] - rjmp didUnstuffE ;[06] - -unstuffOdd: - ori x3, 1<<5 ;[09] will be shifted right 4 times for bit 1 - in x2, USBIN ;[00] [10] - andi shift, ~0x80;[01] - andi x2, USBMASK ;[02] - breq se0 ;[03] - subi leap, 3 ;[04] since this is a short (10 cycle) bit, enforce leap bit - nop ;[05] - rjmp didUnstuffO ;[06] - -rxByteLoop: - andi x1, USBMASK ;[03] - eor x2, x1 ;[04] - subi leap, 1 ;[05] - brpl skipLeap ;[06] - subi leap, -3 ;1 one leap cycle every 3rd byte -> 85 + 1/3 cycles per byte - nop ;1 -skipLeap: - subi x2, 1 ;[08] - ror shift ;[09] -didUnstuff6: - cpi shift, 0xfc ;[10] - in x2, USBIN ;[00] [11] <-- sample bit 7 - brcc unstuff6 ;[01] - andi x2, USBMASK ;[02] - eor x1, x2 ;[03] - subi x1, 1 ;[04] - ror shift ;[05] -didUnstuff7: - cpi shift, 0xfc ;[06] - brcc unstuff7 ;[07] - eor x3, shift ;[08] reconstruct: x3 is 1 at bit locations we changed, 0 at others - st y+, x3 ;[09] store data -rxBitLoop: - in x1, USBIN ;[00] [11] <-- sample bit 0/2/4 - andi x1, USBMASK ;[01] - eor x2, x1 ;[02] - andi x3, 0x3f ;[03] topmost two bits reserved for 6 and 7 - subi x2, 1 ;[04] - ror shift ;[05] - cpi shift, 0xfc ;[06] - brcc unstuffEven ;[07] -didUnstuffE: - lsr x3 ;[08] - lsr x3 ;[09] -rxbit1: - in x2, USBIN ;[00] [10] <-- sample bit 1/3/5 - andi x2, USBMASK ;[01] - breq se0 ;[02] - eor x1, x2 ;[03] - subi x1, 1 ;[04] - ror shift ;[05] - cpi shift, 0xfc ;[06] - brcc unstuffOdd ;[07] -didUnstuffO: - subi bitcnt, 0xab;[08] == addi 0x55, 0x55 = 0x100/3 - brcs rxBitLoop ;[09] - - subi cnt, 1 ;[10] - in x1, USBIN ;[00] [11] <-- sample bit 6 - brcc rxByteLoop ;[01] - rjmp overflow - -macro POP_STANDARD ; 14 cycles - pop cnt - pop x4 - pop x3 - pop x2 - pop x1 - pop shift - pop bitcnt - endm -macro POP_RETI ; 7 cycles - pop YH - pop YL - out SREG, YL - pop YL - endm - -#include "asmcommon.inc" - -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) -; K = (D+ = 1), (D- = 0) -; Spec allows 7.5 bit times from EOP to SOP for replies - -bitstuffN: - eor x1, x4 ;[5] - ldi x2, 0 ;[6] - nop2 ;[7] - nop ;[9] - out USBOUT, x1 ;[10] <-- out - rjmp didStuffN ;[0] - -bitstuff6: - eor x1, x4 ;[5] - ldi x2, 0 ;[6] Carry is zero due to brcc - rol shift ;[7] compensate for ror shift at branch destination - rjmp didStuff6 ;[8] - -bitstuff7: - ldi x2, 0 ;[2] Carry is zero due to brcc - rjmp didStuff7 ;[3] - - -sendNakAndReti: - ldi x3, USBPID_NAK ;[-18] - rjmp sendX3AndReti ;[-17] -sendAckAndReti: - ldi cnt, USBPID_ACK ;[-17] -sendCntAndReti: - mov x3, cnt ;[-16] -sendX3AndReti: - ldi YL, 20 ;[-15] x3==r20 address is 20 - ldi YH, 0 ;[-14] - ldi cnt, 2 ;[-13] -; rjmp usbSendAndReti fallthrough - -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] -;uses: x1...x4, btcnt, shift, cnt, Y -;Numbers in brackets are time since first bit of sync pattern is sent -;We don't match the transfer rate exactly (don't insert leap cycles every third -;byte) because the spec demands only 1.5% precision anyway. -usbSendAndReti: ; 12 cycles until SOP - in x2, USBDDR ;[-12] - ori x2, USBMASK ;[-11] - sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) - in x1, USBOUT ;[-8] port mirror for tx loop - out USBDDR, x2 ;[-7] <- acquire bus -; need not init x2 (bitstuff history) because sync starts with 0 - ldi x4, USBMASK ;[-6] exor mask - ldi shift, 0x80 ;[-5] sync byte is first byte sent -txByteLoop: - ldi bitcnt, 0x35 ;[-4] [6] binary 0011 0101 -txBitLoop: - sbrs shift, 0 ;[-3] [7] - eor x1, x4 ;[-2] [8] - out USBOUT, x1 ;[-1] [9] <-- out N - ror shift ;[0] [10] - ror x2 ;[1] -didStuffN: - cpi x2, 0xfc ;[2] - brcc bitstuffN ;[3] - lsr bitcnt ;[4] - brcc txBitLoop ;[5] - brne txBitLoop ;[6] - - sbrs shift, 0 ;[7] - eor x1, x4 ;[8] -didStuff6: - out USBOUT, x1 ;[-1] [9] <-- out 6 - ror shift ;[0] [10] - ror x2 ;[1] - cpi x2, 0xfc ;[2] - brcc bitstuff6 ;[3] - ror shift ;[4] -didStuff7: - ror x2 ;[5] - sbrs x2, 7 ;[6] - eor x1, x4 ;[7] - nop ;[8] - cpi x2, 0xfc ;[9] - out USBOUT, x1 ;[-1][10] <-- out 7 - brcc bitstuff7 ;[0] [11] - ld shift, y+ ;[1] - dec cnt ;[3] - brne txByteLoop ;[4] -;make SE0: - cbr x1, USBMASK ;[5] prepare SE0 [spec says EOP may be 21 to 25 cycles] - lds x2, usbNewDeviceAddr;[6] - lsl x2 ;[8] we compare with left shifted address - subi YL, 20 + 2 ;[9] Only assign address on data packets, not ACK/NAK in x3 - sbci YH, 0 ;[10] - out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - breq skipAddrAssign ;[0] - sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer -skipAddrAssign: -;end of usbDeviceAddress transfer - ldi x2, 1< max 52 cycles interrupt disable -;max stack usage: [ret(2), r0, SREG, YL, YH, shift, x1, x2, x3, x4, cnt] = 12 bytes -;nominal frequency: 16.5 MHz -> 11 cycles per bit -; 16.3125 MHz < F_CPU < 16.6875 MHz (+/- 1.1%) -; Numbers in brackets are clocks counted from center of last sync bit -; when instruction starts - - -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG [sofError], r0, YH, shift, x1, x2, x3, x4, cnt - push YL ;[-23] push only what is necessary to sync with edge ASAP - in YL, SREG ;[-21] - push YL ;[-20] -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of < 1/4 bit which meets the spec. - sbis USBIN, USBMINUS ;[-15] - rjmp foundK ;[-14] - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -foundK: ;[-12] -;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling] -;we have 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push r0 ;[-12] -; [---] ;[-11] - push YH ;[-10] -; [---] ;[-9] - lds YL, usbInputBufOffset;[-8] -; [---] ;[-7] - clr YH ;[-6] - subi YL, lo8(-(usbRxBuf));[-5] [rx loop init] - sbci YH, hi8(-(usbRxBuf));[-4] [rx loop init] - mov r0, x2 ;[-3] [rx loop init] - sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early) - rjmp haveTwoBitsK ;[-1] - pop YH ;[0] undo the pushes from before - pop r0 ;[2] - rjmp waitForK ;[4] this was not the end of sync, retry -; The entire loop from waitForK until rjmp waitForK above must not exceed two -; bit times (= 22 cycles). - -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -haveTwoBitsK: ;[1] - push shift ;[1] - push x1 ;[3] - push x2 ;[5] - push x3 ;[7] - ldi shift, 0xff ;[9] [rx loop init] - ori x3, 0xff ;[10] [rx loop init] == ser x3, clear zero flag - - in x1, USBIN ;[11] <-- sample bit 0 - bst x1, USBMINUS ;[12] - bld shift, 0 ;[13] - push x4 ;[14] == phase -; [---] ;[15] - push cnt ;[16] -; [---] ;[17] - ldi phase, 0 ;[18] [rx loop init] - ldi cnt, USB_BUFSIZE;[19] [rx loop init] - rjmp rxbit1 ;[20] -; [---] ;[21] - -;---------------------------------------------------------------------------- -; Receiver loop (numbers in brackets are cycles within byte after instr) -;---------------------------------------------------------------------------- -/* -byte oriented operations done during loop: -bit 0: store data -bit 1: SE0 check -bit 2: overflow check -bit 3: catch up -bit 4: rjmp to achieve conditional jump range -bit 5: PLL -bit 6: catch up -bit 7: jump, fixup bitstuff -; 87 [+ 2] cycles ------------------------------------------------------------------- -*/ -continueWithBit5: - in x2, USBIN ;[055] <-- bit 5 - eor r0, x2 ;[056] - or phase, r0 ;[057] - sbrc phase, USBMINUS ;[058] - lpm ;[059] optional nop3; modifies r0 - in phase, USBIN ;[060] <-- phase - eor x1, x2 ;[061] - bst x1, USBMINUS ;[062] - bld shift, 5 ;[063] - andi shift, 0x3f ;[064] - in x1, USBIN ;[065] <-- bit 6 - breq unstuff5 ;[066] *** unstuff escape - eor phase, x1 ;[067] - eor x2, x1 ;[068] - bst x2, USBMINUS ;[069] - bld shift, 6 ;[070] -didUnstuff6: ;[ ] - in r0, USBIN ;[071] <-- phase - cpi shift, 0x02 ;[072] - brlo unstuff6 ;[073] *** unstuff escape -didUnstuff5: ;[ ] - nop2 ;[074] -; [---] ;[075] - in x2, USBIN ;[076] <-- bit 7 - eor x1, x2 ;[077] - bst x1, USBMINUS ;[078] - bld shift, 7 ;[079] -didUnstuff7: ;[ ] - eor r0, x2 ;[080] - or phase, r0 ;[081] - in r0, USBIN ;[082] <-- phase - cpi shift, 0x04 ;[083] - brsh rxLoop ;[084] -; [---] ;[085] -unstuff7: ;[ ] - andi x3, ~0x80 ;[085] - ori shift, 0x80 ;[086] - in x2, USBIN ;[087] <-- sample stuffed bit 7 - nop ;[088] - rjmp didUnstuff7 ;[089] -; [---] ;[090] - ;[080] - -unstuff5: ;[067] - eor phase, x1 ;[068] - andi x3, ~0x20 ;[069] - ori shift, 0x20 ;[070] - in r0, USBIN ;[071] <-- phase - mov x2, x1 ;[072] - nop ;[073] - nop2 ;[074] -; [---] ;[075] - in x1, USBIN ;[076] <-- bit 6 - eor r0, x1 ;[077] - or phase, r0 ;[078] - eor x2, x1 ;[079] - bst x2, USBMINUS ;[080] - bld shift, 6 ;[081] no need to check bitstuffing, we just had one - in r0, USBIN ;[082] <-- phase - rjmp didUnstuff5 ;[083] -; [---] ;[084] - ;[074] - -unstuff6: ;[074] - andi x3, ~0x40 ;[075] - in x1, USBIN ;[076] <-- bit 6 again - ori shift, 0x40 ;[077] - nop2 ;[078] -; [---] ;[079] - rjmp didUnstuff6 ;[080] -; [---] ;[081] - ;[071] - -unstuff0: ;[013] - eor r0, x2 ;[014] - or phase, r0 ;[015] - andi x2, USBMASK ;[016] check for SE0 - in r0, USBIN ;[017] <-- phase - breq didUnstuff0 ;[018] direct jump to se0 would be too long - andi x3, ~0x01 ;[019] - ori shift, 0x01 ;[020] - mov x1, x2 ;[021] mov existing sample - in x2, USBIN ;[022] <-- bit 1 again - rjmp didUnstuff0 ;[023] -; [---] ;[024] - ;[014] - -unstuff1: ;[024] - eor r0, x1 ;[025] - or phase, r0 ;[026] - andi x3, ~0x02 ;[027] - in r0, USBIN ;[028] <-- phase - ori shift, 0x02 ;[029] - mov x2, x1 ;[030] - rjmp didUnstuff1 ;[031] -; [---] ;[032] - ;[022] - -unstuff2: ;[035] - eor r0, x2 ;[036] - or phase, r0 ;[037] - andi x3, ~0x04 ;[038] - in r0, USBIN ;[039] <-- phase - ori shift, 0x04 ;[040] - mov x1, x2 ;[041] - rjmp didUnstuff2 ;[042] -; [---] ;[043] - ;[033] - -unstuff3: ;[043] - in x2, USBIN ;[044] <-- bit 3 again - eor r0, x2 ;[045] - or phase, r0 ;[046] - andi x3, ~0x08 ;[047] - ori shift, 0x08 ;[048] - nop ;[049] - in r0, USBIN ;[050] <-- phase - rjmp didUnstuff3 ;[051] -; [---] ;[052] - ;[042] - -unstuff4: ;[053] - andi x3, ~0x10 ;[054] - in x1, USBIN ;[055] <-- bit 4 again - ori shift, 0x10 ;[056] - rjmp didUnstuff4 ;[057] -; [---] ;[058] - ;[048] - -rxLoop: ;[085] - eor x3, shift ;[086] reconstruct: x3 is 0 at bit locations we changed, 1 at others - in x1, USBIN ;[000] <-- bit 0 - st y+, x3 ;[001] -; [---] ;[002] - eor r0, x1 ;[003] - or phase, r0 ;[004] - eor x2, x1 ;[005] - in r0, USBIN ;[006] <-- phase - ser x3 ;[007] - bst x2, USBMINUS ;[008] - bld shift, 0 ;[009] - andi shift, 0xf9 ;[010] -rxbit1: ;[ ] - in x2, USBIN ;[011] <-- bit 1 - breq unstuff0 ;[012] *** unstuff escape - andi x2, USBMASK ;[013] SE0 check for bit 1 -didUnstuff0: ;[ ] Z only set if we detected SE0 in bitstuff - breq se0 ;[014] - eor r0, x2 ;[015] - or phase, r0 ;[016] - in r0, USBIN ;[017] <-- phase - eor x1, x2 ;[018] - bst x1, USBMINUS ;[019] - bld shift, 1 ;[020] - andi shift, 0xf3 ;[021] -didUnstuff1: ;[ ] - in x1, USBIN ;[022] <-- bit 2 - breq unstuff1 ;[023] *** unstuff escape - eor r0, x1 ;[024] - or phase, r0 ;[025] - subi cnt, 1 ;[026] overflow check - brcs overflow ;[027] - in r0, USBIN ;[028] <-- phase - eor x2, x1 ;[029] - bst x2, USBMINUS ;[030] - bld shift, 2 ;[031] - andi shift, 0xe7 ;[032] -didUnstuff2: ;[ ] - in x2, USBIN ;[033] <-- bit 3 - breq unstuff2 ;[034] *** unstuff escape - eor r0, x2 ;[035] - or phase, r0 ;[036] - eor x1, x2 ;[037] - bst x1, USBMINUS ;[038] - in r0, USBIN ;[039] <-- phase - bld shift, 3 ;[040] - andi shift, 0xcf ;[041] -didUnstuff3: ;[ ] - breq unstuff3 ;[042] *** unstuff escape - nop ;[043] - in x1, USBIN ;[044] <-- bit 4 - eor x2, x1 ;[045] - bst x2, USBMINUS ;[046] - bld shift, 4 ;[047] -didUnstuff4: ;[ ] - eor r0, x1 ;[048] - or phase, r0 ;[049] - in r0, USBIN ;[050] <-- phase - andi shift, 0x9f ;[051] - breq unstuff4 ;[052] *** unstuff escape - rjmp continueWithBit5;[053] -; [---] ;[054] - -macro POP_STANDARD ; 16 cycles - pop cnt - pop x4 - pop x3 - pop x2 - pop x1 - pop shift - pop YH - pop r0 - endm -macro POP_RETI ; 5 cycles - pop YL - out SREG, YL - pop YL - endm - -#include "asmcommon.inc" - - -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) -; K = (D+ = 1), (D- = 0) -; Spec allows 7.5 bit times from EOP to SOP for replies - -bitstuff7: - eor x1, x4 ;[4] - ldi x2, 0 ;[5] - nop2 ;[6] C is zero (brcc) - rjmp didStuff7 ;[8] - -bitstuffN: - eor x1, x4 ;[5] - ldi x2, 0 ;[6] - lpm ;[7] 3 cycle NOP, modifies r0 - out USBOUT, x1 ;[10] <-- out - rjmp didStuffN ;[0] - -#define bitStatus x3 - -sendNakAndReti: - ldi cnt, USBPID_NAK ;[-19] - rjmp sendCntAndReti ;[-18] -sendAckAndReti: - ldi cnt, USBPID_ACK ;[-17] -sendCntAndReti: - mov r0, cnt ;[-16] - ldi YL, 0 ;[-15] R0 address is 0 - ldi YH, 0 ;[-14] - ldi cnt, 2 ;[-13] -; rjmp usbSendAndReti fallthrough - -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] -;uses: x1...x4, shift, cnt, Y -;Numbers in brackets are time since first bit of sync pattern is sent -usbSendAndReti: ; 12 cycles until SOP - in x2, USBDDR ;[-12] - ori x2, USBMASK ;[-11] - sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) - in x1, USBOUT ;[-8] port mirror for tx loop - out USBDDR, x2 ;[-7] <- acquire bus -; need not init x2 (bitstuff history) because sync starts with 0 - ldi x4, USBMASK ;[-6] exor mask - ldi shift, 0x80 ;[-5] sync byte is first byte sent - ldi bitStatus, 0xff ;[-4] init bit loop counter, works for up to 12 bytes -byteloop: -bitloop: - sbrs shift, 0 ;[8] [-3] - eor x1, x4 ;[9] [-2] - out USBOUT, x1 ;[10] [-1] <-- out - ror shift ;[0] - ror x2 ;[1] -didStuffN: - cpi x2, 0xfc ;[2] - brcc bitstuffN ;[3] - nop ;[4] - subi bitStatus, 37 ;[5] 256 / 7 ~=~ 37 - brcc bitloop ;[6] when we leave the loop, bitStatus has almost the initial value - sbrs shift, 0 ;[7] - eor x1, x4 ;[8] - ror shift ;[9] -didStuff7: - out USBOUT, x1 ;[10] <-- out - ror x2 ;[0] - cpi x2, 0xfc ;[1] - brcc bitstuff7 ;[2] - ld shift, y+ ;[3] - dec cnt ;[5] - brne byteloop ;[6] -;make SE0: - cbr x1, USBMASK ;[7] prepare SE0 [spec says EOP may be 21 to 25 cycles] - lds x2, usbNewDeviceAddr;[8] - lsl x2 ;[10] we compare with left shifted address - out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - subi YL, 2 ;[0] Only assign address on data packets, not ACK/NAK in r0 - sbci YH, 0 ;[1] - breq skipAddrAssign ;[2] - sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer -skipAddrAssign: -;end of usbDeviceAddress transfer - ldi x2, 1< 12 cycles per bit -; Numbers in brackets are clocks counted from center of last sync bit -; when instruction starts -;register use in receive loop to receive the data bytes: -; shift assembles the byte currently being received -; x1 holds the D+ and D- line state -; x2 holds the previous line state -; cnt holds the number of bytes left in the receive buffer -; x3 holds the higher crc byte (see algorithm below) -; x4 is used as temporary register for the crc algorithm -; x5 is used for unstuffing: when unstuffing the last received bit is inverted in shift (to prevent further -; unstuffing calls. In the same time the corresponding bit in x5 is cleared to mark the bit as beening iverted -; zl lower crc value and crc table index -; zh used for crc table accesses - -;-------------------------------------------------------------------------------------------------------------- -; CRC mods: -; table driven crc checker, Z points to table in prog space -; ZL is the lower crc byte, x3 is the higher crc byte -; x4 is used as temp register to store different results -; the initialization of the crc register is not 0xFFFF but 0xFE54. This is because during the receipt of the -; first data byte an virtual zero data byte is added to the crc register, this results in the correct initial -; value of 0xFFFF at beginning of the second data byte before the first data byte is added to the crc. -; The magic number 0xFE54 results form the crc table: At tabH[0x54] = 0xFF = crcH (required) and -; tabL[0x54] = 0x01 -> crcL = 0x01 xor 0xFE = 0xFF -; bitcnt is renamed to x5 and is used for unstuffing purposes, the unstuffing works like in the 12MHz version -;-------------------------------------------------------------------------------------------------------------- -; CRC algorithm: -; The crc register is formed by x3 (higher byte) and ZL (lower byte). The algorithm uses a 'reversed' form -; i.e. that it takes the least significant bit first and shifts to the right. So in fact the highest order -; bit seen from the polynomial devision point of view is the lsb of ZL. (If this sounds strange to you i -; propose a research on CRC :-) ) -; Each data byte received is xored to ZL, the lower crc byte. This byte now builds the crc -; table index. Next the new high byte is loaded from the table and stored in x4 until we have space in x3 -; (its destination). -; Afterwards the lower table is loaded from the table and stored in ZL (the old index is overwritten as -; we don't need it anymore. In fact this is a right shift by 8 bits.) Now the old crc high value is xored -; to ZL, this is the second shift of the old crc value. Now x4 (the temp reg) is moved to x3 and the crc -; calculation is done. -; Prior to the first byte the two CRC register have to be initialized to 0xFFFF (as defined in usb spec) -; however the crc engine also runs during the receipt of the first byte, therefore x3 and zl are initialized -; to a magic number which results in a crc value of 0xFFFF after the first complete byte. -; -; This algorithm is split into the extra cycles of the different bits: -; bit7: XOR the received byte to ZL -; bit5: load the new high byte to x4 -; bit6: load the lower xor byte from the table, xor zl and x3, store result in zl (=the new crc low value) -; move x4 (the new high byte) to x3, the crc value is ready -; - - -macro POP_STANDARD ; 18 cycles - pop ZH - pop ZL - pop cnt - pop x5 - pop x3 - pop x2 - pop x1 - pop shift - pop x4 - endm -macro POP_RETI ; 7 cycles - pop YH - pop YL - out SREG, YL - pop YL - endm - -macro CRC_CLEANUP_AND_CHECK - ; the last byte has already been xored with the lower crc byte, we have to do the table lookup and xor - ; x3 is the higher crc byte, zl the lower one - ldi ZH, hi8(usbCrcTableHigh);[+1] get the new high byte from the table - lpm x2, Z ;[+2][+3][+4] - ldi ZH, hi8(usbCrcTableLow);[+5] get the new low xor byte from the table - lpm ZL, Z ;[+6][+7][+8] - eor ZL, x3 ;[+7] xor the old high byte with the value from the table, x2:ZL now holds the crc value - cpi ZL, 0x01 ;[+8] if the crc is ok we have a fixed remainder value of 0xb001 in x2:ZL (see usb spec) - brne ignorePacket ;[+9] detected a crc fault -> paket is ignored and retransmitted by the host - cpi x2, 0xb0 ;[+10] - brne ignorePacket ;[+11] detected a crc fault -> paket is ignored and retransmitted by the host - endm - - -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG, YH, [sofError], x4, shift, x1, x2, x3, x5, cnt, ZL, ZH - push YL ;[-28] push only what is necessary to sync with edge ASAP - in YL, SREG ;[-26] - push YL ;[-25] - push YH ;[-23] -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of < 1/4 bit which meets the spec. - sbis USBIN, USBMINUS ;[-17] - rjmp foundK ;[-16] - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -foundK: ;[-15] -;{3, 5} after falling D- edge, average delay: 4 cycles -;bit0 should be at 30 (2.5 bits) for center sampling. Currently at 4 so 26 cylces till bit 0 sample -;use 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push x4 ;[-14] -; [---] ;[-13] - lds YL, usbInputBufOffset;[-12] used to toggle the two usb receive buffers -; [---] ;[-11] - clr YH ;[-10] - subi YL, lo8(-(usbRxBuf));[-9] [rx loop init] - sbci YH, hi8(-(usbRxBuf));[-8] [rx loop init] - push shift ;[-7] -; [---] ;[-6] - ldi shift, 0x80 ;[-5] the last bit is the end of byte marker for the pid receiver loop - clc ;[-4] the carry has to be clear for receipt of pid bit 0 - sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early) - rjmp haveTwoBitsK ;[-2] - pop shift ;[-1] undo the push from before - pop x4 ;[1] - rjmp waitForK ;[3] this was not the end of sync, retry -; The entire loop from waitForK until rjmp waitForK above must not exceed two -; bit times (= 24 cycles). - -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -haveTwoBitsK: - push x1 ;[0] - push x2 ;[2] - push x3 ;[4] crc high byte - ldi x2, 1< jump back and store the byte - ori shift, 0x01 ;[11] invert the last received bit to prevent furhter unstuffing - in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors - andi x5, 0xFE ;[1] mark this bit as inverted (will be corrected before storing shift) - eor x1, x2 ;[2] x1 and x2 have to be different because the stuff bit is always a zero - andi x1, USBMASK ;[3] mask the interesting bits - breq stuffErr ;[4] if the stuff bit is a 1-bit something went wrong - mov x1, x2 ;[5] the next bit expects the last state to be in x1 - rjmp didunstuff0 ;[6] - ;[7] jump delay of rjmp didunstuffX - -unstuff1: ;[11] this is the jump delay of breq unstuffX - in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors - ori shift, 0x02 ;[1] invert the last received bit to prevent furhter unstuffing - andi x5, 0xFD ;[2] mark this bit as inverted (will be corrected before storing shift) - eor x2, x1 ;[3] x1 and x2 have to be different because the stuff bit is always a zero - andi x2, USBMASK ;[4] mask the interesting bits - breq stuffErr ;[5] if the stuff bit is a 1-bit something went wrong - mov x2, x1 ;[6] the next bit expects the last state to be in x2 - nop2 ;[7] - ;[8] - rjmp didunstuff1 ;[9] - ;[10] jump delay of rjmp didunstuffX - -unstuff2: ;[9] this is the jump delay of breq unstuffX - ori shift, 0x04 ;[10] invert the last received bit to prevent furhter unstuffing - andi x5, 0xFB ;[11] mark this bit as inverted (will be corrected before storing shift) - in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors - eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero - andi x1, USBMASK ;[2] mask the interesting bits - breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong - mov x1, x2 ;[4] the next bit expects the last state to be in x1 - nop2 ;[5] - ;[6] - rjmp didunstuff2 ;[7] - ;[8] jump delay of rjmp didunstuffX - -unstuff3: ;[9] this is the jump delay of breq unstuffX - ori shift, 0x08 ;[10] invert the last received bit to prevent furhter unstuffing - andi x5, 0xF7 ;[11] mark this bit as inverted (will be corrected before storing shift) - in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors - eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero - andi x2, USBMASK ;[2] mask the interesting bits - breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong - mov x2, x1 ;[4] the next bit expects the last state to be in x2 - nop2 ;[5] - ;[6] - rjmp didunstuff3 ;[7] - ;[8] jump delay of rjmp didunstuffX - - - -; the include has to be here due to branch distance restirctions -#define __USE_CRC__ -#include "asmcommon.inc" - - - -; USB spec says: -; idle = J -; J = (D+ = 0), (D- = 1) -; K = (D+ = 1), (D- = 0) -; Spec allows 7.5 bit times from EOP to SOP for replies -; 7.5 bit times is 90 cycles. ...there is plenty of time - - -sendNakAndReti: - ldi x3, USBPID_NAK ;[-18] - rjmp sendX3AndReti ;[-17] -sendAckAndReti: - ldi cnt, USBPID_ACK ;[-17] -sendCntAndReti: - mov x3, cnt ;[-16] -sendX3AndReti: - ldi YL, 20 ;[-15] x3==r20 address is 20 - ldi YH, 0 ;[-14] - ldi cnt, 2 ;[-13] -; rjmp usbSendAndReti fallthrough - -;usbSend: -;pointer to data in 'Y' -;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] -;uses: x1...x4, btcnt, shift, cnt, Y -;Numbers in brackets are time since first bit of sync pattern is sent - -usbSendAndReti: ; 12 cycles until SOP - in x2, USBDDR ;[-12] - ori x2, USBMASK ;[-11] - sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) - in x1, USBOUT ;[-8] port mirror for tx loop - out USBDDR, x2 ;[-6] <- acquire bus - ldi x2, 0 ;[-6] init x2 (bitstuff history) because sync starts with 0 - ldi x4, USBMASK ;[-5] exor mask - ldi shift, 0x80 ;[-4] sync byte is first byte sent -txByteLoop: - ldi bitcnt, 0x40 ;[-3]=[9] binary 01000000 -txBitLoop: ; the loop sends the first 7 bits of the byte - sbrs shift, 0 ;[-2]=[10] if we have to send a 1 don't change the line state - eor x1, x4 ;[-1]=[11] - out USBOUT, x1 ;[0] - ror shift ;[1] - ror x2 ;[2] transfers the last sent bit to the stuffing history -didStuffN: - nop ;[3] - nop ;[4] - cpi x2, 0xfc ;[5] if we sent six consecutive ones - brcc bitstuffN ;[6] - lsr bitcnt ;[7] - brne txBitLoop ;[8] restart the loop while the 1 is still in the bitcount - -; transmit bit 7 - sbrs shift, 0 ;[9] - eor x1, x4 ;[10] -didStuff7: - ror shift ;[11] - out USBOUT, x1 ;[0] transfer bit 7 to the pins - ror x2 ;[1] move the bit into the stuffing history - cpi x2, 0xfc ;[2] - brcc bitstuff7 ;[3] - ld shift, y+ ;[4] get next byte to transmit - dec cnt ;[5] decrement byte counter - brne txByteLoop ;[7] if we have more bytes start next one - ;[8] branch delay - -;make SE0: - cbr x1, USBMASK ;[8] prepare SE0 [spec says EOP may be 25 to 30 cycles] - lds x2, usbNewDeviceAddr;[9] - lsl x2 ;[11] we compare with left shifted address - out USBOUT, x1 ;[0] <-- out SE0 -- from now 2 bits = 24 cycles until bus idle - subi YL, 20 + 2 ;[1] Only assign address on data packets, not ACK/NAK in x3 - sbci YH, 0 ;[2] -;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: -;set address only after data packet was sent, not after handshake - breq skipAddrAssign ;[3] - sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer -skipAddrAssign: -;end of usbDeviceAddress transfer - ldi x2, 1< -int main (int argc, char **argv) -{ - int i, j; - for (i=0; i<512; i++){ - unsigned short crc = i & 0xff; - for(j=0; j<8; j++) crc = (crc >> 1) ^ ((crc & 1) ? 0xa001 : 0); - if((i & 7) == 0) printf("\n.byte "); - printf("0x%02x, ", (i > 0xff ? (crc >> 8) : crc) & 0xff); - if(i == 255) printf("\n"); - } - return 0; -} - -// Use the following algorithm to compute CRC values: -ushort computeCrc(uchar *msg, uchar msgLen) -{ - uchar i; - ushort crc = 0xffff; - for(i = 0; i < msgLen; i++) - crc = usbCrcTable16[lo8(crc) ^ msg[i]] ^ hi8(crc); - return crc; -} -*/ - -.balign 256 -usbCrcTableLow: -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 -.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 - -; .balign 256 -usbCrcTableHigh: -.byte 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2 -.byte 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04 -.byte 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E -.byte 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8 -.byte 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A -.byte 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC -.byte 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6 -.byte 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10 -.byte 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32 -.byte 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4 -.byte 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE -.byte 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38 -.byte 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA -.byte 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C -.byte 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26 -.byte 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0 -.byte 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62 -.byte 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4 -.byte 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE -.byte 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68 -.byte 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA -.byte 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C -.byte 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76 -.byte 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0 -.byte 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92 -.byte 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54 -.byte 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E -.byte 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98 -.byte 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A -.byte 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C -.byte 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86 -.byte 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 - diff --git a/tools/avrusb/usbdrv/usbdrvasm20.inc b/tools/avrusb/usbdrv/usbdrvasm20.inc deleted file mode 100644 index 5cfaa5f..0000000 --- a/tools/avrusb/usbdrv/usbdrvasm20.inc +++ /dev/null @@ -1,360 +0,0 @@ -/* Name: usbdrvasm20.inc - * Project: AVR USB driver - * Author: Jeroen Benschop - * Based on usbdrvasm16.inc from Christian Starkjohann - * Creation Date: 2008-03-05 - * Tabsize: 4 - * Copyright: (c) 2008 by Jeroen Benschop and OBJECTIVE DEVELOPMENT Software GmbH - * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) - * Revision: $Id: usbdrvasm20.inc 692 2008-11-07 15:07:40Z cs $ - */ - -/* Do not link this file! Link usbdrvasm.S instead, which includes the - * appropriate implementation! - */ - -/* -General Description: -This file is the 20 MHz version of the asssembler part of the USB driver. It -requires a 20 MHz crystal (not a ceramic resonator and not a calibrated RC -oscillator). - -See usbdrv.h for a description of the entire driver. - -Since almost all of this code is timing critical, don't change unless you -really know what you are doing! Many parts require not only a maximum number -of CPU cycles, but even an exact number of cycles! -*/ - -#define leap2 x3 -#ifdef __IAR_SYSTEMS_ASM__ -#define nextInst $+2 -#else -#define nextInst .+0 -#endif - -;max stack usage: [ret(2), YL, SREG, YH, bitcnt, shift, x1, x2, x3, x4, cnt] = 12 bytes -;nominal frequency: 20 MHz -> 13.333333 cycles per bit, 106.666667 cycles per byte -; Numbers in brackets are clocks counted from center of last sync bit -; when instruction starts -;register use in receive loop: -; shift assembles the byte currently being received -; x1 holds the D+ and D- line state -; x2 holds the previous line state -; x4 (leap) is used to add a leap cycle once every three bytes received -; X3 (leap2) is used to add a leap cycle once every three stuff bits received -; bitcnt is used to determine when a stuff bit is due -; cnt holds the number of bytes left in the receive buffer - -USB_INTR_VECTOR: -;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt - push YL ;[-28] push only what is necessary to sync with edge ASAP - in YL, SREG ;[-26] - push YL ;[-25] - push YH ;[-23] -;---------------------------------------------------------------------------- -; Synchronize with sync pattern: -;---------------------------------------------------------------------------- -;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] -;sync up with J to K edge during sync pattern -- use fastest possible loops -;The first part waits at most 1 bit long since we must be in sync pattern. -;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to -;waitForJ, ensure that this prerequisite is met. -waitForJ: - inc YL - sbis USBIN, USBMINUS - brne waitForJ ; just make sure we have ANY timeout -waitForK: -;The following code results in a sampling window of < 1/4 bit which meets the spec. - sbis USBIN, USBMINUS ;[-19] - rjmp foundK ;[-18] - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK - sbis USBIN, USBMINUS - rjmp foundK -#if USB_COUNT_SOF - lds YL, usbSofCount - inc YL - sts usbSofCount, YL -#endif /* USB_COUNT_SOF */ -#ifdef USB_SOF_HOOK - USB_SOF_HOOK -#endif - rjmp sofError -foundK: ;[-16] -;{3, 5} after falling D- edge, average delay: 4 cycles -;bit0 should be at 34 for center sampling. Currently at 4 so 30 cylces till bit 0 sample -;use 1 bit time for setup purposes, then sample again. Numbers in brackets -;are cycles from center of first sync (double K) bit after the instruction - push bitcnt ;[-16] -; [---] ;[-15] - lds YL, usbInputBufOffset;[-14] -; [---] ;[-13] - clr YH ;[-12] - subi YL, lo8(-(usbRxBuf));[-11] [rx loop init] - sbci YH, hi8(-(usbRxBuf));[-10] [rx loop init] - push shift ;[-9] -; [---] ;[-8] - ldi shift,0x40 ;[-7] set msb to "1" so processing bit7 can be detected - nop2 ;[-6] -; [---] ;[-5] - ldi bitcnt, 5 ;[-4] [rx loop init] - sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early) - rjmp haveTwoBitsK ;[-2] - pop shift ;[-1] undo the push from before - pop bitcnt ;[1] - rjmp waitForK ;[3] this was not the end of sync, retry -; The entire loop from waitForK until rjmp waitForK above must not exceed two -; bit times (= 27 cycles). - -;---------------------------------------------------------------------------- -; push more registers and initialize values while we sample the first bits: -;---------------------------------------------------------------------------- -haveTwoBitsK: - push x1 ;[0] - push x2 ;[2] - push x3 ;[4] (leap2) - ldi leap2, 0x55 ;[6] add leap cycle on 2nd,5th,8th,... stuff bit - push x4 ;[7] == leap - ldi leap, 0x55 ;[9] skip leap cycle on 2nd,5th,8th,... byte received - push cnt ;[10] - ldi cnt, USB_BUFSIZE ;[12] [rx loop init] - ldi x2, 1< -#ifndef __IAR_SYSTEMS_ASM__ -# include -#endif - -#define __attribute__(arg) /* not supported on IAR */ - -#ifdef __IAR_SYSTEMS_ASM__ -# define __ASSEMBLER__ /* IAR does not define standard macro for asm */ -#endif - -#ifdef __HAS_ELPM__ -# define PROGMEM __farflash -#else -# define PROGMEM __flash -#endif - -#define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr)) - -/* The following definitions are not needed by the driver, but may be of some - * help if you port a gcc based project to IAR. - */ -#define cli() __disable_interrupt() -#define sei() __enable_interrupt() -#define wdt_reset() __watchdog_reset() -#define _BV(x) (1 << (x)) - -/* assembler compatibility macros */ -#define nop2 rjmp $+2 /* jump to next instruction */ -#define XL r26 -#define XH r27 -#define YL r28 -#define YH r29 -#define ZL r30 -#define ZH r31 -#define lo8(x) LOW(x) -#define hi8(x) (((x)>>8) & 0xff) /* not HIGH to allow XLINK to make a proper range check */ - -/* Depending on the device you use, you may get problems with the way usbdrv.h - * handles the differences between devices. Since IAR does not use #defines - * for MCU registers, we can't check for the existence of a particular - * register with an #ifdef. If the autodetection mechanism fails, include - * definitions for the required USB_INTR_* macros in your usbconfig.h. See - * usbconfig-prototype.h and usbdrv.h for details. - */ - -/* ------------------------------------------------------------------------- */ -#elif __CODEVISIONAVR__ /* check for CodeVision AVR */ -/* ------------------------------------------------------------------------- */ -/* This port is not working (yet) */ - -/* #define F_CPU _MCU_CLOCK_FREQUENCY_ seems to be defined automatically */ - -#include -#include - -#define __attribute__(arg) /* not supported on IAR */ - -#define PROGMEM __flash -#define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr)) - -#ifndef __ASSEMBLER__ -static inline void cli(void) -{ - #asm("cli"); -} -static inline void sei(void) -{ - #asm("sei"); -} -#endif -#define _delay_ms(t) delay_ms(t) -#define _BV(x) (1 << (x)) -#define USB_CFG_USE_SWITCH_STATEMENT 1 /* macro for if() cascase fails for unknown reason */ - -#define macro .macro -#define endm .endmacro -#define nop2 rjmp .+0 /* jump to next instruction */ - -/* ------------------------------------------------------------------------- */ -#else /* default development environment is avr-gcc/avr-libc */ -/* ------------------------------------------------------------------------- */ - -#include -#ifdef __ASSEMBLER__ -# define _VECTOR(N) __vector_ ## N /* io.h does not define this for asm */ -#else -# include -#endif - -#define USB_READ_FLASH(addr) pgm_read_byte(addr) - -#define macro .macro -#define endm .endm -#define nop2 rjmp .+0 /* jump to next instruction */ - -#endif /* development environment */ - -/* for conveniecne, ensure that PRG_RDB exists */ -#ifndef PRG_RDB -# define PRG_RDB(addr) USB_READ_FLASH(addr) -#endif -#endif /* __usbportability_h_INCLUDED__ */