├── Makefile ├── binary ├── main.elf └── main.hex ├── main.c ├── readme.md ├── usbconfig.h └── usbdrv ├── .DS_Store ├── Changelog.txt ├── CommercialLicense.txt ├── License.txt ├── Readme.txt ├── USB-ID-FAQ.txt ├── USB-IDs-for-free.txt ├── USBID-License.txt ├── asmcommon.inc ├── oddebug.c ├── oddebug.h ├── usbconfig-prototype.h ├── usbdrv.c ├── usbdrv.h ├── usbdrvasm.S ├── usbdrvasm.asm ├── usbdrvasm12.inc ├── usbdrvasm128.inc ├── usbdrvasm15.inc ├── usbdrvasm16.inc ├── usbdrvasm165.inc ├── usbdrvasm18-crc.inc ├── usbdrvasm20.inc └── usbportability.h /Makefile: -------------------------------------------------------------------------------- 1 | # Name: Makefile 2 | # Project: custom-class example 3 | # Author: Christian Starkjohann 4 | # Creation Date: 2008-04-07 5 | # Tabsize: 4 6 | # Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH 7 | # License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) 8 | # This Revision: $Id: Makefile 692 2008-11-07 15:07:40Z cs $ 9 | 10 | DEVICE = attiny44 11 | F_CPU = 12000000 # in Hz 12 | FUSE_L = 0xFF 13 | FUSE_H = 0xDF 14 | AVRDUDE = avrdude -c avrispmkii -P usb -p $(DEVICE) # edit this line for your programmer 15 | 16 | CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0 17 | OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o 18 | 19 | COMPILE = avr-gcc -Wall -Os -DF_CPU=$(F_CPU) $(CFLAGS) -mmcu=$(DEVICE) 20 | 21 | ############################################################################## 22 | # Fuse values for particular devices 23 | ############################################################################## 24 | # If your device is not listed here, go to 25 | # http://palmavr.sourceforge.net/cgi-bin/fc.cgi 26 | # and choose options for external crystal clock and no clock divider 27 | # 28 | ################################## ATMega8 ################################## 29 | # ATMega8 FUSE_L (Fuse low byte): 30 | # 0x9f = 1 0 0 1 1 1 1 1 31 | # ^ ^ \ / \--+--/ 32 | # | | | +------- CKSEL 3..0 (external >8M crystal) 33 | # | | +--------------- SUT 1..0 (crystal osc, BOD enabled) 34 | # | +------------------ BODEN (BrownOut Detector enabled) 35 | # +-------------------- BODLEVEL (2.7V) 36 | # ATMega8 FUSE_H (Fuse high byte): 37 | # 0xc9 = 1 1 0 0 1 0 0 1 <-- BOOTRST (boot reset vector at 0x0000) 38 | # ^ ^ ^ ^ ^ ^ ^------ BOOTSZ0 39 | # | | | | | +-------- BOOTSZ1 40 | # | | | | + --------- EESAVE (don't preserve EEPROM over chip erase) 41 | # | | | +-------------- CKOPT (full output swing) 42 | # | | +---------------- SPIEN (allow serial programming) 43 | # | +------------------ WDTON (WDT not always on) 44 | # +-------------------- RSTDISBL (reset pin is enabled) 45 | # 46 | ############################## ATMega48/88/168 ############################## 47 | # ATMega*8 FUSE_L (Fuse low byte): 48 | # 0xdf = 1 1 0 1 1 1 1 1 49 | # ^ ^ \ / \--+--/ 50 | # | | | +------- CKSEL 3..0 (external >8M crystal) 51 | # | | +--------------- SUT 1..0 (crystal osc, BOD enabled) 52 | # | +------------------ CKOUT (if 0: Clock output enabled) 53 | # +-------------------- CKDIV8 (if 0: divide by 8) 54 | # ATMega*8 FUSE_H (Fuse high byte): 55 | # 0xde = 1 1 0 1 1 1 1 0 56 | # ^ ^ ^ ^ ^ \-+-/ 57 | # | | | | | +------ BODLEVEL 0..2 (110 = 1.8 V) 58 | # | | | | + --------- EESAVE (preserve EEPROM over chip erase) 59 | # | | | +-------------- WDTON (if 0: watchdog always on) 60 | # | | +---------------- SPIEN (allow serial programming) 61 | # | +------------------ DWEN (debug wire enable) 62 | # +-------------------- RSTDISBL (reset pin is enabled) 63 | # 64 | ############################## ATTiny25/45/85 ############################### 65 | # ATMega*5 FUSE_L (Fuse low byte): 66 | # 0xef = 1 1 1 0 1 1 1 1 67 | # ^ ^ \+/ \--+--/ 68 | # | | | +------- CKSEL 3..0 (clock selection -> crystal @ 12 MHz) 69 | # | | +--------------- SUT 1..0 (BOD enabled, fast rising power) 70 | # | +------------------ CKOUT (clock output on CKOUT pin -> disabled) 71 | # +-------------------- CKDIV8 (divide clock by 8 -> don't divide) 72 | # ATMega*5 FUSE_H (Fuse high byte): 73 | # 0xdd = 1 1 0 1 1 1 0 1 74 | # ^ ^ ^ ^ ^ \-+-/ 75 | # | | | | | +------ BODLEVEL 2..0 (brownout trigger level -> 2.7V) 76 | # | | | | +---------- EESAVE (preserve EEPROM on Chip Erase -> not preserved) 77 | # | | | +-------------- WDTON (watchdog timer always on -> disable) 78 | # | | +---------------- SPIEN (enable serial programming -> enabled) 79 | # | +------------------ DWEN (debug wire enable) 80 | # +-------------------- RSTDISBL (disable external reset -> enabled) 81 | # 82 | ################################ ATTiny2313 ################################# 83 | # ATTiny2313 FUSE_L (Fuse low byte): 84 | # 0xef = 1 1 1 0 1 1 1 1 85 | # ^ ^ \+/ \--+--/ 86 | # | | | +------- CKSEL 3..0 (clock selection -> crystal @ 12 MHz) 87 | # | | +--------------- SUT 1..0 (BOD enabled, fast rising power) 88 | # | +------------------ CKOUT (clock output on CKOUT pin -> disabled) 89 | # +-------------------- CKDIV8 (divide clock by 8 -> don't divide) 90 | # ATTiny2313 FUSE_H (Fuse high byte): 91 | # 0xdb = 1 1 0 1 1 0 1 1 92 | # ^ ^ ^ ^ \-+-/ ^ 93 | # | | | | | +---- RSTDISBL (disable external reset -> enabled) 94 | # | | | | +-------- BODLEVEL 2..0 (brownout trigger level -> 2.7V) 95 | # | | | +-------------- WDTON (watchdog timer always on -> disable) 96 | # | | +---------------- SPIEN (enable serial programming -> enabled) 97 | # | +------------------ EESAVE (preserve EEPROM on Chip Erase -> not preserved) 98 | # +-------------------- DWEN (debug wire enable) 99 | 100 | 101 | # symbolic targets: 102 | help: 103 | @echo "This Makefile has no default rule. Use one of the following:" 104 | @echo "make hex ....... to build main.hex" 105 | @echo "make program ... to flash fuses and firmware" 106 | @echo "make fuse ...... to flash the fuses" 107 | @echo "make flash ..... to flash the firmware (use this on metaboard)" 108 | @echo "make clean ..... to delete objects and hex file" 109 | 110 | hex: main.hex 111 | 112 | program: flash fuse 113 | 114 | # rule for programming fuse bits: 115 | fuse: 116 | @[ "$(FUSE_H)" != "" -a "$(FUSE_L)" != "" ] || \ 117 | { echo "*** Edit Makefile and choose values for FUSE_L and FUSE_H!"; exit 1; } 118 | $(AVRDUDE) -U hfuse:w:$(FUSE_H):m -U lfuse:w:$(FUSE_L):m 119 | 120 | # rule for uploading firmware: 121 | flash: main.hex 122 | $(AVRDUDE) -U flash:w:main.hex:i 123 | 124 | # rule for deleting dependent files (those which can be built by Make): 125 | clean: 126 | 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 127 | 128 | # Generic rule for compiling C files: 129 | .c.o: 130 | $(COMPILE) -c $< -o $@ 131 | 132 | # Generic rule for assembling Assembler source files: 133 | .S.o: 134 | $(COMPILE) -x assembler-with-cpp -c $< -o $@ 135 | # "-x assembler-with-cpp" should not be necessary since this is the default 136 | # file type for the .S (with capital S) extension. However, upper case 137 | # characters are not always preserved on Windows. To ensure WinAVR 138 | # compatibility define the file type manually. 139 | 140 | # Generic rule for compiling C to assembler, used for debugging only. 141 | .c.s: 142 | $(COMPILE) -S $< -o $@ 143 | 144 | # file targets: 145 | 146 | # Since we don't want to ship the driver multipe times, we copy it into this project: 147 | usbdrv: 148 | cp -r ../../../usbdrv . 149 | 150 | main.elf: usbdrv $(OBJECTS) # usbdrv dependency only needed because we copy it 151 | $(COMPILE) -o main.elf $(OBJECTS) 152 | 153 | main.hex: main.elf 154 | rm -f main.hex main.eep.hex 155 | avr-objcopy -j .text -j .data -O ihex main.elf main.hex 156 | avr-size main.hex 157 | 158 | # debugging targets: 159 | 160 | disasm: main.elf 161 | avr-objdump -d main.elf 162 | 163 | cpp: 164 | $(COMPILE) -E main.c 165 | -------------------------------------------------------------------------------- /binary/main.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/ArduinoISP/95dc3acaf2bdc01bcaee3743c9449c01c6362b19/binary/main.elf -------------------------------------------------------------------------------- /binary/main.hex: -------------------------------------------------------------------------------- 1 | :100000002FC07BC148C047C046C045C044C043C0A4 2 | :1000100042C041C040C03FC03EC03DC03CC03BC0EC 3 | :100020003AC004030904160341007200640075001D 4 | :1000300069006E006F00490053005000120110016A 5 | :10004000FF000008412349000401000200010902E9 6 | :10005000120001010080140904000000FF000000EC 7 | :1000600011241FBECFE5D1E0DEBFCDBF10E0A0E67A 8 | :10007000B0E0EEE2F8E002C005900D92A236B107C2 9 | :10008000D9F710E0A2E6B0E001C01D92A53AB10791 10 | :10009000E1F7B0D3CAC3B4CF1F93CF93DF9360917E 11 | :1000A0008B00635067FD9CC080918800CCE0D0E05D 12 | :1000B000C81BD109C157DF4F809187008D3209F0ED 13 | :1000C0007DC0683009F08AC083EC80937B008AE5AC 14 | :1000D00080936000109262008881807631F0CE01BA 15 | :1000E00087D28F3F09F459C05FC09A811092840073 16 | :1000F0008981882331F41092850024E830E082E081 17 | :1001000047C0853019F490938C0038C0863069F56B 18 | :100110008B81813019F48CE390E004C0823041F48B 19 | :100120008EE490E090938A008093890082E119C068 20 | :100130008330B1F4992341F482E290E090938A00F5 21 | :100140008093890084E00DC0913051F0923041F4E9 22 | :1001500086E290E090938A008093890086E101C056 23 | :1001600080E090E4909362001FC0883059F089309D 24 | :1001700019F490938E0002C08A3039F024E830E000 25 | :1001800080E006C02EE830E002C024E830E081E0E4 26 | :1001900030938A002093890007C0988197FD8E8153 27 | :1001A00090E89093620007C09F81992321F49E817B 28 | :1001B000981708F4892F8093610010C08091620025 29 | :1001C00087FF0CC0CE01C9D28F3F21F48EE180930E 30 | :1001D000600004C0882311F01092610010928B001F 31 | :1001E0008091600084FF5BC0809161008F3F09F4C3 32 | :1001F00056C0182F893008F018E0811B80936100E9 33 | :1002000080917B0098E8892780937B001123B1F1CE 34 | :100210008091620087FF08C08CE790E0612F7CD25C 35 | :10022000182F8930B0F52AC02091890030918A00BA 36 | :10023000412F415086FF0EC050E0EA01C358DF4F06 37 | :10024000F901ACE7B0E084918D933196AC17BD070E 38 | :10025000D1F70CC0D90150E0CA0183589F4FECE799 39 | :10026000F0E06D916193E817F907D9F74F5F5F4FA1 40 | :10027000420F531F50938A00409389008CE790E00F 41 | :10028000612F37D01C5F1C3041F08FEF80936100ED 42 | :1002900004C08FEF809361001EE11093600084E141 43 | :1002A00099B3917831F48150D9F710928C00109263 44 | :1002B0008600DF91CF911F91089585B7826085BF39 45 | :1002C0008BB780648BBF0895A82FB92F80E090E092 46 | :1002D00041E050EA609530E009C02D918227979562 47 | :1002E000879510F084279527305EC8F36F5FA8F3D9 48 | :1002F0000895EADF8D939D930895CF93CFB7CF9361 49 | :10030000C395C89BE9F7C89B09C0C89B07C0C89B99 50 | :1003100005C0C89B03C0C89B01C0A1C0DF93C091AA 51 | :100320008800DD27C157DF4FC89B02C0DF91EBCFAC 52 | :100330002F930F931F9309B32FEF00FB20F94F93D7 53 | :100340003F9319B34FEF012700FB21F93BE031C088 54 | :100350004E7F012F19B3216028C0102F4D7F2260DE 55 | :10036000000009B329C04B7F2460012F000019B39E 56 | :100370002BC019B3477F28602AC04F7E09B3206184 57 | :100380002CC04F7D19B320622FC04F7B09B320646E 58 | :1003900032C0422709B349934FEF0000102710FBEA 59 | :1003A00020F919B31178C9F1297F91F2012700FBD7 60 | :1003B00021F909B3237F89F2315058F1102710FB3E 61 | :1003C00022F919B3277E79F2012700FB23F92F7C4C 62 | :1003D00081F209B3102710FB24F92F7971F200C0C4 63 | :1003E00019B3012700FB25F92F7359F200C009B397 64 | :1003F000102710FB26F9223040F200C019B3012764 65 | :1004000000FB27F9243028F64F77206819B3000045 66 | :10041000F9CF10E41ABF002717C03B503195C31B1A 67 | :10042000D04010E41ABF0881033CE9F00B34D9F046 68 | :10043000209186001981110F1213EDCF093641F179 69 | :100440000D3211F0013E39F700938D003F914F912D 70 | :100450001F910F912F91DF91CAB7C6FD51CFCF9158 71 | :10046000CFBFCF91189520918D00222379F3109161 72 | :100470008B00112311F5343012F130938B0020934F 73 | :100480008700109188003BE0311B3093880017C033 74 | :1004900000918B0001308CF40AE53091600034FD4E 75 | :1004A00010C000936000CBE7D0E00FC02795A8F400 76 | :1004B0005150A9F4220F0000F9CF4AE503C042EDE4 77 | :1004C00001C0432FC4E1D0E032E01AB31168D89ADA 78 | :1004D0001ABB0BB320E411E85F93012756E00BBB76 79 | :1004E000279520F4515021F4220FF9CF012756E02F 80 | :1004F00000003B5A0BBBD0F2279528F4515029F449 81 | :10050000220F0000F9CF012756E027950BBB20F4FE 82 | :10051000515021F4220FF9CF012756E029913323BE 83 | :100520000BBB21F60E7710918C00110FC651D040F5 84 | :100530000BBB11F01093860010E41ABF01601AB3D0 85 | :100540001E77402F4E775F9100C000C00BBB1ABBD7 86 | :100550004BBB7CCFFC0150916D00862F972FDC01A7 87 | :1005600094E0619128E030E040E880E0742F762349 88 | :1005700009F0DE9A052E00C000000A94E1F7DC9A2B 89 | :10058000052E00C000000A94E1F7880FCD998F5F17 90 | :10059000DE98DC9846952150304041F78D9391507C 91 | :1005A00001F7089580917000909171009C012F5F78 92 | :1005B0003F4F30937100209370002091720027FF0D 93 | :1005C00002C0880F991F2093630080FF03C028603A 94 | :1005D00020936300292F2695209364009695879594 95 | :1005E0008093650083E690E067E670E0B3DF0895EE 96 | :1005F000CF93DF93FC014181442379F4A3E7B0E07A 97 | :1006000081918D9380E0AB37B807D1F71897B093FD 98 | :100610008A00A093890088E07CC06481A62FB0E0A6 99 | :10062000413059F48C918093730083E790E090936C 100 | :100630008A008093890081E06CC05281423011F4BD 101 | :100640005C9366C00296752F777021E030E001C0A0 102 | :10065000220F7A95EAF7433021F420958C9182237A 103 | :1006600004C0443021F48C91822B8C9351C04530CE 104 | :1006700079F450936D00662311F492E001C09AE082 105 | :100680008AB38A658ABB8BB3857A892B8BBB40C0C2 106 | :10069000463041F4DB9A8BB3857A8BBB8AB3857A7B 107 | :1006A0008ABB36C02BB3222399F1473051F4C3E7FC 108 | :1006B000D0E0BE014FDFD0938A00C093890084E070 109 | :1006C00028C0483031F450936B00838180936C00D4 110 | :1006D0001FC0848195819093710080937000493090 111 | :1006E00011F480E211C04B3011F480EA0DC0828118 112 | :1006F000938190936F0080936E004A3011F480E4F0 113 | :1007000003C04C3029F480EC809372008FEF01C05D 114 | :1007100080E0DF91CF910895EF92FF921F93DF93D6 115 | :10072000CF930F92CDB7DEB7182F862F612F792F79 116 | :100730007B0108C0898336DF90916A00F7019193AD 117 | :100740007F0189819E2D911B9817A0F30F90CF9167 118 | :10075000DF911F91FF90EF900895DF92EF92FF924B 119 | :100760000F931F93CF93DF93F82EE62E0F2D192FA3 120 | :1007700050E6D52E32C0F80181918F01809366003A 121 | :1007800011DF809163008D2580936300C0E0D0E08D 122 | :100790001DC083E690E067E670E0DCDE80916A00D1 123 | :1007A00090916600891741F490916B00891721F0B0 124 | :1007B00090916C00891789F420916D0030E045E03C 125 | :1007C000220F331F4A95E1F7C20FD31F20916E000D 126 | :1007D00030916F00C217D307E0F2802F8F198E156A 127 | :1007E00050F281E0DF91CF911F910F91FF90EF9038 128 | :1007F000DF9008952EE088E190E00FB6F894A89578 129 | :1008000081BD0FBE21BD59DDD09A80E007C0A895FB 130 | :10081000E7EBFBE03197F1F700C000008150B9F73A 131 | :0E082000D0987894A89538DCFDCFF894FFCFDF 132 | :02082E005AFF6F 133 | :00000001FF 134 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* Name: main.c 2 | * Project: FabISP Firmware 3 | * Author: David A. Mellis 4 | * Based on Work By: Dick Streefland and Christian Starkjohann 5 | * Creation Date: 2009-11-18 6 | * Tabsize: 4 7 | * Copyright: (c) 2006-2008 Dick Streefland 8 | * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH 9 | * License: GNU GPL v2 (see License.txt), GNU GPL v3 10 | */ 11 | 12 | /* 13 | This example should run on most AVRs with only little changes. No special 14 | hardware resources except INT0 are used. You may have to change usbconfig.h for 15 | different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or 16 | at least be connected to INT0 as well. 17 | */ 18 | 19 | #include 20 | #include 21 | #include /* for sei() */ 22 | #include /* for _delay_ms() */ 23 | 24 | #include /* required by usbdrv.h */ 25 | #include "usbdrv.h" 26 | #include "oddebug.h" /* This is also an example for using debug macros */ 27 | 28 | typedef unsigned char byte_t; 29 | typedef unsigned int uint_t; 30 | 31 | enum 32 | { 33 | // Generic requests 34 | USBTINY_ECHO, // 0x00: echo test 35 | USBTINY_READ, // 0x01: read byte (wIndex:address) 36 | USBTINY_WRITE, // 0x02: write byte (wIndex:address, wValue:value) 37 | USBTINY_CLR, // 0x03: clear bit (wIndex:address, wValue:bitno) 38 | USBTINY_SET, // 0x04: set bit (wIndex:address, wValue:bitno) 39 | // Programming requests 40 | USBTINY_POWERUP, // 0x05: apply power (wValue:SCK-period, wIndex:RESET) 41 | USBTINY_POWERDOWN, // 0x06: remove power from chip 42 | USBTINY_SPI, // 0x07: issue SPI command (wValue:c1c0, wIndex:c3c2) 43 | USBTINY_POLL_BYTES, // 0x08: set poll bytes for write (wValue:p1p2) 44 | USBTINY_FLASH_READ, // 0x09: read flash (wIndex:address) 45 | USBTINY_FLASH_WRITE, // 0x0A: write flash (wIndex:address, wValue:timeout) 46 | USBTINY_EEPROM_READ, // 0x0B: read eeprom (wIndex:address) 47 | USBTINY_EEPROM_WRITE, // 0x0C: write eeprom (wIndex:address, wValue:timeout) 48 | }; 49 | 50 | // ---------------------------------------------------------------------- 51 | // Programmer output pins: 52 | // LED PA1 53 | // RESET PA3 54 | // SCK PA4 55 | // MOSI PA6 56 | // ---------------------------------------------------------------------- 57 | #define PORT PORTA 58 | #define DDR DDRA 59 | #define POWER_MASK 0x02 60 | #define RESET_MASK (1 << 3) 61 | #define SCK_MASK (1 << 4) 62 | #define MOSI_MASK (1 << 6) 63 | #define ALL_MASK (POWER_MASK | RESET_MASK | SCK_MASK | MOSI_MASK) 64 | 65 | // ---------------------------------------------------------------------- 66 | // Programmer input pins: 67 | // MISO PA5 68 | // ---------------------------------------------------------------------- 69 | #define PIN PINA 70 | #define MISO_MASK (1 << 5) 71 | 72 | // ---------------------------------------------------------------------- 73 | // Local data 74 | // ---------------------------------------------------------------------- 75 | static byte_t sck_period; // SCK period in microseconds (1..250) 76 | static byte_t poll1; // first poll byte for write 77 | static byte_t poll2; // second poll byte for write 78 | static uint_t address; // read/write address 79 | static uint_t timeout; // write timeout in usec 80 | static byte_t cmd0; // current read/write command byte 81 | static byte_t cmd[4]; // SPI command buffer 82 | static byte_t res[4]; // SPI result buffer 83 | 84 | // ---------------------------------------------------------------------- 85 | // Delay exactly times 0.5 microseconds (6 cycles). 86 | // ---------------------------------------------------------------------- 87 | __attribute__((always_inline)) 88 | static void delay ( void ) 89 | { 90 | asm volatile( 91 | " mov __tmp_reg__,%0 \n" 92 | "0: rjmp 1f \n" 93 | "1: nop \n" 94 | " dec __tmp_reg__ \n" 95 | " brne 0b \n" 96 | : : "r" (sck_period) ); 97 | } 98 | 99 | // ---------------------------------------------------------------------- 100 | // Issue one SPI command. 101 | // ---------------------------------------------------------------------- 102 | static void spi ( byte_t* cmd, byte_t* res ) 103 | { 104 | byte_t i; 105 | byte_t c; 106 | byte_t r; 107 | byte_t mask; 108 | 109 | for ( i = 0; i < 4; i++ ) 110 | { 111 | c = *cmd++; 112 | r = 0; 113 | for ( mask = 0x80; mask; mask >>= 1 ) 114 | { 115 | if ( c & mask ) 116 | { 117 | PORT |= MOSI_MASK; 118 | } 119 | delay(); 120 | PORT |= SCK_MASK; 121 | delay(); 122 | r <<= 1; 123 | if ( PIN & MISO_MASK ) 124 | { 125 | r++; 126 | } 127 | PORT &= ~ MOSI_MASK; 128 | PORT &= ~ SCK_MASK; 129 | } 130 | *res++ = r; 131 | } 132 | } 133 | 134 | // ---------------------------------------------------------------------- 135 | // Create and issue a read or write SPI command. 136 | // ---------------------------------------------------------------------- 137 | static void spi_rw ( void ) 138 | { 139 | uint_t a; 140 | 141 | a = address++; 142 | if ( cmd0 & 0x80 ) 143 | { // eeprom 144 | a <<= 1; 145 | } 146 | cmd[0] = cmd0; 147 | if ( a & 1 ) 148 | { 149 | cmd[0] |= 0x08; 150 | } 151 | cmd[1] = a >> 9; 152 | cmd[2] = a >> 1; 153 | spi( cmd, res ); 154 | } 155 | 156 | static uchar dataBuffer[8]; /* buffer must stay valid when usbFunctionSetup returns */ 157 | // ---------------------------------------------------------------------- 158 | // Handle a non-standard SETUP packet. 159 | // ---------------------------------------------------------------------- 160 | extern usbMsgLen_t usbFunctionSetup ( byte_t data[8] ) 161 | { 162 | byte_t bit; 163 | byte_t mask; 164 | byte_t* addr; 165 | byte_t req; 166 | byte_t i; 167 | 168 | // Generic requests 169 | req = data[1]; 170 | if ( req == USBTINY_ECHO ) 171 | { 172 | for ( i = 0; i < 8; i++ ) 173 | { 174 | dataBuffer[i] = data[i]; 175 | } 176 | usbMsgPtr = dataBuffer; 177 | return 8; 178 | } 179 | addr = (byte_t*) (int) data[4]; 180 | if ( req == USBTINY_READ ) 181 | { 182 | dataBuffer[0] = *addr; 183 | usbMsgPtr = dataBuffer; 184 | return 1; 185 | } 186 | if ( req == USBTINY_WRITE ) 187 | { 188 | *addr = data[2]; 189 | return 0; 190 | } 191 | bit = data[2] & 7; 192 | mask = 1 << bit; 193 | if ( req == USBTINY_CLR ) 194 | { 195 | *addr &= ~ mask; 196 | return 0; 197 | } 198 | if ( req == USBTINY_SET ) 199 | { 200 | *addr |= mask; 201 | return 0; 202 | } 203 | 204 | // Programming requests 205 | if ( req == USBTINY_POWERUP ) 206 | { 207 | sck_period = data[2]; 208 | mask = POWER_MASK; 209 | if ( data[4] ) 210 | { 211 | mask |= RESET_MASK; 212 | } 213 | DDR |= ALL_MASK; 214 | PORT = (PORT & ~ ALL_MASK) | mask; 215 | return 0; 216 | } 217 | if ( req == USBTINY_POWERDOWN ) 218 | { 219 | PORT |= RESET_MASK; 220 | PORT &= ~ ALL_MASK; 221 | DDR &= ~ ALL_MASK; 222 | return 0; 223 | } 224 | if ( ! PORT ) 225 | { 226 | return 0; 227 | } 228 | if ( req == USBTINY_SPI ) 229 | { 230 | spi( data + 2, dataBuffer ); 231 | usbMsgPtr = dataBuffer; 232 | return 4; 233 | } 234 | if ( req == USBTINY_POLL_BYTES ) 235 | { 236 | poll1 = data[2]; 237 | poll2 = data[3]; 238 | return 0; 239 | } 240 | address = * (uint_t*) & data[4]; 241 | if ( req == USBTINY_FLASH_READ ) 242 | { 243 | cmd0 = 0x20; 244 | return USB_NO_MSG; // usbFunctionRead() will be called to get the data 245 | } 246 | if ( req == USBTINY_EEPROM_READ ) 247 | { 248 | cmd0 = 0xa0; 249 | return USB_NO_MSG; // usbFunctionRead() will be called to get the data 250 | } 251 | timeout = * (uint_t*) & data[2]; 252 | if ( req == USBTINY_FLASH_WRITE ) 253 | { 254 | cmd0 = 0x40; 255 | return USB_NO_MSG; // data will be received by usbFunctionWrite() 256 | } 257 | if ( req == USBTINY_EEPROM_WRITE ) 258 | { 259 | cmd0 = 0xc0; 260 | return USB_NO_MSG; // data will be received by usbFunctionWrite() 261 | } 262 | return 0; 263 | } 264 | 265 | // ---------------------------------------------------------------------- 266 | // Handle an IN packet. 267 | // ---------------------------------------------------------------------- 268 | extern byte_t usbFunctionRead ( byte_t* data, byte_t len ) 269 | { 270 | byte_t i; 271 | 272 | for ( i = 0; i < len; i++ ) 273 | { 274 | spi_rw(); 275 | data[i] = res[3]; 276 | } 277 | return len; 278 | } 279 | 280 | // ---------------------------------------------------------------------- 281 | // Handle an OUT packet. 282 | // ---------------------------------------------------------------------- 283 | extern byte_t usbFunctionWrite ( byte_t* data, byte_t len ) 284 | { 285 | byte_t i; 286 | uint_t usec; 287 | byte_t r; 288 | 289 | for ( i = 0; i < len; i++ ) 290 | { 291 | cmd[3] = data[i]; 292 | spi_rw(); 293 | cmd[0] ^= 0x60; // turn write into read 294 | for ( usec = 0; usec < timeout; usec += 32 * sck_period ) 295 | { // when timeout > 0, poll until byte is written 296 | spi( cmd, res ); 297 | r = res[3]; 298 | if ( r == cmd[3] && r != poll1 && r != poll2 ) 299 | { 300 | break; 301 | } 302 | } 303 | } 304 | 305 | return 1; 306 | } 307 | 308 | /* ------------------------------------------------------------------------- */ 309 | 310 | int main(void) 311 | { 312 | uchar i; 313 | 314 | wdt_enable(WDTO_1S); 315 | /* Even if you don't use the watchdog, turn it off here. On newer devices, 316 | * the status of the watchdog (on/off, period) is PRESERVED OVER RESET! 317 | */ 318 | DBG1(0x00, 0, 0); /* debug output: main starts */ 319 | /* RESET status: all port bits are inputs without pull-up. 320 | * That's the way we need D+ and D-. Therefore we don't need any 321 | * additional hardware initialization. 322 | */ 323 | odDebugInit(); 324 | usbInit(); 325 | usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */ 326 | i = 0; 327 | while(--i){ /* fake USB disconnect for > 250 ms */ 328 | wdt_reset(); 329 | _delay_ms(1); 330 | } 331 | usbDeviceConnect(); 332 | sei(); 333 | DBG1(0x01, 0, 0); /* debug output: main loop starts */ 334 | for(;;){ /* main event loop */ 335 | DBG1(0x02, 0, 0); /* debug output: main loop iterates */ 336 | wdt_reset(); 337 | usbPoll(); 338 | } 339 | return 0; 340 | } 341 | 342 | /* ------------------------------------------------------------------------- */ 343 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ArduinoISP firwmare sources: 2 | 3 | To compile sources you need avr-gcc (the provided binary files are compiled with avr-gcc 4.5.3). 4 | 5 | You also need an AVRISP mkII programmer to write the firwmare into the device. If you want to use another programmer you have to modify the makefile and change the command line for avrdude in order to match your programmer. 6 | Just move into the code folder with the terminal and use: 7 | 8 | *make hex* 9 | 10 | Then write the binary file into the microcontroller with 11 | 12 | *sudo make program* 13 | -------------------------------------------------------------------------------- /usbconfig.h: -------------------------------------------------------------------------------- 1 | /* Name: usbconfig.h 2 | * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers 3 | * Author: Christian Starkjohann 4 | * Creation Date: 2005-04-01 5 | * Tabsize: 4 6 | * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH 7 | * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) 8 | * This Revision: $Id: usbconfig-prototype.h 767 2009-08-22 11:39:22Z cs $ 9 | */ 10 | 11 | #ifndef __usbconfig_h_included__ 12 | #define __usbconfig_h_included__ 13 | 14 | /* 15 | General Description: 16 | This file is an example configuration (with inline documentation) for the USB 17 | driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is 18 | also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may 19 | wire the lines to any other port, as long as D+ is also wired to INT0 (or any 20 | other hardware interrupt, as long as it is the highest level interrupt, see 21 | section at the end of this file). 22 | */ 23 | 24 | /* ---------------------------- Hardware Config ---------------------------- */ 25 | 26 | #define USB_CFG_IOPORTNAME A 27 | /* This is the port where the USB bus is connected. When you configure it to 28 | * "B", the registers PORTB, PINB and DDRB will be used. 29 | */ 30 | #define USB_CFG_DMINUS_BIT 0 31 | /* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected. 32 | * This may be any bit in the port. 33 | */ 34 | #define USB_CFG_DPLUS_BIT 7 35 | /* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected. 36 | * This may be any bit in the port. Please note that D+ must also be connected 37 | * to interrupt pin INT0! [You can also use other interrupts, see section 38 | * "Optional MCU Description" below, or you can connect D- to the interrupt, as 39 | * it is required if you use the USB_COUNT_SOF feature. If you use D- for the 40 | * interrupt, the USB interrupt will also be triggered at Start-Of-Frame 41 | * markers every millisecond.] 42 | */ 43 | #define USB_CFG_CLOCK_KHZ (F_CPU/1000) 44 | /* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000, 45 | * 16500 and 20000. The 12.8 MHz and 16.5 MHz versions of the code require no 46 | * crystal, they tolerate +/- 1% deviation from the nominal frequency. All 47 | * other rates require a precision of 2000 ppm and thus a crystal! 48 | * Default if not specified: 12 MHz 49 | */ 50 | #define USB_CFG_CHECK_CRC 0 51 | /* Define this to 1 if you want that the driver checks integrity of incoming 52 | * data packets (CRC checks). CRC checks cost quite a bit of code size and are 53 | * currently only available for 18 MHz crystal clock. You must choose 54 | * USB_CFG_CLOCK_KHZ = 18000 if you enable this option. 55 | */ 56 | 57 | /* ----------------------- Optional Hardware Config ------------------------ */ 58 | 59 | /* #define USB_CFG_PULLUP_IOPORTNAME D */ 60 | /* If you connect the 1.5k pullup resistor from D- to a port pin instead of 61 | * V+, you can connect and disconnect the device from firmware by calling 62 | * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h). 63 | * This constant defines the port on which the pullup resistor is connected. 64 | */ 65 | /* #define USB_CFG_PULLUP_BIT 4 */ 66 | /* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined 67 | * above) where the 1.5k pullup resistor is connected. See description 68 | * above for details. 69 | */ 70 | 71 | /* --------------------------- Functional Range ---------------------------- */ 72 | 73 | #define USB_CFG_HAVE_INTRIN_ENDPOINT 0 74 | /* Define this to 1 if you want to compile a version with two endpoints: The 75 | * default control endpoint 0 and an interrupt-in endpoint (any other endpoint 76 | * number). 77 | */ 78 | #define USB_CFG_HAVE_INTRIN_ENDPOINT3 0 79 | /* Define this to 1 if you want to compile a version with three endpoints: The 80 | * default control endpoint 0, an interrupt-in endpoint 3 (or the number 81 | * configured below) and a catch-all default interrupt-in endpoint as above. 82 | * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature. 83 | */ 84 | #define USB_CFG_EP3_NUMBER 3 85 | /* If the so-called endpoint 3 is used, it can now be configured to any other 86 | * endpoint number (except 0) with this macro. Default if undefined is 3. 87 | */ 88 | /* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */ 89 | /* The above macro defines the startup condition for data toggling on the 90 | * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1. 91 | * Since the token is toggled BEFORE sending any data, the first packet is 92 | * sent with the oposite value of this configuration! 93 | */ 94 | #define USB_CFG_IMPLEMENT_HALT 0 95 | /* Define this to 1 if you also want to implement the ENDPOINT_HALT feature 96 | * for endpoint 1 (interrupt endpoint). Although you may not need this feature, 97 | * it is required by the standard. We have made it a config option because it 98 | * bloats the code considerably. 99 | */ 100 | #define USB_CFG_SUPPRESS_INTR_CODE 0 101 | /* Define this to 1 if you want to declare interrupt-in endpoints, but don't 102 | * want to send any data over them. If this macro is defined to 1, functions 103 | * usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if 104 | * you need the interrupt-in endpoints in order to comply to an interface 105 | * (e.g. HID), but never want to send any data. This option saves a couple 106 | * of bytes in flash memory and the transmit buffers in RAM. 107 | */ 108 | #define USB_CFG_INTR_POLL_INTERVAL 10 109 | /* If you compile a version with endpoint 1 (interrupt-in), this is the poll 110 | * interval. The value is in milliseconds and must not be less than 10 ms for 111 | * low speed devices. 112 | */ 113 | #define USB_CFG_IS_SELF_POWERED 0 114 | /* Define this to 1 if the device has its own power supply. Set it to 0 if the 115 | * device is powered from the USB bus. 116 | */ 117 | #define USB_CFG_MAX_BUS_POWER 40 118 | /* Set this variable to the maximum USB bus power consumption of your device. 119 | * The value is in milliamperes. [It will be divided by two since USB 120 | * communicates power requirements in units of 2 mA.] 121 | */ 122 | #define USB_CFG_IMPLEMENT_FN_WRITE 1 123 | /* Set this to 1 if you want usbFunctionWrite() to be called for control-out 124 | * transfers. Set it to 0 if you don't need it and want to save a couple of 125 | * bytes. 126 | */ 127 | #define USB_CFG_IMPLEMENT_FN_READ 1 128 | /* Set this to 1 if you need to send control replies which are generated 129 | * "on the fly" when usbFunctionRead() is called. If you only want to send 130 | * data from a static buffer, set it to 0 and return the data from 131 | * usbFunctionSetup(). This saves a couple of bytes. 132 | */ 133 | #define USB_CFG_IMPLEMENT_FN_WRITEOUT 0 134 | /* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints. 135 | * You must implement the function usbFunctionWriteOut() which receives all 136 | * interrupt/bulk data sent to any endpoint other than 0. The endpoint number 137 | * can be found in 'usbRxToken'. 138 | */ 139 | #define USB_CFG_HAVE_FLOWCONTROL 0 140 | /* Define this to 1 if you want flowcontrol over USB data. See the definition 141 | * of the macros usbDisableAllRequests() and usbEnableAllRequests() in 142 | * usbdrv.h. 143 | */ 144 | #define USB_CFG_LONG_TRANSFERS 0 145 | /* Define this to 1 if you want to send/receive blocks of more than 254 bytes 146 | * in a single control-in or control-out transfer. Note that the capability 147 | * for long transfers increases the driver size. 148 | */ 149 | /* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */ 150 | /* This macro is a hook if you want to do unconventional things. If it is 151 | * defined, it's inserted at the beginning of received message processing. 152 | * If you eat the received message and don't want default processing to 153 | * proceed, do a return after doing your things. One possible application 154 | * (besides debugging) is to flash a status LED on each packet. 155 | */ 156 | /* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */ 157 | /* This macro is a hook if you need to know when an USB RESET occurs. It has 158 | * one parameter which distinguishes between the start of RESET state and its 159 | * end. 160 | */ 161 | /* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */ 162 | /* This macro (if defined) is executed when a USB SET_ADDRESS request was 163 | * received. 164 | */ 165 | #define USB_COUNT_SOF 0 166 | /* define this macro to 1 if you need the global variable "usbSofCount" which 167 | * counts SOF packets. This feature requires that the hardware interrupt is 168 | * connected to D- instead of D+. 169 | */ 170 | /* #ifdef __ASSEMBLER__ 171 | * macro myAssemblerMacro 172 | * in YL, TCNT0 173 | * sts timer0Snapshot, YL 174 | * endm 175 | * #endif 176 | * #define USB_SOF_HOOK myAssemblerMacro 177 | * This macro (if defined) is executed in the assembler module when a 178 | * Start Of Frame condition is detected. It is recommended to define it to 179 | * the name of an assembler macro which is defined here as well so that more 180 | * than one assembler instruction can be used. The macro may use the register 181 | * YL and modify SREG. If it lasts longer than a couple of cycles, USB messages 182 | * immediately after an SOF pulse may be lost and must be retried by the host. 183 | * What can you do with this hook? Since the SOF signal occurs exactly every 184 | * 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in 185 | * designs running on the internal RC oscillator. 186 | * Please note that Start Of Frame detection works only if D- is wired to the 187 | * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES! 188 | */ 189 | #define USB_CFG_CHECK_DATA_TOGGLING 0 190 | /* define this macro to 1 if you want to filter out duplicate data packets 191 | * sent by the host. Duplicates occur only as a consequence of communication 192 | * errors, when the host does not receive an ACK. Please note that you need to 193 | * implement the filtering yourself in usbFunctionWriteOut() and 194 | * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable 195 | * for each control- and out-endpoint to check for duplicate packets. 196 | */ 197 | #define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0 198 | /* define this macro to 1 if you want the function usbMeasureFrameLength() 199 | * compiled in. This function can be used to calibrate the AVR's RC oscillator. 200 | */ 201 | #define USB_USE_FAST_CRC 0 202 | /* The assembler module has two implementations for the CRC algorithm. One is 203 | * faster, the other is smaller. This CRC routine is only used for transmitted 204 | * messages where timing is not critical. The faster routine needs 31 cycles 205 | * per byte while the smaller one needs 61 to 69 cycles. The faster routine 206 | * may be worth the 32 bytes bigger code size if you transmit lots of data and 207 | * run the AVR close to its limit. 208 | */ 209 | 210 | /* -------------------------- Device Description --------------------------- */ 211 | 212 | #define USB_CFG_VENDOR_ID 0x41, 0x23 /* = 0x2341 = Arduino */ 213 | /* USB vendor ID for the device, low byte first. If you have registered your 214 | * own Vendor ID, define it here. Otherwise you may use one of obdev's free 215 | * shared VID/PID pairs. Be sure to read USB-IDs-for-free.txt for rules! 216 | */ 217 | #define USB_CFG_DEVICE_ID 0x49, 0x00 /* = 0x0049 = arduinoisp */ 218 | /* This is the ID of the product, low byte first. It is interpreted in the 219 | * scope of the vendor ID. If you have registered your own VID with usb.org 220 | * or if you have licensed a PID from somebody else, define it here. Otherwise 221 | * you may use one of obdev's free shared VID/PID pairs. See the file 222 | * USB-IDs-for-free.txt for details! 223 | */ 224 | #define USB_CFG_DEVICE_VERSION 0x04, 0x01 225 | /* Version number of the device: Minor number first, then major number. 226 | */ 227 | /* #define USB_CFG_VENDOR_NAME 'o', 'b', 'd', 'e', 'v', '.', 'a', 't' */ 228 | /* #define USB_CFG_VENDOR_NAME_LEN 8 */ 229 | /* These two values define the vendor name returned by the USB device. The name 230 | * must be given as a list of characters under single quotes. The characters 231 | * are interpreted as Unicode (UTF-16) entities. 232 | * If you don't want a vendor name string, undefine these macros. 233 | * ALWAYS define a vendor name containing your Internet domain name if you use 234 | * obdev's free shared VID/PID pair. See the file USB-IDs-for-free.txt for 235 | * details. 236 | */ 237 | #define USB_CFG_DEVICE_NAME 'A', 'r', 'd', 'u', 'i', 'n', 'o', 'I', 'S', 'P' 238 | #define USB_CFG_DEVICE_NAME_LEN 10 239 | /* Same as above for the device name. If you don't want a device name, undefine 240 | * the macros. See the file USB-IDs-for-free.txt before you assign a name if 241 | * you use a shared VID/PID. 242 | */ 243 | /*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */ 244 | /*#define USB_CFG_SERIAL_NUMBER_LEN 0 */ 245 | /* Same as above for the serial number. If you don't want a serial number, 246 | * undefine the macros. 247 | * It may be useful to provide the serial number through other means than at 248 | * compile time. See the section about descriptor properties below for how 249 | * to fine tune control over USB descriptors such as the string descriptor 250 | * for the serial number. 251 | */ 252 | #define USB_CFG_DEVICE_CLASS 0xff /* set to 0 if deferred to interface */ 253 | #define USB_CFG_DEVICE_SUBCLASS 0 254 | /* See USB specification if you want to conform to an existing device class. 255 | * Class 0xff is "vendor specific". 256 | */ 257 | #define USB_CFG_INTERFACE_CLASS 0xff /* define class here if not at device level */ 258 | #define USB_CFG_INTERFACE_SUBCLASS 0 259 | #define USB_CFG_INTERFACE_PROTOCOL 0 260 | /* See USB specification if you want to conform to an existing device class or 261 | * protocol. The following classes must be set at interface level: 262 | * HID class is 3, no subclass and protocol required (but may be useful!) 263 | * CDC class is 2, use subclass 2 and protocol 1 for ACM 264 | */ 265 | /* #define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 42 */ 266 | /* Define this to the length of the HID report descriptor, if you implement 267 | * an HID device. Otherwise don't define it or define it to 0. 268 | * If you use this define, you must add a PROGMEM character array named 269 | * "usbHidReportDescriptor" to your code which contains the report descriptor. 270 | * Don't forget to keep the array and this define in sync! 271 | */ 272 | 273 | /* #define USB_PUBLIC static */ 274 | /* Use the define above if you #include usbdrv.c instead of linking against it. 275 | * This technique saves a couple of bytes in flash memory. 276 | */ 277 | 278 | /* ------------------- Fine Control over USB Descriptors ------------------- */ 279 | /* If you don't want to use the driver's default USB descriptors, you can 280 | * provide our own. These can be provided as (1) fixed length static data in 281 | * flash memory, (2) fixed length static data in RAM or (3) dynamically at 282 | * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more 283 | * information about this function. 284 | * Descriptor handling is configured through the descriptor's properties. If 285 | * no properties are defined or if they are 0, the default descriptor is used. 286 | * Possible properties are: 287 | * + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched 288 | * at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is 289 | * used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if 290 | * you want RAM pointers. 291 | * + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found 292 | * in static memory is in RAM, not in flash memory. 293 | * + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash), 294 | * the driver must know the descriptor's length. The descriptor itself is 295 | * found at the address of a well known identifier (see below). 296 | * List of static descriptor names (must be declared PROGMEM if in flash): 297 | * char usbDescriptorDevice[]; 298 | * char usbDescriptorConfiguration[]; 299 | * char usbDescriptorHidReport[]; 300 | * char usbDescriptorString0[]; 301 | * int usbDescriptorStringVendor[]; 302 | * int usbDescriptorStringDevice[]; 303 | * int usbDescriptorStringSerialNumber[]; 304 | * Other descriptors can't be provided statically, they must be provided 305 | * dynamically at runtime. 306 | * 307 | * Descriptor properties are or-ed or added together, e.g.: 308 | * #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18)) 309 | * 310 | * The following descriptors are defined: 311 | * USB_CFG_DESCR_PROPS_DEVICE 312 | * USB_CFG_DESCR_PROPS_CONFIGURATION 313 | * USB_CFG_DESCR_PROPS_STRINGS 314 | * USB_CFG_DESCR_PROPS_STRING_0 315 | * USB_CFG_DESCR_PROPS_STRING_VENDOR 316 | * USB_CFG_DESCR_PROPS_STRING_PRODUCT 317 | * USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 318 | * USB_CFG_DESCR_PROPS_HID 319 | * USB_CFG_DESCR_PROPS_HID_REPORT 320 | * USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver) 321 | * 322 | * Note about string descriptors: String descriptors are not just strings, they 323 | * are Unicode strings prefixed with a 2 byte header. Example: 324 | * int serialNumberDescriptor[] = { 325 | * USB_STRING_DESCRIPTOR_HEADER(6), 326 | * 'S', 'e', 'r', 'i', 'a', 'l' 327 | * }; 328 | */ 329 | 330 | #define USB_CFG_DESCR_PROPS_DEVICE 0 331 | #define USB_CFG_DESCR_PROPS_CONFIGURATION 0 332 | #define USB_CFG_DESCR_PROPS_STRINGS 0 333 | #define USB_CFG_DESCR_PROPS_STRING_0 0 334 | #define USB_CFG_DESCR_PROPS_STRING_VENDOR 0 335 | #define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0 336 | #define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0 337 | #define USB_CFG_DESCR_PROPS_HID 0 338 | #define USB_CFG_DESCR_PROPS_HID_REPORT 0 339 | #define USB_CFG_DESCR_PROPS_UNKNOWN 0 340 | 341 | /* ----------------------- Optional MCU Description ------------------------ */ 342 | 343 | /* The following configurations have working defaults in usbdrv.h. You 344 | * usually don't need to set them explicitly. Only if you want to run 345 | * the driver on a device which is not yet supported or with a compiler 346 | * which is not fully supported (such as IAR C) or if you use a differnt 347 | * interrupt than INT0, you may have to define some of these. 348 | */ 349 | /* #define USB_INTR_CFG MCUCR */ 350 | /* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */ 351 | /* #define USB_INTR_CFG_CLR 0 */ 352 | /* #define USB_INTR_ENABLE GIMSK */ 353 | /* #define USB_INTR_ENABLE_BIT INT0 */ 354 | /* #define USB_INTR_PENDING GIFR */ 355 | /* #define USB_INTR_PENDING_BIT INTF0 */ 356 | /* #define USB_INTR_VECTOR SIG_INTERRUPT0 */ 357 | 358 | #endif /* __usbconfig_h_included__ */ 359 | -------------------------------------------------------------------------------- /usbdrv/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/ArduinoISP/95dc3acaf2bdc01bcaee3743c9449c01c6362b19/usbdrv/.DS_Store -------------------------------------------------------------------------------- /usbdrv/Changelog.txt: -------------------------------------------------------------------------------- 1 | This file documents changes in the firmware-only USB driver for atmel's AVR 2 | microcontrollers. New entries are always appended to the end of the file. 3 | Scroll down to the bottom to see the most recent changes. 4 | 5 | 2005-04-01: 6 | - Implemented endpoint 1 as interrupt-in endpoint. 7 | - Moved all configuration options to usbconfig.h which is not part of the 8 | driver. 9 | - Changed interface for usbVendorSetup(). 10 | - Fixed compatibility with ATMega8 device. 11 | - Various minor optimizations. 12 | 13 | 2005-04-11: 14 | - Changed interface to application: Use usbFunctionSetup(), usbFunctionRead() 15 | and usbFunctionWrite() now. Added configuration options to choose which 16 | of these functions to compile in. 17 | - Assembler module delivers receive data non-inverted now. 18 | - Made register and bit names compatible with more AVR devices. 19 | 20 | 2005-05-03: 21 | - Allow address of usbRxBuf on any memory page as long as the buffer does 22 | not cross 256 byte page boundaries. 23 | - Better device compatibility: works with Mega88 now. 24 | - Code optimization in debugging module. 25 | - Documentation updates. 26 | 27 | 2006-01-02: 28 | - Added (free) default Vendor- and Product-IDs bought from voti.nl. 29 | - Added USBID-License.txt file which defines the rules for using the free 30 | shared VID/PID pair. 31 | - Added Readme.txt to the usbdrv directory which clarifies administrative 32 | issues. 33 | 34 | 2006-01-25: 35 | - Added "configured state" to become more standards compliant. 36 | - Added "HALT" state for interrupt endpoint. 37 | - Driver passes the "USB Command Verifier" test from usb.org now. 38 | - Made "serial number" a configuration option. 39 | - Minor optimizations, we now recommend compiler option "-Os" for best 40 | results. 41 | - Added a version number to usbdrv.h 42 | 43 | 2006-02-03: 44 | - New configuration variable USB_BUFFER_SECTION for the memory section where 45 | the USB rx buffer will go. This defaults to ".bss" if not defined. Since 46 | this buffer MUST NOT cross 256 byte pages (not even touch a page at the 47 | end), the user may want to pass a linker option similar to 48 | "-Wl,--section-start=.mybuffer=0x800060". 49 | - Provide structure for usbRequest_t. 50 | - New defines for USB constants. 51 | - Prepared for HID implementations. 52 | - Increased data size limit for interrupt transfers to 8 bytes. 53 | - New macro usbInterruptIsReady() to query interrupt buffer state. 54 | 55 | 2006-02-18: 56 | - Ensure that the data token which is sent as an ack to an OUT transfer is 57 | always zero sized. This fixes a bug where the host reports an error after 58 | sending an out transfer to the device, although all data arrived at the 59 | device. 60 | - Updated docs in usbdrv.h to reflect changed API in usbFunctionWrite(). 61 | 62 | * Release 2006-02-20 63 | 64 | - Give a compiler warning when compiling with debugging turned on. 65 | - Added Oleg Semyonov's changes for IAR-cc compatibility. 66 | - Added new (optional) functions usbDeviceConnect() and usbDeviceDisconnect() 67 | (also thanks to Oleg!). 68 | - Rearranged tests in usbPoll() to save a couple of instructions in the most 69 | likely case that no actions are pending. 70 | - We need a delay between the SET ADDRESS request until the new address 71 | becomes active. This delay was handled in usbPoll() until now. Since the 72 | spec says that the delay must not exceed 2ms, previous versions required 73 | aggressive polling during the enumeration phase. We have now moved the 74 | handling of the delay into the interrupt routine. 75 | - We must not reply with NAK to a SETUP transaction. We can only achieve this 76 | by making sure that the rx buffer is empty when SETUP tokens are expected. 77 | We therefore don't pass zero sized data packets from the status phase of 78 | a transfer to usbPoll(). This change MAY cause troubles if you rely on 79 | receiving a less than 8 bytes long packet in usbFunctionWrite() to 80 | identify the end of a transfer. usbFunctionWrite() will NEVER be called 81 | with a zero length. 82 | 83 | * Release 2006-03-14 84 | 85 | - Improved IAR C support: tiny memory model, more devices 86 | - Added template usbconfig.h file under the name usbconfig-prototype.h 87 | 88 | * Release 2006-03-26 89 | 90 | - Added provision for one more interrupt-in endpoint (endpoint 3). 91 | - Added provision for one interrupt-out endpoint (endpoint 1). 92 | - Added flowcontrol macros for USB. 93 | - Added provision for custom configuration descriptor. 94 | - Allow ANY two port bits for D+ and D-. 95 | - Merged (optional) receive endpoint number into global usbRxToken variable. 96 | - Use USB_CFG_IOPORTNAME instead of USB_CFG_IOPORT. We now construct the 97 | variable name from the single port letter instead of computing the address 98 | of related ports from the output-port address. 99 | 100 | * Release 2006-06-26 101 | 102 | - Updated documentation in usbdrv.h and usbconfig-prototype.h to reflect the 103 | new features. 104 | - Removed "#warning" directives because IAR does not understand them. Use 105 | unused static variables instead to generate a warning. 106 | - Do not include when compiling with IAR. 107 | - Introduced USB_CFG_DESCR_PROPS_* in usbconfig.h to configure how each 108 | USB descriptor should be handled. It is now possible to provide descriptor 109 | data in Flash, RAM or dynamically at runtime. 110 | - STALL is now a status in usbTxLen* instead of a message. We can now conform 111 | to the spec and leave the stall status pending until it is cleared. 112 | - Made usbTxPacketCnt1 and usbTxPacketCnt3 public. This allows the 113 | application code to reset data toggling on interrupt pipes. 114 | 115 | * Release 2006-07-18 116 | 117 | - Added an #if !defined __ASSEMBLER__ to the warning in usbdrv.h. This fixes 118 | an assembler error. 119 | - usbDeviceDisconnect() takes pull-up resistor to high impedance now. 120 | 121 | * Release 2007-02-01 122 | 123 | - Merged in some code size improvements from usbtiny (thanks to Dick 124 | Streefland for these optimizations!) 125 | - Special alignment requirement for usbRxBuf not required any more. Thanks 126 | again to Dick Streefland for this hint! 127 | - Reverted to "#warning" instead of unused static variables -- new versions 128 | of IAR CC should handle this directive. 129 | - Changed Open Source license to GNU GPL v2 in order to make linking against 130 | other free libraries easier. We no longer require publication of the 131 | circuit diagrams, but we STRONGLY encourage it. If you improve the driver 132 | itself, PLEASE grant us a royalty free license to your changes for our 133 | commercial license. 134 | 135 | * Release 2007-03-29 136 | 137 | - New configuration option "USB_PUBLIC" in usbconfig.h. 138 | - Set USB version number to 1.10 instead of 1.01. 139 | - Code used USB_CFG_DESCR_PROPS_STRING_DEVICE and 140 | USB_CFG_DESCR_PROPS_STRING_PRODUCT inconsistently. Changed all occurrences 141 | to USB_CFG_DESCR_PROPS_STRING_PRODUCT. 142 | - New assembler module for 16.5 MHz RC oscillator clock with PLL in receiver 143 | code. 144 | - New assembler module for 16 MHz crystal. 145 | - usbdrvasm.S contains common code only, clock-specific parts have been moved 146 | to usbdrvasm12.S, usbdrvasm16.S and usbdrvasm165.S respectively. 147 | 148 | * Release 2007-06-25 149 | 150 | - 16 MHz module: Do SE0 check in stuffed bits as well. 151 | 152 | * Release 2007-07-07 153 | 154 | - Define hi8(x) for IAR compiler to limit result to 8 bits. This is necessary 155 | for negative values. 156 | - Added 15 MHz module contributed by V. Bosch. 157 | - Interrupt vector name can now be configured. This is useful if somebody 158 | wants to use a different hardware interrupt than INT0. 159 | 160 | * Release 2007-08-07 161 | 162 | - Moved handleIn3 routine in usbdrvasm16.S so that relative jump range is 163 | not exceeded. 164 | - More config options: USB_RX_USER_HOOK(), USB_INITIAL_DATATOKEN, 165 | USB_COUNT_SOF 166 | - USB_INTR_PENDING can now be a memory address, not just I/O 167 | 168 | * Release 2007-09-19 169 | 170 | - Split out common parts of assembler modules into separate include file 171 | - Made endpoint numbers configurable so that given interface definitions 172 | can be matched. See USB_CFG_EP3_NUMBER in usbconfig-prototype.h. 173 | - Store endpoint number for interrupt/bulk-out so that usbFunctionWriteOut() 174 | can handle any number of endpoints. 175 | - Define usbDeviceConnect() and usbDeviceDisconnect() even if no 176 | USB_CFG_PULLUP_IOPORTNAME is defined. Directly set D+ and D- to 0 in this 177 | case. 178 | 179 | * Release 2007-12-01 180 | 181 | - Optimize usbDeviceConnect() and usbDeviceDisconnect() for less code size 182 | when USB_CFG_PULLUP_IOPORTNAME is not defined. 183 | 184 | * Release 2007-12-13 185 | 186 | - Renamed all include-only assembler modules from *.S to *.inc so that 187 | people don't add them to their project sources. 188 | - Distribute leap bits in tx loop more evenly for 16 MHz module. 189 | - Use "macro" and "endm" instead of ".macro" and ".endm" for IAR 190 | - Avoid compiler warnings for constant expr range by casting some values in 191 | USB descriptors. 192 | 193 | * Release 2008-01-21 194 | 195 | - Fixed bug in 15 and 16 MHz module where the new address set with 196 | SET_ADDRESS was already accepted at the next NAK or ACK we send, not at 197 | the next data packet we send. This caused problems when the host polled 198 | too fast. Thanks to Alexander Neumann for his help and patience debugging 199 | this issue! 200 | 201 | * Release 2008-02-05 202 | 203 | - Fixed bug in 16.5 MHz module where a register was used in the interrupt 204 | handler before it was pushed. This bug was introduced with version 205 | 2007-09-19 when common parts were moved to a separate file. 206 | - Optimized CRC routine (thanks to Reimar Doeffinger). 207 | 208 | * Release 2008-02-16 209 | 210 | - Removed outdated IAR compatibility stuff (code sections). 211 | - Added hook macros for USB_RESET_HOOK() and USB_SET_ADDRESS_HOOK(). 212 | - Added optional routine usbMeasureFrameLength() for calibration of the 213 | internal RC oscillator. 214 | 215 | * Release 2008-02-28 216 | 217 | - USB_INITIAL_DATATOKEN defaults to USBPID_DATA1 now, which means that we 218 | start with sending USBPID_DATA0. 219 | - Changed defaults in usbconfig-prototype.h 220 | - Added free USB VID/PID pair for MIDI class devices 221 | - Restructured AVR-USB as separate package, not part of PowerSwitch any more. 222 | 223 | * Release 2008-04-18 224 | 225 | - Restructured usbdrv.c so that it is easier to read and understand. 226 | - Better code optimization with gcc 4. 227 | - If a second interrupt in endpoint is enabled, also add it to config 228 | descriptor. 229 | - Added config option for long transfers (above 254 bytes), see 230 | USB_CFG_LONG_TRANSFERS in usbconfig.h. 231 | - Added 20 MHz module contributed by Jeroen Benschop. 232 | 233 | * Release 2008-05-13 234 | 235 | - Fixed bug in libs-host/hiddata.c function usbhidGetReport(): length 236 | was not incremented, pointer to length was incremented instead. 237 | - Added code to command line tool(s) which claims an interface. This code 238 | is disabled by default, but may be necessary on newer Linux kernels. 239 | - Added usbconfig.h option "USB_CFG_CHECK_DATA_TOGGLING". 240 | - New header "usbportability.h" prepares ports to other development 241 | environments. 242 | - Long transfers (above 254 bytes) did not work when usbFunctionRead() was 243 | used to supply the data. Fixed this bug. [Thanks to Alexander Neumann!] 244 | - In hiddata.c (example code for sending/receiving data over HID), use 245 | USB_RECIP_DEVICE instead of USB_RECIP_INTERFACE for control transfers so 246 | that we need not claim the interface. 247 | - in usbPoll() loop 20 times polling for RESET state instead of 10 times. 248 | This accounts for the higher clock rates we now support. 249 | - Added a module for 12.8 MHz RC oscillator with PLL in receiver loop. 250 | - Added hook to SOF code so that oscillator can be tuned to USB frame clock. 251 | - Added timeout to waitForJ loop. Helps preventing unexpected hangs. 252 | - Added example code for oscillator tuning to libs-device (thanks to 253 | Henrik Haftmann for the idea to this routine). 254 | - Implemented option USB_CFG_SUPPRESS_INTR_CODE. 255 | 256 | * Release 2008-10-22 257 | 258 | - Fixed libs-device/osctune.h: OSCCAL is memory address on ATMega88 and 259 | similar, not offset of 0x20 needs to be added. 260 | - Allow distribution under GPLv3 for those who have to link against other 261 | code distributed under GPLv3. 262 | 263 | * Release 2008-11-26 264 | 265 | - Removed libusb-win32 dependency for hid-data example in Makefile.windows. 266 | It was never required and confused many people. 267 | - Added extern uchar usbRxToken to usbdrv.h. 268 | - Integrated a module with CRC checks at 18 MHz by Lukas Schrittwieser. 269 | 270 | * Release 2009-03-23 271 | 272 | - Hid-mouse example used settings from hid-data example, fixed that. 273 | - Renamed project to V-USB due to a trademark issue with Atmel(r). 274 | - Changed CommercialLicense.txt and USBID-License.txt to make the 275 | background of USB ID registration clearer. 276 | 277 | * Release 2009-04-15 278 | 279 | - Changed CommercialLicense.txt to reflect the new range of PIDs from 280 | Jason Kotzin. 281 | - Removed USBID-License.txt in favor of USB-IDs-for-free.txt and 282 | USB-ID-FAQ.txt 283 | - Fixed a bug in the 12.8 MHz module: End Of Packet decection was made in 284 | the center between bit 0 and 1 of each byte. This is where the data lines 285 | are expected to change and the sampled data may therefore be nonsense. 286 | We therefore check EOP ONLY if bits 0 AND 1 have both been read as 0 on D-. 287 | - Fixed a bitstuffing problem in the 16 MHz module: If bit 6 was stuffed, 288 | the unstuffing code in the receiver routine was 1 cycle too long. If 289 | multiple bytes had the unstuffing in bit 6, the error summed up until the 290 | receiver was out of sync. 291 | - Included option for faster CRC routine. 292 | Thanks to Slawomir Fras (BoskiDialer) for this code! 293 | - Updated bits in Configuration Descriptor's bmAttributes according to 294 | USB 1.1 (in particular bit 7, it is a must-be-set bit now). 295 | 296 | * Release 2009-08-22 297 | -------------------------------------------------------------------------------- /usbdrv/CommercialLicense.txt: -------------------------------------------------------------------------------- 1 | V-USB Driver Software License Agreement 2 | Version 2009-08-03 3 | 4 | THIS LICENSE AGREEMENT GRANTS YOU CERTAIN RIGHTS IN A SOFTWARE. YOU CAN 5 | ENTER INTO THIS AGREEMENT AND ACQUIRE THE RIGHTS OUTLINED BELOW BY PAYING 6 | THE AMOUNT ACCORDING TO SECTION 4 ("PAYMENT") TO OBJECTIVE DEVELOPMENT. 7 | 8 | 9 | 1 DEFINITIONS 10 | 11 | 1.1 "OBJECTIVE DEVELOPMENT" shall mean OBJECTIVE DEVELOPMENT Software GmbH, 12 | Grosse Schiffgasse 1A/7, 1020 Wien, AUSTRIA. 13 | 14 | 1.2 "You" shall mean the Licensee. 15 | 16 | 1.3 "V-USB" shall mean all files included in the package distributed under 17 | the name "vusb" by OBJECTIVE DEVELOPMENT (http://www.obdev.at/vusb/) 18 | unless otherwise noted. This includes the firmware-only USB device 19 | implementation for Atmel AVR microcontrollers, some simple device examples 20 | and host side software examples and libraries. 21 | 22 | 23 | 2 LICENSE GRANTS 24 | 25 | 2.1 Source Code. OBJECTIVE DEVELOPMENT shall furnish you with the source 26 | code of V-USB. 27 | 28 | 2.2 Distribution and Use. OBJECTIVE DEVELOPMENT grants you the 29 | non-exclusive right to use, copy and distribute V-USB with your hardware 30 | product(s), restricted by the limitations in section 3 below. 31 | 32 | 2.3 Modifications. OBJECTIVE DEVELOPMENT grants you the right to modify 33 | the source code and your copy of V-USB according to your needs. 34 | 35 | 2.4 USB IDs. OBJECTIVE DEVELOPMENT furnishes you with one or two USB 36 | Product ID(s), sent to you in e-mail. These Product IDs are reserved 37 | exclusively for you. OBJECTIVE DEVELOPMENT has obtained USB Product ID 38 | ranges under the Vendor ID 5824 from Wouter van Ooijen (Van Ooijen 39 | Technische Informatica, www.voti.nl) and under the Vendor ID 8352 from 40 | Jason Kotzin (Clay Logic, www.claylogic.com). Both owners of the Vendor IDs 41 | have obtained these IDs from the USB Implementers Forum, Inc. 42 | (www.usb.org). OBJECTIVE DEVELOPMENT disclaims all liability which might 43 | arise from the assignment of USB IDs. 44 | 45 | 2.5 USB Certification. Although not part of this agreement, we want to make 46 | it clear that you cannot become USB certified when you use V-USB or a USB 47 | Product ID assigned by OBJECTIVE DEVELOPMENT. AVR microcontrollers don't 48 | meet the electrical specifications required by the USB specification and 49 | the USB Implementers Forum certifies only members who bought a Vendor ID of 50 | their own. 51 | 52 | 53 | 3 LICENSE RESTRICTIONS 54 | 55 | 3.1 Number of Units. Only one of the following three definitions is 56 | applicable. Which one is determined by the amount you pay to OBJECTIVE 57 | DEVELOPMENT, see section 4 ("Payment") below. 58 | 59 | Hobby License: You may use V-USB according to section 2 above in no more 60 | than 5 hardware units. These units must not be sold for profit. 61 | 62 | Entry Level License: You may use V-USB according to section 2 above in no 63 | more than 150 hardware units. 64 | 65 | Professional License: You may use V-USB according to section 2 above in 66 | any number of hardware units, except for large scale production ("unlimited 67 | fair use"). Quantities below 10,000 units are not considered large scale 68 | production. If your reach quantities which are obviously large scale 69 | production, you must pay a license fee of 0.10 EUR per unit for all units 70 | above 10,000. 71 | 72 | 3.2 Rental. You may not rent, lease, or lend V-USB or otherwise encumber 73 | any copy of V-USB, or any of the rights granted herein. 74 | 75 | 3.3 Transfer. You may not transfer your rights under this Agreement to 76 | another party without OBJECTIVE DEVELOPMENT's prior written consent. If 77 | such consent is obtained, you may permanently transfer this License to 78 | another party. The recipient of such transfer must agree to all terms and 79 | conditions of this Agreement. 80 | 81 | 3.4 Reservation of Rights. OBJECTIVE DEVELOPMENT retains all rights not 82 | expressly granted. 83 | 84 | 3.5 Non-Exclusive Rights. Your license rights under this Agreement are 85 | non-exclusive. 86 | 87 | 3.6 Third Party Rights. This Agreement cannot grant you rights controlled 88 | by third parties. In particular, you are not allowed to use the USB logo or 89 | other trademarks owned by the USB Implementers Forum, Inc. without their 90 | consent. Since such consent depends on USB certification, it should be 91 | noted that V-USB will not pass certification because it does not 92 | implement checksum verification and the microcontroller ports do not meet 93 | the electrical specifications. 94 | 95 | 96 | 4 PAYMENT 97 | 98 | The payment amount depends on the variation of this agreement (according to 99 | section 3.1) into which you want to enter. Concrete prices are listed on 100 | OBJECTIVE DEVELOPMENT's web site, usually at 101 | http://www.obdev.at/vusb/license.html. You agree to pay the amount listed 102 | there to OBJECTIVE DEVELOPMENT or OBJECTIVE DEVELOPMENT's payment processor 103 | or reseller. 104 | 105 | 106 | 5 COPYRIGHT AND OWNERSHIP 107 | 108 | V-USB is protected by copyright laws and international copyright 109 | treaties, as well as other intellectual property laws and treaties. V-USB 110 | is licensed, not sold. 111 | 112 | 113 | 6 TERM AND TERMINATION 114 | 115 | 6.1 Term. This Agreement shall continue indefinitely. However, OBJECTIVE 116 | DEVELOPMENT may terminate this Agreement and revoke the granted license and 117 | USB-IDs if you fail to comply with any of its terms and conditions. 118 | 119 | 6.2 Survival of Terms. All provisions regarding secrecy, confidentiality 120 | and limitation of liability shall survive termination of this agreement. 121 | 122 | 123 | 7 DISCLAIMER OF WARRANTY AND LIABILITY 124 | 125 | LIMITED WARRANTY. V-USB IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 126 | KIND. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, OBJECTIVE 127 | DEVELOPMENT AND ITS SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES, EITHER 128 | EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 129 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND 130 | NON-INFRINGEMENT, WITH REGARD TO V-USB, AND THE PROVISION OF OR FAILURE 131 | TO PROVIDE SUPPORT SERVICES. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL 132 | RIGHTS. YOU MAY HAVE OTHERS, WHICH VARY FROM STATE/JURISDICTION TO 133 | STATE/JURISDICTION. 134 | 135 | LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, 136 | IN NO EVENT SHALL OBJECTIVE DEVELOPMENT OR ITS SUPPLIERS BE LIABLE FOR ANY 137 | SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER 138 | (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, 139 | BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY 140 | LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE V-USB OR THE 141 | PROVISION OF OR FAILURE TO PROVIDE SUPPORT SERVICES, EVEN IF OBJECTIVE 142 | DEVELOPMENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY 143 | CASE, OBJECTIVE DEVELOPMENT'S ENTIRE LIABILITY UNDER ANY PROVISION OF THIS 144 | AGREEMENT SHALL BE LIMITED TO THE AMOUNT ACTUALLY PAID BY YOU FOR V-USB. 145 | 146 | 147 | 8 MISCELLANEOUS TERMS 148 | 149 | 8.1 Marketing. OBJECTIVE DEVELOPMENT has the right to mention for marketing 150 | purposes that you entered into this agreement. 151 | 152 | 8.2 Entire Agreement. This document represents the entire agreement between 153 | OBJECTIVE DEVELOPMENT and you. It may only be modified in writing signed by 154 | an authorized representative of both, OBJECTIVE DEVELOPMENT and you. 155 | 156 | 8.3 Severability. In case a provision of these terms and conditions should 157 | be or become partly or entirely invalid, ineffective, or not executable, 158 | the validity of all other provisions shall not be affected. 159 | 160 | 8.4 Applicable Law. This agreement is governed by the laws of the Republic 161 | of Austria. 162 | 163 | 8.5 Responsible Courts. The responsible courts in Vienna/Austria will have 164 | exclusive jurisdiction regarding all disputes in connection with this 165 | agreement. 166 | 167 | -------------------------------------------------------------------------------- /usbdrv/Readme.txt: -------------------------------------------------------------------------------- 1 | This is the Readme file to Objective Development's firmware-only USB driver 2 | for Atmel AVR microcontrollers. For more information please visit 3 | http://www.obdev.at/vusb/ 4 | 5 | This directory contains the USB firmware only. Copy it as-is to your own 6 | project and add all .c and .S files to your project (these files are marked 7 | with an asterisk in the list below). Then copy usbconfig-prototype.h as 8 | usbconfig.h to your project and edit it according to your configuration. 9 | 10 | 11 | TECHNICAL DOCUMENTATION 12 | ======================= 13 | The technical documentation (API) for the firmware driver is contained in the 14 | file "usbdrv.h". Please read all of it carefully! Configuration options are 15 | documented in "usbconfig-prototype.h". 16 | 17 | The driver consists of the following files: 18 | Readme.txt ............. The file you are currently reading. 19 | Changelog.txt .......... Release notes for all versions of the driver. 20 | usbdrv.h ............... Driver interface definitions and technical docs. 21 | * usbdrv.c ............... High level language part of the driver. Link this 22 | module to your code! 23 | * usbdrvasm.S ............ Assembler part of the driver. This module is mostly 24 | a stub and includes one of the usbdrvasm*.S files 25 | depending on processor clock. Link this module to 26 | your code! 27 | usbdrvasm*.inc ......... Assembler routines for particular clock frequencies. 28 | Included by usbdrvasm.S, don't link it directly! 29 | asmcommon.inc .......... Common assembler routines. Included by 30 | usbdrvasm*.inc, don't link it directly! 31 | usbconfig-prototype.h .. Prototype for your own usbdrv.h file. 32 | * oddebug.c .............. Debug functions. Only used when DEBUG_LEVEL is 33 | defined to a value greater than 0. Link this module 34 | to your code! 35 | oddebug.h .............. Interface definitions of the debug module. 36 | usbportability.h ....... Header with compiler-dependent stuff. 37 | usbdrvasm.asm .......... Compatibility stub for IAR-C-compiler. Use this 38 | module instead of usbdrvasm.S when you assembler 39 | with IAR's tools. 40 | License.txt ............ Open Source license for this driver. 41 | CommercialLicense.txt .. Optional commercial license for this driver. 42 | USB-ID-FAQ.txt ......... General infos about USB Product- and Vendor-IDs. 43 | USB-IDs-for-free.txt ... List and terms of use for free shared PIDs. 44 | 45 | (*) ... These files should be linked to your project. 46 | 47 | 48 | CPU CORE CLOCK FREQUENCY 49 | ======================== 50 | We supply assembler modules for clock frequencies of 12 MHz, 12.8 MHz, 15 MHz, 51 | 16 MHz, 16.5 MHz 18 MHz and 20 MHz. Other clock rates are not supported. The 52 | actual clock rate must be configured in usbdrv.h unless you use the default 53 | 12 MHz. 54 | 55 | 12 MHz Clock 56 | This is the traditional clock rate of V-USB because it's the lowest clock 57 | rate where the timing constraints of the USB spec can be met. 58 | 59 | 15 MHz Clock 60 | Similar to 12 MHz, but some NOPs inserted. On the other hand, the higher clock 61 | rate allows for some loops which make the resulting code size somewhat smaller 62 | than the 12 MHz version. 63 | 64 | 16 MHz Clock 65 | This clock rate has been added for users of the Arduino board and other 66 | ready-made boards which come with a fixed 16 MHz crystal. It's also an option 67 | if you need the slightly higher clock rate for performance reasons. Since 68 | 16 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code 69 | is somewhat tricky and has to insert a leap cycle every third byte. 70 | 71 | 12.8 MHz and 16.5 MHz Clock 72 | The assembler modules for these clock rates differ from the other modules 73 | because they have been built for an RC oscillator with only 1% precision. The 74 | receiver code inserts leap cycles to compensate for clock deviations. 1% is 75 | also the precision which can be achieved by calibrating the internal RC 76 | oscillator of the AVR. Please note that only AVRs with internal 64 MHz PLL 77 | oscillator can reach 16.5 MHz with the RC oscillator. This includes the very 78 | popular ATTiny25, ATTiny45, ATTiny85 series as well as the ATTiny26. Almost 79 | all AVRs can reach 12.8 MHz, although this is outside the specified range. 80 | 81 | See the EasyLogger example at http://www.obdev.at/vusb/easylogger.html for 82 | code which calibrates the RC oscillator based on the USB frame clock. 83 | 84 | 18 MHz Clock 85 | This module is closer to the USB specification because it performs an on the 86 | fly CRC check for incoming packets. Packets with invalid checksum are 87 | discarded as required by the spec. If you also implement checks for data 88 | PID toggling on application level (see option USB_CFG_CHECK_DATA_TOGGLING 89 | in usbconfig.h for more info), this ensures data integrity. Due to the CRC 90 | tables and alignment requirements, this code is bigger than modules for other 91 | clock rates. To activate this module, you must define USB_CFG_CHECK_CRC to 1 92 | and USB_CFG_CLOCK_KHZ to 18000 in usbconfig.h. 93 | 94 | 20 MHz Clock 95 | This module is for people who won't do it with less than the maximum. Since 96 | 20 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code 97 | uses similar tricks as the 16 MHz module to insert leap cycles. 98 | 99 | 100 | USB IDENTIFIERS 101 | =============== 102 | Every USB device needs a vendor- and a product-identifier (VID and PID). VIDs 103 | are obtained from usb.org for a price of 1,500 USD. Once you have a VID, you 104 | can assign PIDs at will. 105 | 106 | Since an entry level cost of 1,500 USD is too high for most small companies 107 | and hobbyists, we provide some VID/PID pairs for free. See the file 108 | USB-IDs-for-free.txt for details. 109 | 110 | Objective Development also has some license offerings which include product 111 | IDs. See http://www.obdev.at/vusb/ for details. 112 | 113 | 114 | DEVELOPMENT SYSTEM 115 | ================== 116 | This driver has been developed and optimized for the GNU compiler version 3 117 | (gcc 3). It does work well with gcc 4, but with bigger code size. We recommend 118 | that you use the GNU compiler suite because it is freely available. V-USB 119 | has also been ported to the IAR compiler and assembler. It has been tested 120 | with IAR 4.10B/W32 and 4.12A/W32 on an ATmega8 with the "small" and "tiny" 121 | memory model. Not every release is tested with IAR CC and the driver may 122 | therefore fail to compile with IAR. Please note that gcc is more efficient for 123 | usbdrv.c because this module has been deliberately optimized for gcc. 124 | 125 | 126 | USING V-USB FOR FREE 127 | ==================== 128 | The AVR firmware driver is published under the GNU General Public License 129 | Version 2 (GPL2) and the GNU General Public License Version 3 (GPL3). It is 130 | your choice whether you apply the terms of version 2 or version 3. 131 | 132 | If you decide for the free GPL2 or GPL3, we STRONGLY ENCOURAGE you to do the 133 | following things IN ADDITION to the obligations from the GPL: 134 | 135 | (1) Publish your entire project on a web site and drop us a note with the URL. 136 | Use the form at http://www.obdev.at/vusb/feedback.html for your submission. 137 | If you don't have a web site, you can publish the project in obdev's 138 | documentation wiki at 139 | http://www.obdev.at/goto.php?t=vusb-wiki&p=hosted-projects. 140 | 141 | (2) Adhere to minimum publication standards. Please include AT LEAST: 142 | - a circuit diagram in PDF, PNG or GIF format 143 | - full source code for the host software 144 | - a Readme.txt file in ASCII format which describes the purpose of the 145 | project and what can be found in which directories and which files 146 | - a reference to http://www.obdev.at/vusb/ 147 | 148 | (3) If you improve the driver firmware itself, please give us a free license 149 | to your modifications for our commercial license offerings. 150 | 151 | 152 | COMMERCIAL LICENSES FOR V-USB 153 | ============================= 154 | If you don't want to publish your source code under the terms of the GPL, 155 | you can simply pay money for V-USB. As an additional benefit you get 156 | USB PIDs for free, reserved exclusively to you. See the file 157 | "CommercialLicense.txt" for details. 158 | 159 | -------------------------------------------------------------------------------- /usbdrv/USB-ID-FAQ.txt: -------------------------------------------------------------------------------- 1 | Version 2009-08-22 2 | 3 | ========================== 4 | WHY DO WE NEED THESE IDs? 5 | ========================== 6 | 7 | USB is more than a low level protocol for data transport. It also defines a 8 | common set of requests which must be understood by all devices. And as part 9 | of these common requests, the specification defines data structures, the 10 | USB Descriptors, which are used to describe the properties of the device. 11 | 12 | From the perspective of an operating system, it is therefore possible to find 13 | out basic properties of a device (such as e.g. the manufacturer and the name 14 | of the device) without a device-specific driver. This is essential because 15 | the operating system can choose a driver to load based on this information 16 | (Plug-And-Play). 17 | 18 | Among the most important properties in the Device Descriptor are the USB 19 | Vendor- and Product-ID. Both are 16 bit integers. The most simple form of 20 | driver matching is based on these IDs. The driver announces the Vendor- and 21 | Product-IDs of the devices it can handle and the operating system loads the 22 | appropriate driver when the device is connected. 23 | 24 | It is obvious that this technique only works if the pair Vendor- plus 25 | Product-ID is unique: Only devices which require the same driver can have the 26 | same pair of IDs. 27 | 28 | 29 | ===================================================== 30 | HOW DOES THE USB STANDARD ENSURE THAT IDs ARE UNIQUE? 31 | ===================================================== 32 | 33 | Since it is so important that USB IDs are unique, the USB Implementers Forum, 34 | Inc. (usb.org) needs a way to enforce this legally. It is not forbidden by 35 | law to build a device and assign it any random numbers as IDs. Usb.org 36 | therefore needs an agreement to regulate the use of USB IDs. The agreement 37 | binds only parties who agreed to it, of course. Everybody else is free to use 38 | any numbers for their IDs. 39 | 40 | So how can usb.org ensure that every manufacturer of USB devices enters into 41 | an agreement with them? They do it via trademark licensing. Usb.org has 42 | registered the trademark "USB", all associated logos and related terms. If 43 | you want to put an USB logo on your product or claim that it is USB 44 | compliant, you must license these trademarks from usb.org. And this is where 45 | you enter into an agreement. See the "USB-IF Trademark License Agreement and 46 | Usage Guidelines for the USB-IF Logo" at 47 | http://www.usb.org/developers/logo_license/. 48 | 49 | Licensing the USB trademarks requires that you buy a USB Vendor-ID from 50 | usb.org (one-time fee of ca. 2,000 USD), that you become a member of usb.org 51 | (yearly fee of ca. 4,000 USD) and that you meet all the technical 52 | specifications from the USB spec. 53 | 54 | This means that most hobbyists and small companies will never be able to 55 | become USB compliant, just because membership is so expensive. And you can't 56 | be compliant with a driver based on V-USB anyway, because the AVR's port pins 57 | don't meet the electrical specifications for USB. So, in principle, all 58 | hobbyists and small companies are free to choose any random numbers for their 59 | IDs. They have nothing to lose... 60 | 61 | There is one exception worth noting, though: If you use a sub-component which 62 | implements USB, the vendor of the sub-components may guarantee USB 63 | compliance. This might apply to some or all of FTDI's solutions. 64 | 65 | 66 | ======================================================================= 67 | WHY SHOULD YOU OBTAIN USB IDs EVEN IF YOU DON'T LICENSE USB TRADEMARKS? 68 | ======================================================================= 69 | 70 | You have learned in the previous section that you are free to choose any 71 | numbers for your IDs anyway. So why not do exactly this? There is still the 72 | technical issue. If you choose IDs which are already in use by somebody else, 73 | operating systems will load the wrong drivers and your device won't work. 74 | Even if you choose IDs which are not currently in use, they may be in use in 75 | the next version of the operating system or even after an automatic update. 76 | 77 | So what you need is a pair of Vendor- and Product-IDs for which you have the 78 | guarantee that no USB compliant product uses them. This implies that no 79 | operating system will ever ship with drivers responsible for these IDs. 80 | 81 | 82 | ============================================== 83 | HOW DOES OBJECTIVE DEVELOPMENT HANDLE USB IDs? 84 | ============================================== 85 | 86 | Objective Development gives away pairs of USB-IDs with their V-USB licenses. 87 | In order to ensure that these IDs are unique, Objective Development has an 88 | agreement with the company/person who has bought the USB Vendor-ID from 89 | usb.org. This agreement ensures that a range of USB Product-IDs is reserved 90 | for assignment by Objective Development and that the owner of the Vendor-ID 91 | won't give it to anybody else. 92 | 93 | This means that you have to trust three parties to ensure uniqueness of 94 | your IDs: 95 | 96 | - Objective Development, that they don't give the same PID to more than 97 | one person. 98 | - The owner of the Vendor-ID that they don't assign PIDs from the range 99 | assigned to Objective Development to anybody else. 100 | - Usb.org that they don't assign the same Vendor-ID a second time. 101 | 102 | 103 | ================================== 104 | WHO IS THE OWNER OF THE VENDOR-ID? 105 | ================================== 106 | 107 | Objective Development has obtained ranges of USB Product-IDs under two 108 | Vendor-IDs: Under Vendor-ID 5824 from Wouter van Ooijen (Van Ooijen 109 | Technische Informatica, www.voti.nl) and under Vendor-ID 8352 from Jason 110 | Kotzin (Clay Logic, www.claylogic.com). Both VID owners have received their 111 | Vendor-ID directly from usb.org. 112 | 113 | 114 | ========================================================================= 115 | CAN I USE USB-IDs FROM OBJECTIVE DEVELOPMENT WITH OTHER DRIVERS/HARDWARE? 116 | ========================================================================= 117 | 118 | The short answer is: Yes. All you get is a guarantee that the IDs are never 119 | assigned to anybody else. What more do you need? 120 | 121 | 122 | ============================ 123 | WHAT ABOUT SHARED ID PAIRS? 124 | ============================ 125 | 126 | Objective Development has reserved some PID/VID pairs for shared use. You 127 | have no guarantee of uniqueness for them, except that no USB compliant device 128 | uses them. In order to avoid technical problems, we must ensure that all 129 | devices with the same pair of IDs use the same driver on kernel level. For 130 | details, see the file USB-IDs-for-free.txt. 131 | 132 | 133 | ====================================================== 134 | I HAVE HEARD THAT SUB-LICENSING OF USB-IDs IS ILLEGAL? 135 | ====================================================== 136 | 137 | A 16 bit integer number cannot be protected by copyright laws. It is not 138 | sufficiently complex. And since none of the parties involved entered into the 139 | USB-IF Trademark License Agreement, we are not bound by this agreement. So 140 | there is no reason why it should be illegal to sub-license USB-IDs. 141 | 142 | 143 | ============================================= 144 | WHO IS LIABLE IF THERE ARE INCOMPATIBILITIES? 145 | ============================================= 146 | 147 | Objective Development disclaims all liabilities which might arise from the 148 | assignment of IDs. If you guarantee product features to your customers 149 | without proper disclaimer, YOU are liable for that. 150 | -------------------------------------------------------------------------------- /usbdrv/USB-IDs-for-free.txt: -------------------------------------------------------------------------------- 1 | Version 2009-08-22 2 | 3 | =========================== 4 | FREE USB-IDs FOR SHARED USE 5 | =========================== 6 | 7 | Objective Development has reserved a set of USB Product-IDs for use according 8 | to the guidelines outlined below. For more information about the concept of 9 | USB IDs please see the file USB-ID-FAQ.txt. Objective Development guarantees 10 | that the IDs listed below are not used by any USB compliant devices. 11 | 12 | 13 | ==================== 14 | MECHANISM OF SHARING 15 | ==================== 16 | 17 | From a technical point of view, two different devices can share the same USB 18 | Vendor- and Product-ID if they require the same driver on operating system 19 | level. We make use of this fact by assigning separate IDs for various device 20 | classes. On application layer, devices must be distinguished by their textual 21 | name or serial number. We offer separate sets of IDs for discrimination by 22 | textual name and for serial number. 23 | 24 | Examples for shared use of USB IDs are included with V-USB in the "examples" 25 | subdirectory. 26 | 27 | 28 | ====================================== 29 | IDs FOR DISCRIMINATION BY TEXTUAL NAME 30 | ====================================== 31 | 32 | If you use one of the IDs listed below, your device and host-side software 33 | must conform to these rules: 34 | 35 | (1) The USB device MUST provide a textual representation of the manufacturer 36 | and product identification. The manufacturer identification MUST be available 37 | at least in USB language 0x0409 (English/US). 38 | 39 | (2) The textual manufacturer identification MUST contain either an Internet 40 | domain name (e.g. "mycompany.com") registered and owned by you, or an e-mail 41 | address under your control (e.g. "myname@gmx.net"). You can embed the domain 42 | name or e-mail address in any string you like, e.g. "Objective Development 43 | http://www.obdev.at/vusb/". 44 | 45 | (3) You are responsible for retaining ownership of the domain or e-mail 46 | address for as long as any of your products are in use. 47 | 48 | (4) You may choose any string for the textual product identification, as long 49 | as this string is unique within the scope of your textual manufacturer 50 | identification. 51 | 52 | (5) Application side device look-up MUST be based on the textual manufacturer 53 | and product identification in addition to VID/PID matching. The driver 54 | matching MUST be a comparison of the entire strings, NOT a sub-string match. 55 | 56 | (6) For devices which implement a particular USB device class (e.g. HID), the 57 | operating system's default class driver MUST be used. If an operating system 58 | driver for Vendor Class devices is needed, this driver must be libusb or 59 | libusb-win32 (see http://libusb.org/ and 60 | http://libusb-win32.sourceforge.net/). 61 | 62 | Table if IDs for discrimination by textual name: 63 | 64 | PID dec (hex) | VID dec (hex) | Description of use 65 | ==============+===============+============================================ 66 | 1500 (0x05dc) | 5824 (0x16c0) | For Vendor Class devices with libusb 67 | --------------+---------------+-------------------------------------------- 68 | 1503 (0x05df) | 5824 (0x16c0) | For generic HID class devices (which are 69 | | | NOT mice, keyboards or joysticks) 70 | --------------+---------------+-------------------------------------------- 71 | 1505 (0x05e1) | 5824 (0x16c0) | For CDC-ACM class devices (modems) 72 | --------------+---------------+-------------------------------------------- 73 | 1508 (0x05e4) | 5824 (0x16c0) | For MIDI class devices 74 | --------------+---------------+-------------------------------------------- 75 | 76 | Note that Windows caches the textual product- and vendor-description for 77 | mice, keyboards and joysticks. Name-bsed discrimination is therefore not 78 | recommended for these device classes. 79 | 80 | 81 | ======================================= 82 | IDs FOR DISCRIMINATION BY SERIAL NUMBER 83 | ======================================= 84 | 85 | If you use one of the IDs listed below, your device and host-side software 86 | must conform to these rules: 87 | 88 | (1) The USB device MUST provide a textual representation of the serial 89 | number. The serial number string MUST be available at least in USB language 90 | 0x0409 (English/US). 91 | 92 | (2) The serial number MUST start with either an Internet domain name (e.g. 93 | "mycompany.com") registered and owned by you, or an e-mail address under your 94 | control (e.g. "myname@gmx.net"), both terminated with a colon (":") character. 95 | You MAY append any string you like for further discrimination of your devices. 96 | 97 | (3) You are responsible for retaining ownership of the domain or e-mail 98 | address for as long as any of your products are in use. 99 | 100 | (5) Application side device look-up MUST be based on the serial number string 101 | in addition to VID/PID matching. The matching must start at the first 102 | character of the serial number string and include the colon character 103 | terminating your domain or e-mail address. It MAY stop anywhere after that. 104 | 105 | (6) For devices which implement a particular USB device class (e.g. HID), the 106 | operating system's default class driver MUST be used. If an operating system 107 | driver for Vendor Class devices is needed, this driver must be libusb or 108 | libusb-win32 (see http://libusb.org/ and 109 | http://libusb-win32.sourceforge.net/). 110 | 111 | Table if IDs for discrimination by serial number string: 112 | 113 | PID dec (hex) | VID dec (hex) | Description of use 114 | ===============+===============+=========================================== 115 | 10200 (0x27d8) | 5824 (0x16c0) | For Vendor Class devices with libusb 116 | ---------------+---------------+------------------------------------------- 117 | 10201 (0x27d9) | 5824 (0x16c0) | For generic HID class devices (which are 118 | | | NOT mice, keyboards or joysticks) 119 | ---------------+---------------+------------------------------------------- 120 | 10202 (0x27da) | 5824 (0x16c0) | For USB Mice 121 | ---------------+---------------+------------------------------------------- 122 | 10203 (0x27db) | 5824 (0x16c0) | For USB Keyboards 123 | ---------------+---------------+------------------------------------------- 124 | 10204 (0x27db) | 5824 (0x16c0) | For USB Joysticks 125 | ---------------+---------------+------------------------------------------- 126 | 10205 (0x27dc) | 5824 (0x16c0) | For CDC-ACM class devices (modems) 127 | ---------------+---------------+------------------------------------------- 128 | 10206 (0x27dd) | 5824 (0x16c0) | For MIDI class devices 129 | ---------------+---------------+------------------------------------------- 130 | 131 | 132 | ================= 133 | ORIGIN OF USB-IDs 134 | ================= 135 | 136 | OBJECTIVE DEVELOPMENT Software GmbH has obtained all VID/PID pairs listed 137 | here from Wouter van Ooijen (see www.voti.nl) for exclusive disposition. 138 | Wouter van Ooijen has obtained the VID from the USB Implementers Forum, Inc. 139 | (see www.usb.org). The VID is registered for the company name "Van Ooijen 140 | Technische Informatica". 141 | 142 | 143 | ========== 144 | DISCLAIMER 145 | ========== 146 | 147 | OBJECTIVE DEVELOPMENT Software GmbH disclaims all liability for any 148 | problems which are caused by the shared use of these VID/PID pairs. 149 | -------------------------------------------------------------------------------- /usbdrv/USBID-License.txt: -------------------------------------------------------------------------------- 1 | Royalty-Free Non-Exclusive Use of USB Product-IDs 2 | ================================================= 3 | 4 | Version 2009-04-13 5 | 6 | Strictly speaking, this is not a license. You can't give a license to use 7 | a simple number (such as e.g. 1500) for any purpose. This is a set of rules 8 | which should make it possible to build USB devices without the requirement 9 | for individual USB IDs. If you break one of the rules, you will run into 10 | technical problems sooner or later, but you don't risk legal trouble. 11 | 12 | 13 | OBJECTIVE DEVELOPMENT Software GmbH hereby grants you the non-exclusive 14 | right to use four USB.org vendor-ID (VID) / product-ID (PID) pairs with 15 | products based on Objective Development's firmware-only USB driver for 16 | Atmel AVR microcontrollers: 17 | 18 | * VID = 5824 (=0x16c0) / PID = 1500 (=0x5dc) for devices implementing no 19 | USB device class (vendor-class devices with USB class = 0xff). Devices 20 | using this pair will be referred to as "VENDOR CLASS" devices. 21 | 22 | * VID = 5824 (=0x16c0) / PID = 1503 (=0x5df) for HID class devices 23 | (excluding mice and keyboards). Devices using this pair will be referred 24 | to as "HID CLASS" devices. 25 | 26 | * VID = 5824 (=0x16c0) / PID = 1505 (=0x5e1) for CDC class modem devices 27 | Devices using this pair will be referred to as "CDC-ACM CLASS" devices. 28 | 29 | * VID = 5824 (=0x16c0) / PID = 1508 (=0x5e4) for MIDI class devices 30 | Devices using this pair will be referred to as "MIDI CLASS" devices. 31 | 32 | Since the granted right is non-exclusive, the same VID/PID pairs may be 33 | used by many companies and individuals for different products. To avoid 34 | conflicts, your device and host driver software MUST adhere to the rules 35 | outlined below. 36 | 37 | OBJECTIVE DEVELOPMENT Software GmbH has obtained these VID/PID pairs from 38 | Wouter van Ooijen (see www.voti.nl) for exclusive disposition. Wouter van 39 | Ooijen has obtained the VID from the USB Implementers Forum, Inc. 40 | (see www.usb.org). The VID is registered for the company name 41 | "Van Ooijen Technische Informatica". 42 | 43 | 44 | RULES AND RESTRICTIONS 45 | ====================== 46 | 47 | (1) The USB device MUST provide a textual representation of the 48 | manufacturer and product identification. The manufacturer identification 49 | MUST be available at least in USB language 0x0409 (English/US). 50 | 51 | (2) The textual manufacturer identification MUST contain either an Internet 52 | domain name (e.g. "mycompany.com") registered and owned by you, or an 53 | e-mail address under your control (e.g. "myname@gmx.net"). You can embed 54 | the domain name or e-mail address in any string you like, e.g. "Objective 55 | Development http://www.obdev.at/vusb/". 56 | 57 | (3) You are responsible for retaining ownership of the domain or e-mail 58 | address for as long as any of your products are in use. 59 | 60 | (4) You may choose any string for the textual product identification, as 61 | long as this string is unique within the scope of your textual manufacturer 62 | identification. 63 | 64 | (5) Matching of device-specific drivers MUST be based on the textual 65 | manufacturer and product identification in addition to the usual VID/PID 66 | matching. This means that operating system features which are based on 67 | VID/PID matching only (e.g. Windows kernel level drivers, automatic actions 68 | when the device is plugged in etc) MUST NOT be used. The driver matching 69 | MUST be a comparison of the entire strings, NOT a sub-string match. For 70 | CDC-ACM CLASS and MIDI CLASS devices, a generic class driver should be used 71 | and the matching is based on the USB device class. 72 | 73 | (6) The extent to which VID/PID matching is allowed for non device-specific 74 | drivers or features depends on the operating system and particular VID/PID 75 | pair used: 76 | 77 | * Mac OS X, Linux, FreeBSD and other Unixes: No VID/PID matching is 78 | required and hence no VID/PID-only matching is allowed at all. 79 | 80 | * Windows: The operating system performs VID/PID matching for the kernel 81 | level driver. You are REQUIRED to use libusb-win32 (see 82 | http://libusb-win32.sourceforge.net/) as the kernel level driver for 83 | VENDOR CLASS devices. HID CLASS devices all use the generic HID class 84 | driver shipped with Windows, except mice and keyboards. You therefore 85 | MUST NOT use any of the shared VID/PID pairs for mice or keyboards. 86 | CDC-ACM CLASS devices require a ".inf" file which matches on the VID/PID 87 | pair. This ".inf" file MUST load the "usbser" driver to configure the 88 | device as modem (COM-port). 89 | 90 | (7) OBJECTIVE DEVELOPMENT Software GmbH disclaims all liability for any 91 | problems which are caused by the shared use of these VID/PID pairs. You 92 | have been warned that the sharing of VID/PID pairs may cause problems. If 93 | you want to avoid them, get your own VID/PID pair for exclusive use. 94 | 95 | 96 | HOW TO IMPLEMENT THESE RULES 97 | ============================ 98 | 99 | The following rules are for VENDOR CLASS and HID CLASS devices. CDC-ACM 100 | CLASS and MIDI CLASS devices use the operating system's class driver and 101 | don't need a custom driver. 102 | 103 | The host driver MUST iterate over all devices with the given VID/PID 104 | numbers in their device descriptors and query the string representation for 105 | the manufacturer name in USB language 0x0409 (English/US). It MUST compare 106 | the ENTIRE string with your textual manufacturer identification chosen in 107 | (2) above. A substring search for your domain or e-mail address is NOT 108 | acceptable. The driver MUST NOT touch the device (other than querying the 109 | descriptors) unless the strings match. 110 | 111 | For all USB devices with matching VID/PID and textual manufacturer 112 | identification, the host driver must query the textual product 113 | identification and string-compare it with the name of the product it can 114 | control. It may only initialize the device if the product matches exactly. 115 | 116 | Objective Development provides examples for these matching rules with the 117 | "PowerSwitch" project (using libusb) and with the "Automator" project 118 | (using Windows calls on Windows and libusb on Unix). 119 | 120 | 121 | Technical Notes: 122 | ================ 123 | 124 | Sharing the same VID/PID pair among devices is possible as long as ALL 125 | drivers which match the VID/PID also perform matching on the textual 126 | identification strings. This is easy on all operating systems except 127 | Windows, since Windows establishes a static connection between the VID/PID 128 | pair and a kernel level driver. All devices with the same VID/PID pair must 129 | therefore use THE SAME kernel level driver. 130 | 131 | We therefore demand that you use libusb-win32 for VENDOR CLASS devices. 132 | This is a generic kernel level driver which allows all types of USB access 133 | for user space applications. This is only a partial solution of the 134 | problem, though, because different device drivers may come with different 135 | versions of libusb-win32 and they may not work with the libusb version of 136 | the respective other driver. You are therefore encouraged to test your 137 | driver against a broad range of libusb-win32 versions. Do not use new 138 | features in new versions, or check for their existence before you use them. 139 | When a new libusb-win32 becomes available, make sure that your driver is 140 | compatible with it. 141 | 142 | For HID CLASS devices it is necessary that all those devices bind to the 143 | same kernel driver: Microsoft's generic USB HID driver. This is true for 144 | all HID devices except those with a specialized driver. Currently, the only 145 | HIDs with specialized drivers are mice and keyboards. You therefore MUST 146 | NOT use a shared VID/PID with mouse and keyboard devices. 147 | 148 | Sharing the same VID/PID among different products is unusual and probably 149 | violates the USB specification. If you do it, you do it at your own risk. 150 | 151 | To avoid possible incompatibilities, we highly recommend that you get your 152 | own VID/PID pair if you intend to sell your product. Objective 153 | Development's commercial licenses for V-USB include a PID for 154 | unrestricted exclusive use. 155 | -------------------------------------------------------------------------------- /usbdrv/asmcommon.inc: -------------------------------------------------------------------------------- 1 | /* Name: asmcommon.inc 2 | * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers 3 | * Author: Christian Starkjohann 4 | * Creation Date: 2007-11-05 5 | * Tabsize: 4 6 | * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH 7 | * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) 8 | * Revision: $Id$ 9 | */ 10 | 11 | /* Do not link this file! Link usbdrvasm.S instead, which includes the 12 | * appropriate implementation! 13 | */ 14 | 15 | /* 16 | General Description: 17 | This file contains assembler code which is shared among the USB driver 18 | implementations for different CPU cocks. Since the code must be inserted 19 | in the middle of the module, it's split out into this file and #included. 20 | 21 | Jump destinations called from outside: 22 | sofError: Called when no start sequence was found. 23 | se0: Called when a package has been successfully received. 24 | overflow: Called when receive buffer overflows. 25 | doReturn: Called after sending data. 26 | 27 | Outside jump destinations used by this module: 28 | waitForJ: Called to receive an already arriving packet. 29 | sendAckAndReti: 30 | sendNakAndReti: 31 | sendCntAndReti: 32 | usbSendAndReti: 33 | 34 | The following macros must be defined before this file is included: 35 | .macro POP_STANDARD 36 | .endm 37 | .macro POP_RETI 38 | .endm 39 | */ 40 | 41 | #define token x1 42 | 43 | overflow: 44 | ldi x2, 1< 0 14 | 15 | #warning "Never compile production devices with debugging enabled" 16 | 17 | static void uartPutc(char c) 18 | { 19 | while(!(ODDBG_USR & (1 << ODDBG_UDRE))); /* wait for data register empty */ 20 | ODDBG_UDR = c; 21 | } 22 | 23 | static uchar hexAscii(uchar h) 24 | { 25 | h &= 0xf; 26 | if(h >= 10) 27 | h += 'a' - (uchar)10 - '0'; 28 | h += '0'; 29 | return h; 30 | } 31 | 32 | static void printHex(uchar c) 33 | { 34 | uartPutc(hexAscii(c >> 4)); 35 | uartPutc(hexAscii(c)); 36 | } 37 | 38 | void odDebug(uchar prefix, uchar *data, uchar len) 39 | { 40 | printHex(prefix); 41 | uartPutc(':'); 42 | while(len--){ 43 | uartPutc(' '); 44 | printHex(*data++); 45 | } 46 | uartPutc('\r'); 47 | uartPutc('\n'); 48 | } 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /usbdrv/oddebug.h: -------------------------------------------------------------------------------- 1 | /* Name: oddebug.h 2 | * Project: AVR library 3 | * Author: Christian Starkjohann 4 | * Creation Date: 2005-01-16 5 | * Tabsize: 4 6 | * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH 7 | * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) 8 | * This Revision: $Id: oddebug.h 692 2008-11-07 15:07:40Z cs $ 9 | */ 10 | 11 | #ifndef __oddebug_h_included__ 12 | #define __oddebug_h_included__ 13 | 14 | /* 15 | General Description: 16 | This module implements a function for debug logs on the serial line of the 17 | AVR microcontroller. Debugging can be configured with the define 18 | 'DEBUG_LEVEL'. If this macro is not defined or defined to 0, all debugging 19 | calls are no-ops. If it is 1, DBG1 logs will appear, but not DBG2. If it is 20 | 2, DBG1 and DBG2 logs will be printed. 21 | 22 | A debug log consists of a label ('prefix') to indicate which debug log created 23 | the output and a memory block to dump in hex ('data' and 'len'). 24 | */ 25 | 26 | 27 | #ifndef F_CPU 28 | # define F_CPU 12000000 /* 12 MHz */ 29 | #endif 30 | 31 | /* make sure we have the UART defines: */ 32 | #include "usbportability.h" 33 | 34 | #ifndef uchar 35 | # define uchar unsigned char 36 | #endif 37 | 38 | #if DEBUG_LEVEL > 0 && !(defined TXEN || defined TXEN0) /* no UART in device */ 39 | # warning "Debugging disabled because device has no UART" 40 | # undef DEBUG_LEVEL 41 | #endif 42 | 43 | #ifndef DEBUG_LEVEL 44 | # define DEBUG_LEVEL 0 45 | #endif 46 | 47 | /* ------------------------------------------------------------------------- */ 48 | 49 | #if DEBUG_LEVEL > 0 50 | # define DBG1(prefix, data, len) odDebug(prefix, data, len) 51 | #else 52 | # define DBG1(prefix, data, len) 53 | #endif 54 | 55 | #if DEBUG_LEVEL > 1 56 | # define DBG2(prefix, data, len) odDebug(prefix, data, len) 57 | #else 58 | # define DBG2(prefix, data, len) 59 | #endif 60 | 61 | /* ------------------------------------------------------------------------- */ 62 | 63 | #if DEBUG_LEVEL > 0 64 | extern void odDebug(uchar prefix, uchar *data, uchar len); 65 | 66 | /* Try to find our control registers; ATMEL likes to rename these */ 67 | 68 | #if defined UBRR 69 | # define ODDBG_UBRR UBRR 70 | #elif defined UBRRL 71 | # define ODDBG_UBRR UBRRL 72 | #elif defined UBRR0 73 | # define ODDBG_UBRR UBRR0 74 | #elif defined UBRR0L 75 | # define ODDBG_UBRR UBRR0L 76 | #endif 77 | 78 | #if defined UCR 79 | # define ODDBG_UCR UCR 80 | #elif defined UCSRB 81 | # define ODDBG_UCR UCSRB 82 | #elif defined UCSR0B 83 | # define ODDBG_UCR UCSR0B 84 | #endif 85 | 86 | #if defined TXEN 87 | # define ODDBG_TXEN TXEN 88 | #else 89 | # define ODDBG_TXEN TXEN0 90 | #endif 91 | 92 | #if defined USR 93 | # define ODDBG_USR USR 94 | #elif defined UCSRA 95 | # define ODDBG_USR UCSRA 96 | #elif defined UCSR0A 97 | # define ODDBG_USR UCSR0A 98 | #endif 99 | 100 | #if defined UDRE 101 | # define ODDBG_UDRE UDRE 102 | #else 103 | # define ODDBG_UDRE UDRE0 104 | #endif 105 | 106 | #if defined UDR 107 | # define ODDBG_UDR UDR 108 | #elif defined UDR0 109 | # define ODDBG_UDR UDR0 110 | #endif 111 | 112 | static inline void odDebugInit(void) 113 | { 114 | ODDBG_UCR |= (1< max 25 cycles interrupt disable 39 | ;max stack usage: [ret(2), YL, SREG, YH, shift, x1, x2, x3, cnt, x4] = 11 bytes 40 | ;Numbers in brackets are maximum cycles since SOF. 41 | USB_INTR_VECTOR: 42 | ;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt 43 | push YL ;2 [35] push only what is necessary to sync with edge ASAP 44 | in YL, SREG ;1 [37] 45 | push YL ;2 [39] 46 | ;---------------------------------------------------------------------------- 47 | ; Synchronize with sync pattern: 48 | ;---------------------------------------------------------------------------- 49 | ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 50 | ;sync up with J to K edge during sync pattern -- use fastest possible loops 51 | ;The first part waits at most 1 bit long since we must be in sync pattern. 52 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 53 | ;waitForJ, ensure that this prerequisite is met. 54 | waitForJ: 55 | inc YL 56 | sbis USBIN, USBMINUS 57 | brne waitForJ ; just make sure we have ANY timeout 58 | waitForK: 59 | ;The following code results in a sampling window of 1/4 bit which meets the spec. 60 | sbis USBIN, USBMINUS 61 | rjmp foundK 62 | sbis USBIN, USBMINUS 63 | rjmp foundK 64 | sbis USBIN, USBMINUS 65 | rjmp foundK 66 | sbis USBIN, USBMINUS 67 | rjmp foundK 68 | sbis USBIN, USBMINUS 69 | rjmp foundK 70 | #if USB_COUNT_SOF 71 | lds YL, usbSofCount 72 | inc YL 73 | sts usbSofCount, YL 74 | #endif /* USB_COUNT_SOF */ 75 | #ifdef USB_SOF_HOOK 76 | USB_SOF_HOOK 77 | #endif 78 | rjmp sofError 79 | foundK: 80 | ;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling] 81 | ;we have 1 bit time for setup purposes, then sample again. Numbers in brackets 82 | ;are cycles from center of first sync (double K) bit after the instruction 83 | push YH ;2 [2] 84 | lds YL, usbInputBufOffset;2 [4] 85 | clr YH ;1 [5] 86 | subi YL, lo8(-(usbRxBuf));1 [6] 87 | sbci YH, hi8(-(usbRxBuf));1 [7] 88 | 89 | sbis USBIN, USBMINUS ;1 [8] we want two bits K [sample 1 cycle too early] 90 | rjmp haveTwoBitsK ;2 [10] 91 | pop YH ;2 [11] undo the push from before 92 | rjmp waitForK ;2 [13] this was not the end of sync, retry 93 | haveTwoBitsK: 94 | ;---------------------------------------------------------------------------- 95 | ; push more registers and initialize values while we sample the first bits: 96 | ;---------------------------------------------------------------------------- 97 | push shift ;2 [16] 98 | push x1 ;2 [12] 99 | push x2 ;2 [14] 100 | 101 | in x1, USBIN ;1 [17] <-- sample bit 0 102 | ldi shift, 0xff ;1 [18] 103 | bst x1, USBMINUS ;1 [19] 104 | bld shift, 0 ;1 [20] 105 | push x3 ;2 [22] 106 | push cnt ;2 [24] 107 | 108 | in x2, USBIN ;1 [25] <-- sample bit 1 109 | ser x3 ;1 [26] [inserted init instruction] 110 | eor x1, x2 ;1 [27] 111 | bst x1, USBMINUS ;1 [28] 112 | bld shift, 1 ;1 [29] 113 | ldi cnt, USB_BUFSIZE;1 [30] [inserted init instruction] 114 | rjmp rxbit2 ;2 [32] 115 | 116 | ;---------------------------------------------------------------------------- 117 | ; Receiver loop (numbers in brackets are cycles within byte after instr) 118 | ;---------------------------------------------------------------------------- 119 | 120 | unstuff0: ;1 (branch taken) 121 | andi x3, ~0x01 ;1 [15] 122 | mov x1, x2 ;1 [16] x2 contains last sampled (stuffed) bit 123 | in x2, USBIN ;1 [17] <-- sample bit 1 again 124 | ori shift, 0x01 ;1 [18] 125 | rjmp didUnstuff0 ;2 [20] 126 | 127 | unstuff1: ;1 (branch taken) 128 | mov x2, x1 ;1 [21] x1 contains last sampled (stuffed) bit 129 | andi x3, ~0x02 ;1 [22] 130 | ori shift, 0x02 ;1 [23] 131 | nop ;1 [24] 132 | in x1, USBIN ;1 [25] <-- sample bit 2 again 133 | rjmp didUnstuff1 ;2 [27] 134 | 135 | unstuff2: ;1 (branch taken) 136 | andi x3, ~0x04 ;1 [29] 137 | ori shift, 0x04 ;1 [30] 138 | mov x1, x2 ;1 [31] x2 contains last sampled (stuffed) bit 139 | nop ;1 [32] 140 | in x2, USBIN ;1 [33] <-- sample bit 3 141 | rjmp didUnstuff2 ;2 [35] 142 | 143 | unstuff3: ;1 (branch taken) 144 | in x2, USBIN ;1 [34] <-- sample stuffed bit 3 [one cycle too late] 145 | andi x3, ~0x08 ;1 [35] 146 | ori shift, 0x08 ;1 [36] 147 | rjmp didUnstuff3 ;2 [38] 148 | 149 | unstuff4: ;1 (branch taken) 150 | andi x3, ~0x10 ;1 [40] 151 | in x1, USBIN ;1 [41] <-- sample stuffed bit 4 152 | ori shift, 0x10 ;1 [42] 153 | rjmp didUnstuff4 ;2 [44] 154 | 155 | unstuff5: ;1 (branch taken) 156 | andi x3, ~0x20 ;1 [48] 157 | in x2, USBIN ;1 [49] <-- sample stuffed bit 5 158 | ori shift, 0x20 ;1 [50] 159 | rjmp didUnstuff5 ;2 [52] 160 | 161 | unstuff6: ;1 (branch taken) 162 | andi x3, ~0x40 ;1 [56] 163 | in x1, USBIN ;1 [57] <-- sample stuffed bit 6 164 | ori shift, 0x40 ;1 [58] 165 | rjmp didUnstuff6 ;2 [60] 166 | 167 | ; extra jobs done during bit interval: 168 | ; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs] 169 | ; bit 1: se0 check 170 | ; bit 2: overflow check 171 | ; bit 3: recovery from delay [bit 0 tasks took too long] 172 | ; bit 4: none 173 | ; bit 5: none 174 | ; bit 6: none 175 | ; bit 7: jump, eor 176 | rxLoop: 177 | eor x3, shift ;1 [0] reconstruct: x3 is 0 at bit locations we changed, 1 at others 178 | in x1, USBIN ;1 [1] <-- sample bit 0 179 | st y+, x3 ;2 [3] store data 180 | ser x3 ;1 [4] 181 | nop ;1 [5] 182 | eor x2, x1 ;1 [6] 183 | bst x2, USBMINUS;1 [7] 184 | bld shift, 0 ;1 [8] 185 | in x2, USBIN ;1 [9] <-- sample bit 1 (or possibly bit 0 stuffed) 186 | andi x2, USBMASK ;1 [10] 187 | breq se0 ;1 [11] SE0 check for bit 1 188 | andi shift, 0xf9 ;1 [12] 189 | didUnstuff0: 190 | breq unstuff0 ;1 [13] 191 | eor x1, x2 ;1 [14] 192 | bst x1, USBMINUS;1 [15] 193 | bld shift, 1 ;1 [16] 194 | rxbit2: 195 | in x1, USBIN ;1 [17] <-- sample bit 2 (or possibly bit 1 stuffed) 196 | andi shift, 0xf3 ;1 [18] 197 | breq unstuff1 ;1 [19] do remaining work for bit 1 198 | didUnstuff1: 199 | subi cnt, 1 ;1 [20] 200 | brcs overflow ;1 [21] loop control 201 | eor x2, x1 ;1 [22] 202 | bst x2, USBMINUS;1 [23] 203 | bld shift, 2 ;1 [24] 204 | in x2, USBIN ;1 [25] <-- sample bit 3 (or possibly bit 2 stuffed) 205 | andi shift, 0xe7 ;1 [26] 206 | breq unstuff2 ;1 [27] 207 | didUnstuff2: 208 | eor x1, x2 ;1 [28] 209 | bst x1, USBMINUS;1 [29] 210 | bld shift, 3 ;1 [30] 211 | didUnstuff3: 212 | andi shift, 0xcf ;1 [31] 213 | breq unstuff3 ;1 [32] 214 | in x1, USBIN ;1 [33] <-- sample bit 4 215 | eor x2, x1 ;1 [34] 216 | bst x2, USBMINUS;1 [35] 217 | bld shift, 4 ;1 [36] 218 | didUnstuff4: 219 | andi shift, 0x9f ;1 [37] 220 | breq unstuff4 ;1 [38] 221 | nop2 ;2 [40] 222 | in x2, USBIN ;1 [41] <-- sample bit 5 223 | eor x1, x2 ;1 [42] 224 | bst x1, USBMINUS;1 [43] 225 | bld shift, 5 ;1 [44] 226 | didUnstuff5: 227 | andi shift, 0x3f ;1 [45] 228 | breq unstuff5 ;1 [46] 229 | nop2 ;2 [48] 230 | in x1, USBIN ;1 [49] <-- sample bit 6 231 | eor x2, x1 ;1 [50] 232 | bst x2, USBMINUS;1 [51] 233 | bld shift, 6 ;1 [52] 234 | didUnstuff6: 235 | cpi shift, 0x02 ;1 [53] 236 | brlo unstuff6 ;1 [54] 237 | nop2 ;2 [56] 238 | in x2, USBIN ;1 [57] <-- sample bit 7 239 | eor x1, x2 ;1 [58] 240 | bst x1, USBMINUS;1 [59] 241 | bld shift, 7 ;1 [60] 242 | didUnstuff7: 243 | cpi shift, 0x04 ;1 [61] 244 | brsh rxLoop ;2 [63] loop control 245 | unstuff7: 246 | andi x3, ~0x80 ;1 [63] 247 | ori shift, 0x80 ;1 [64] 248 | in x2, USBIN ;1 [65] <-- sample stuffed bit 7 249 | nop ;1 [66] 250 | rjmp didUnstuff7 ;2 [68] 251 | 252 | macro POP_STANDARD ; 12 cycles 253 | pop cnt 254 | pop x3 255 | pop x2 256 | pop x1 257 | pop shift 258 | pop YH 259 | endm 260 | macro POP_RETI ; 5 cycles 261 | pop YL 262 | out SREG, YL 263 | pop YL 264 | endm 265 | 266 | #include "asmcommon.inc" 267 | 268 | ;---------------------------------------------------------------------------- 269 | ; Transmitting data 270 | ;---------------------------------------------------------------------------- 271 | 272 | txByteLoop: 273 | txBitloop: 274 | stuffN1Delay: ; [03] 275 | ror shift ;[-5] [11] [59] 276 | brcc doExorN1 ;[-4] [60] 277 | subi x4, 1 ;[-3] 278 | brne commonN1 ;[-2] 279 | lsl shift ;[-1] compensate ror after rjmp stuffDelay 280 | nop ;[00] stuffing consists of just waiting 8 cycles 281 | rjmp stuffN1Delay ;[01] after ror, C bit is reliably clear 282 | 283 | sendNakAndReti: ;0 [-19] 19 cycles until SOP 284 | ldi x3, USBPID_NAK ;1 [-18] 285 | rjmp usbSendX3 ;2 [-16] 286 | sendAckAndReti: ;0 [-19] 19 cycles until SOP 287 | ldi x3, USBPID_ACK ;1 [-18] 288 | rjmp usbSendX3 ;2 [-16] 289 | sendCntAndReti: ;0 [-17] 17 cycles until SOP 290 | mov x3, cnt ;1 [-16] 291 | usbSendX3: ;0 [-16] 292 | ldi YL, 20 ;1 [-15] 'x3' is R20 293 | ldi YH, 0 ;1 [-14] 294 | ldi cnt, 2 ;1 [-13] 295 | ; rjmp usbSendAndReti fallthrough 296 | 297 | ; USB spec says: 298 | ; idle = J 299 | ; J = (D+ = 0), (D- = 1) or USBOUT = 0x01 300 | ; K = (D+ = 1), (D- = 0) or USBOUT = 0x02 301 | ; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles) 302 | 303 | ;usbSend: 304 | ;pointer to data in 'Y' 305 | ;number of bytes in 'cnt' -- including sync byte 306 | ;uses: x1...x2, x4, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x4 = bitstuff cnt] 307 | ;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction) 308 | usbSendAndReti: 309 | in x2, USBDDR ;[-12] 12 cycles until SOP 310 | ori x2, USBMASK ;[-11] 311 | sbi USBOUT, USBMINUS ;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) 312 | out USBDDR, x2 ;[-8] <--- acquire bus 313 | in x1, USBOUT ;[-7] port mirror for tx loop 314 | ldi shift, 0x40 ;[-6] sync byte is first byte sent (we enter loop after ror) 315 | ldi x2, USBMASK ;[-5] 316 | push x4 ;[-4] 317 | doExorN1: 318 | eor x1, x2 ;[-2] [06] [62] 319 | ldi x4, 6 ;[-1] [07] [63] 320 | commonN1: 321 | stuffN2Delay: 322 | out USBOUT, x1 ;[00] [08] [64] <--- set bit 323 | ror shift ;[01] 324 | brcc doExorN2 ;[02] 325 | subi x4, 1 ;[03] 326 | brne commonN2 ;[04] 327 | lsl shift ;[05] compensate ror after rjmp stuffDelay 328 | rjmp stuffN2Delay ;[06] after ror, C bit is reliably clear 329 | doExorN2: 330 | eor x1, x2 ;[04] [12] 331 | ldi x4, 6 ;[05] [13] 332 | commonN2: 333 | nop ;[06] [14] 334 | subi cnt, 171 ;[07] [15] trick: (3 * 171) & 0xff = 1 335 | out USBOUT, x1 ;[08] [16] <--- set bit 336 | brcs txBitloop ;[09] [25] [41] 337 | 338 | stuff6Delay: 339 | ror shift ;[42] [50] 340 | brcc doExor6 ;[43] 341 | subi x4, 1 ;[44] 342 | brne common6 ;[45] 343 | lsl shift ;[46] compensate ror after rjmp stuffDelay 344 | nop ;[47] stuffing consists of just waiting 8 cycles 345 | rjmp stuff6Delay ;[48] after ror, C bit is reliably clear 346 | doExor6: 347 | eor x1, x2 ;[45] [53] 348 | ldi x4, 6 ;[46] 349 | common6: 350 | stuff7Delay: 351 | ror shift ;[47] [55] 352 | out USBOUT, x1 ;[48] <--- set bit 353 | brcc doExor7 ;[49] 354 | subi x4, 1 ;[50] 355 | brne common7 ;[51] 356 | lsl shift ;[52] compensate ror after rjmp stuffDelay 357 | rjmp stuff7Delay ;[53] after ror, C bit is reliably clear 358 | doExor7: 359 | eor x1, x2 ;[51] [59] 360 | ldi x4, 6 ;[52] 361 | common7: 362 | ld shift, y+ ;[53] 363 | tst cnt ;[55] 364 | out USBOUT, x1 ;[56] <--- set bit 365 | brne txByteLoop ;[57] 366 | 367 | ;make SE0: 368 | cbr x1, USBMASK ;[58] prepare SE0 [spec says EOP may be 15 to 18 cycles] 369 | lds x2, usbNewDeviceAddr;[59] 370 | lsl x2 ;[61] we compare with left shifted address 371 | subi YL, 2 + 20 ;[62] Only assign address on data packets, not ACK/NAK in x3 372 | sbci YH, 0 ;[63] 373 | out USBOUT, x1 ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle 374 | ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: 375 | ;set address only after data packet was sent, not after handshake 376 | breq skipAddrAssign ;[01] 377 | sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer 378 | skipAddrAssign: 379 | ;end of usbDeviceAddress transfer 380 | ldi x2, 1< 10.0 cycles per bit, 80.0 cycles per byte 30 | ; Numbers in brackets are clocks counted from center of last sync bit 31 | ; when instruction starts 32 | 33 | ;---------------------------------------------------------------------------- 34 | ; order of registers pushed: 35 | ; YL, SREG [sofError] YH, shift, x1, x2, x3, bitcnt, cnt, x4 36 | ;---------------------------------------------------------------------------- 37 | USB_INTR_VECTOR: 38 | push YL ;2 push only what is necessary to sync with edge ASAP 39 | in YL, SREG ;1 40 | push YL ;2 41 | ;---------------------------------------------------------------------------- 42 | ; Synchronize with sync pattern: 43 | ; 44 | ; sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 45 | ; sync up with J to K edge during sync pattern -- use fastest possible loops 46 | ;The first part waits at most 1 bit long since we must be in sync pattern. 47 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 48 | ;waitForJ, ensure that this prerequisite is met. 49 | waitForJ: 50 | inc YL 51 | sbis USBIN, USBMINUS 52 | brne waitForJ ; just make sure we have ANY timeout 53 | ;------------------------------------------------------------------------------- 54 | ; The following code results in a sampling window of < 1/4 bit 55 | ; which meets the spec. 56 | ;------------------------------------------------------------------------------- 57 | waitForK: ;- 58 | sbis USBIN, USBMINUS ;1 [00] <-- sample 59 | rjmp foundK ;2 [01] 60 | sbis USBIN, USBMINUS ; <-- sample 61 | rjmp foundK 62 | sbis USBIN, USBMINUS ; <-- sample 63 | rjmp foundK 64 | sbis USBIN, USBMINUS ; <-- sample 65 | rjmp foundK 66 | sbis USBIN, USBMINUS ; <-- sample 67 | rjmp foundK 68 | sbis USBIN, USBMINUS ; <-- sample 69 | rjmp foundK 70 | #if USB_COUNT_SOF 71 | lds YL, usbSofCount 72 | inc YL 73 | sts usbSofCount, YL 74 | #endif /* USB_COUNT_SOF */ 75 | #ifdef USB_SOF_HOOK 76 | USB_SOF_HOOK 77 | #endif 78 | rjmp sofError 79 | ;------------------------------------------------------------------------------ 80 | ; {3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for 81 | ; center sampling] 82 | ; we have 1 bit time for setup purposes, then sample again. 83 | ; Numbers in brackets are cycles from center of first sync (double K) 84 | ; bit after the instruction 85 | ;------------------------------------------------------------------------------ 86 | foundK: ;- [02] 87 | lds YL, usbInputBufOffset;2 [03+04] tx loop 88 | push YH ;2 [05+06] 89 | clr YH ;1 [07] 90 | subi YL, lo8(-(usbRxBuf)) ;1 [08] [rx loop init] 91 | sbci YH, hi8(-(usbRxBuf)) ;1 [09] [rx loop init] 92 | push shift ;2 [10+11] 93 | ser shift ;1 [12] 94 | sbis USBIN, USBMINUS ;1 [-1] [13] <--sample:we want two bits K (sample 1 cycle too early) 95 | rjmp haveTwoBitsK ;2 [00] [14] 96 | pop shift ;2 [15+16] undo the push from before 97 | pop YH ;2 [17+18] undo the push from before 98 | rjmp waitForK ;2 [19+20] this was not the end of sync, retry 99 | ; The entire loop from waitForK until rjmp waitForK above must not exceed two 100 | ; bit times (= 20 cycles). 101 | 102 | ;---------------------------------------------------------------------------- 103 | ; push more registers and initialize values while we sample the first bits: 104 | ;---------------------------------------------------------------------------- 105 | haveTwoBitsK: ;- [01] 106 | push x1 ;2 [02+03] 107 | push x2 ;2 [04+05] 108 | push x3 ;2 [06+07] 109 | push bitcnt ;2 [08+09] 110 | in x1, USBIN ;1 [00] [10] <-- sample bit 0 111 | bst x1, USBMINUS ;1 [01] 112 | bld shift, 0 ;1 [02] 113 | push cnt ;2 [03+04] 114 | ldi cnt, USB_BUFSIZE ;1 [05] 115 | push x4 ;2 [06+07] tx loop 116 | rjmp rxLoop ;2 [08] 117 | ;---------------------------------------------------------------------------- 118 | ; Receiver loop (numbers in brackets are cycles within byte after instr) 119 | ;---------------------------------------------------------------------------- 120 | unstuff0: ;- [07] (branch taken) 121 | andi x3, ~0x01 ;1 [08] 122 | mov x1, x2 ;1 [09] x2 contains last sampled (stuffed) bit 123 | in x2, USBIN ;1 [00] [10] <-- sample bit 1 again 124 | andi x2, USBMASK ;1 [01] 125 | breq se0Hop ;1 [02] SE0 check for bit 1 126 | ori shift, 0x01 ;1 [03] 0b00000001 127 | nop ;1 [04] 128 | rjmp didUnstuff0 ;2 [05] 129 | ;----------------------------------------------------- 130 | unstuff1: ;- [05] (branch taken) 131 | mov x2, x1 ;1 [06] x1 contains last sampled (stuffed) bit 132 | andi x3, ~0x02 ;1 [07] 133 | ori shift, 0x02 ;1 [08] 0b00000010 134 | nop ;1 [09] 135 | in x1, USBIN ;1 [00] [10] <-- sample bit 2 again 136 | andi x1, USBMASK ;1 [01] 137 | breq se0Hop ;1 [02] SE0 check for bit 2 138 | rjmp didUnstuff1 ;2 [03] 139 | ;----------------------------------------------------- 140 | unstuff2: ;- [05] (branch taken) 141 | andi x3, ~0x04 ;1 [06] 142 | ori shift, 0x04 ;1 [07] 0b00000100 143 | mov x1, x2 ;1 [08] x2 contains last sampled (stuffed) bit 144 | nop ;1 [09] 145 | in x2, USBIN ;1 [00] [10] <-- sample bit 3 146 | andi x2, USBMASK ;1 [01] 147 | breq se0Hop ;1 [02] SE0 check for bit 3 148 | rjmp didUnstuff2 ;2 [03] 149 | ;----------------------------------------------------- 150 | unstuff3: ;- [00] [10] (branch taken) 151 | in x2, USBIN ;1 [01] [11] <-- sample stuffed bit 3 one cycle too late 152 | andi x2, USBMASK ;1 [02] 153 | breq se0Hop ;1 [03] SE0 check for stuffed bit 3 154 | andi x3, ~0x08 ;1 [04] 155 | ori shift, 0x08 ;1 [05] 0b00001000 156 | rjmp didUnstuff3 ;2 [06] 157 | ;---------------------------------------------------------------------------- 158 | ; extra jobs done during bit interval: 159 | ; 160 | ; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs], 161 | ; overflow check, jump to the head of rxLoop 162 | ; bit 1: SE0 check 163 | ; bit 2: SE0 check, recovery from delay [bit 0 tasks took too long] 164 | ; bit 3: SE0 check, recovery from delay [bit 0 tasks took too long] 165 | ; bit 4: SE0 check, none 166 | ; bit 5: SE0 check, none 167 | ; bit 6: SE0 check, none 168 | ; bit 7: SE0 check, reconstruct: x3 is 0 at bit locations we changed, 1 at others 169 | ;---------------------------------------------------------------------------- 170 | rxLoop: ;- [09] 171 | in x2, USBIN ;1 [00] [10] <-- sample bit 1 (or possibly bit 0 stuffed) 172 | andi x2, USBMASK ;1 [01] 173 | brne SkipSe0Hop ;1 [02] 174 | se0Hop: ;- [02] 175 | rjmp se0 ;2 [03] SE0 check for bit 1 176 | SkipSe0Hop: ;- [03] 177 | ser x3 ;1 [04] 178 | andi shift, 0xf9 ;1 [05] 0b11111001 179 | breq unstuff0 ;1 [06] 180 | didUnstuff0: ;- [06] 181 | eor x1, x2 ;1 [07] 182 | bst x1, USBMINUS ;1 [08] 183 | bld shift, 1 ;1 [09] 184 | in x1, USBIN ;1 [00] [10] <-- sample bit 2 (or possibly bit 1 stuffed) 185 | andi x1, USBMASK ;1 [01] 186 | breq se0Hop ;1 [02] SE0 check for bit 2 187 | andi shift, 0xf3 ;1 [03] 0b11110011 188 | breq unstuff1 ;1 [04] do remaining work for bit 1 189 | didUnstuff1: ;- [04] 190 | eor x2, x1 ;1 [05] 191 | bst x2, USBMINUS ;1 [06] 192 | bld shift, 2 ;1 [07] 193 | nop2 ;2 [08+09] 194 | in x2, USBIN ;1 [00] [10] <-- sample bit 3 (or possibly bit 2 stuffed) 195 | andi x2, USBMASK ;1 [01] 196 | breq se0Hop ;1 [02] SE0 check for bit 3 197 | andi shift, 0xe7 ;1 [03] 0b11100111 198 | breq unstuff2 ;1 [04] 199 | didUnstuff2: ;- [04] 200 | eor x1, x2 ;1 [05] 201 | bst x1, USBMINUS ;1 [06] 202 | bld shift, 3 ;1 [07] 203 | didUnstuff3: ;- [07] 204 | andi shift, 0xcf ;1 [08] 0b11001111 205 | breq unstuff3 ;1 [09] 206 | in x1, USBIN ;1 [00] [10] <-- sample bit 4 207 | andi x1, USBMASK ;1 [01] 208 | breq se0Hop ;1 [02] SE0 check for bit 4 209 | eor x2, x1 ;1 [03] 210 | bst x2, USBMINUS ;1 [04] 211 | bld shift, 4 ;1 [05] 212 | didUnstuff4: ;- [05] 213 | andi shift, 0x9f ;1 [06] 0b10011111 214 | breq unstuff4 ;1 [07] 215 | nop2 ;2 [08+09] 216 | in x2, USBIN ;1 [00] [10] <-- sample bit 5 217 | andi x2, USBMASK ;1 [01] 218 | breq se0 ;1 [02] SE0 check for bit 5 219 | eor x1, x2 ;1 [03] 220 | bst x1, USBMINUS ;1 [04] 221 | bld shift, 5 ;1 [05] 222 | didUnstuff5: ;- [05] 223 | andi shift, 0x3f ;1 [06] 0b00111111 224 | breq unstuff5 ;1 [07] 225 | nop2 ;2 [08+09] 226 | in x1, USBIN ;1 [00] [10] <-- sample bit 6 227 | andi x1, USBMASK ;1 [01] 228 | breq se0 ;1 [02] SE0 check for bit 6 229 | eor x2, x1 ;1 [03] 230 | bst x2, USBMINUS ;1 [04] 231 | bld shift, 6 ;1 [05] 232 | didUnstuff6: ;- [05] 233 | cpi shift, 0x02 ;1 [06] 0b00000010 234 | brlo unstuff6 ;1 [07] 235 | nop2 ;2 [08+09] 236 | in x2, USBIN ;1 [00] [10] <-- sample bit 7 237 | andi x2, USBMASK ;1 [01] 238 | breq se0 ;1 [02] SE0 check for bit 7 239 | eor x1, x2 ;1 [03] 240 | bst x1, USBMINUS ;1 [04] 241 | bld shift, 7 ;1 [05] 242 | didUnstuff7: ;- [05] 243 | cpi shift, 0x04 ;1 [06] 0b00000100 244 | brlo unstuff7 ;1 [07] 245 | eor x3, shift ;1 [08] reconstruct: x3 is 0 at bit locations we changed, 1 at others 246 | nop ;1 [09] 247 | in x1, USBIN ;1 [00] [10] <-- sample bit 0 248 | st y+, x3 ;2 [01+02] store data 249 | eor x2, x1 ;1 [03] 250 | bst x2, USBMINUS ;1 [04] 251 | bld shift, 0 ;1 [05] 252 | subi cnt, 1 ;1 [06] 253 | brcs overflow ;1 [07] 254 | rjmp rxLoop ;2 [08] 255 | ;----------------------------------------------------- 256 | unstuff4: ;- [08] 257 | andi x3, ~0x10 ;1 [09] 258 | in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 4 259 | andi x1, USBMASK ;1 [01] 260 | breq se0 ;1 [02] SE0 check for stuffed bit 4 261 | ori shift, 0x10 ;1 [03] 262 | rjmp didUnstuff4 ;2 [04] 263 | ;----------------------------------------------------- 264 | unstuff5: ;- [08] 265 | ori shift, 0x20 ;1 [09] 266 | in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 5 267 | andi x2, USBMASK ;1 [01] 268 | breq se0 ;1 [02] SE0 check for stuffed bit 5 269 | andi x3, ~0x20 ;1 [03] 270 | rjmp didUnstuff5 ;2 [04] 271 | ;----------------------------------------------------- 272 | unstuff6: ;- [08] 273 | andi x3, ~0x40 ;1 [09] 274 | in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 6 275 | andi x1, USBMASK ;1 [01] 276 | breq se0 ;1 [02] SE0 check for stuffed bit 6 277 | ori shift, 0x40 ;1 [03] 278 | rjmp didUnstuff6 ;2 [04] 279 | ;----------------------------------------------------- 280 | unstuff7: ;- [08] 281 | andi x3, ~0x80 ;1 [09] 282 | in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 7 283 | andi x2, USBMASK ;1 [01] 284 | breq se0 ;1 [02] SE0 check for stuffed bit 7 285 | ori shift, 0x80 ;1 [03] 286 | rjmp didUnstuff7 ;2 [04] 287 | 288 | macro POP_STANDARD ; 16 cycles 289 | pop x4 290 | pop cnt 291 | pop bitcnt 292 | pop x3 293 | pop x2 294 | pop x1 295 | pop shift 296 | pop YH 297 | endm 298 | macro POP_RETI ; 5 cycles 299 | pop YL 300 | out SREG, YL 301 | pop YL 302 | endm 303 | 304 | #include "asmcommon.inc" 305 | 306 | ;--------------------------------------------------------------------------- 307 | ; USB spec says: 308 | ; idle = J 309 | ; J = (D+ = 0), (D- = 1) 310 | ; K = (D+ = 1), (D- = 0) 311 | ; Spec allows 7.5 bit times from EOP to SOP for replies 312 | ;--------------------------------------------------------------------------- 313 | bitstuffN: ;- [04] 314 | eor x1, x4 ;1 [05] 315 | clr x2 ;1 [06] 316 | nop ;1 [07] 317 | rjmp didStuffN ;1 [08] 318 | ;--------------------------------------------------------------------------- 319 | bitstuff6: ;- [04] 320 | eor x1, x4 ;1 [05] 321 | clr x2 ;1 [06] 322 | rjmp didStuff6 ;1 [07] 323 | ;--------------------------------------------------------------------------- 324 | bitstuff7: ;- [02] 325 | eor x1, x4 ;1 [03] 326 | clr x2 ;1 [06] 327 | nop ;1 [05] 328 | rjmp didStuff7 ;1 [06] 329 | ;--------------------------------------------------------------------------- 330 | sendNakAndReti: ;- [-19] 331 | ldi x3, USBPID_NAK ;1 [-18] 332 | rjmp sendX3AndReti ;1 [-17] 333 | ;--------------------------------------------------------------------------- 334 | sendAckAndReti: ;- [-17] 335 | ldi cnt, USBPID_ACK ;1 [-16] 336 | sendCntAndReti: ;- [-16] 337 | mov x3, cnt ;1 [-15] 338 | sendX3AndReti: ;- [-15] 339 | ldi YL, 20 ;1 [-14] x3==r20 address is 20 340 | ldi YH, 0 ;1 [-13] 341 | ldi cnt, 2 ;1 [-12] 342 | ; rjmp usbSendAndReti fallthrough 343 | ;--------------------------------------------------------------------------- 344 | ;usbSend: 345 | ;pointer to data in 'Y' 346 | ;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] 347 | ;uses: x1...x4, btcnt, shift, cnt, Y 348 | ;Numbers in brackets are time since first bit of sync pattern is sent 349 | ;We need not to match the transfer rate exactly because the spec demands 350 | ;only 1.5% precision anyway. 351 | usbSendAndReti: ;- [-13] 13 cycles until SOP 352 | in x2, USBDDR ;1 [-12] 353 | ori x2, USBMASK ;1 [-11] 354 | sbi USBOUT, USBMINUS ;2 [-09-10] prepare idle state; D+ and D- must have been 0 (no pullups) 355 | in x1, USBOUT ;1 [-08] port mirror for tx loop 356 | out USBDDR, x2 ;1 [-07] <- acquire bus 357 | ; need not init x2 (bitstuff history) because sync starts with 0 358 | ldi x4, USBMASK ;1 [-06] exor mask 359 | ldi shift, 0x80 ;1 [-05] sync byte is first byte sent 360 | ldi bitcnt, 6 ;1 [-04] 361 | txBitLoop: ;- [-04] [06] 362 | sbrs shift, 0 ;1 [-03] [07] 363 | eor x1, x4 ;1 [-02] [08] 364 | ror shift ;1 [-01] [09] 365 | didStuffN: ;- [09] 366 | out USBOUT, x1 ;1 [00] [10] <-- out N 367 | ror x2 ;1 [01] 368 | cpi x2, 0xfc ;1 [02] 369 | brcc bitstuffN ;1 [03] 370 | dec bitcnt ;1 [04] 371 | brne txBitLoop ;1 [05] 372 | sbrs shift, 0 ;1 [06] 373 | eor x1, x4 ;1 [07] 374 | ror shift ;1 [08] 375 | didStuff6: ;- [08] 376 | nop ;1 [09] 377 | out USBOUT, x1 ;1 [00] [10] <-- out 6 378 | ror x2 ;1 [01] 379 | cpi x2, 0xfc ;1 [02] 380 | brcc bitstuff6 ;1 [03] 381 | sbrs shift, 0 ;1 [04] 382 | eor x1, x4 ;1 [05] 383 | ror shift ;1 [06] 384 | ror x2 ;1 [07] 385 | didStuff7: ;- [07] 386 | ldi bitcnt, 6 ;1 [08] 387 | cpi x2, 0xfc ;1 [09] 388 | out USBOUT, x1 ;1 [00] [10] <-- out 7 389 | brcc bitstuff7 ;1 [01] 390 | ld shift, y+ ;2 [02+03] 391 | dec cnt ;1 [04] 392 | brne txBitLoop ;1 [05] 393 | makeSE0: 394 | cbr x1, USBMASK ;1 [06] prepare SE0 [spec says EOP may be 19 to 23 cycles] 395 | lds x2, usbNewDeviceAddr;2 [07+08] 396 | lsl x2 ;1 [09] we compare with left shifted address 397 | ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: 398 | ;set address only after data packet was sent, not after handshake 399 | out USBOUT, x1 ;1 [00] [10] <-- out SE0-- from now 2 bits==20 cycl. until bus idle 400 | subi YL, 20 + 2 ;1 [01] Only assign address on data packets, not ACK/NAK in x3 401 | sbci YH, 0 ;1 [02] 402 | breq skipAddrAssign ;1 [03] 403 | sts usbDeviceAddr, x2 ;2 [04+05] if not skipped: SE0 is one cycle longer 404 | ;---------------------------------------------------------------------------- 405 | ;end of usbDeviceAddress transfer 406 | skipAddrAssign: ;- [03/04] 407 | ldi x2, 1< 10.6666666 cycles per bit, 85.333333333 cycles per byte 30 | ; Numbers in brackets are clocks counted from center of last sync bit 31 | ; when instruction starts 32 | 33 | USB_INTR_VECTOR: 34 | ;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt 35 | push YL ;[-25] push only what is necessary to sync with edge ASAP 36 | in YL, SREG ;[-23] 37 | push YL ;[-22] 38 | push YH ;[-20] 39 | ;---------------------------------------------------------------------------- 40 | ; Synchronize with sync pattern: 41 | ;---------------------------------------------------------------------------- 42 | ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 43 | ;sync up with J to K edge during sync pattern -- use fastest possible loops 44 | ;The first part waits at most 1 bit long since we must be in sync pattern. 45 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 46 | ;waitForJ, ensure that this prerequisite is met. 47 | waitForJ: 48 | inc YL 49 | sbis USBIN, USBMINUS 50 | brne waitForJ ; just make sure we have ANY timeout 51 | waitForK: 52 | ;The following code results in a sampling window of < 1/4 bit which meets the spec. 53 | sbis USBIN, USBMINUS ;[-15] 54 | rjmp foundK ;[-14] 55 | sbis USBIN, USBMINUS 56 | rjmp foundK 57 | sbis USBIN, USBMINUS 58 | rjmp foundK 59 | sbis USBIN, USBMINUS 60 | rjmp foundK 61 | sbis USBIN, USBMINUS 62 | rjmp foundK 63 | sbis USBIN, USBMINUS 64 | rjmp foundK 65 | #if USB_COUNT_SOF 66 | lds YL, usbSofCount 67 | inc YL 68 | sts usbSofCount, YL 69 | #endif /* USB_COUNT_SOF */ 70 | #ifdef USB_SOF_HOOK 71 | USB_SOF_HOOK 72 | #endif 73 | rjmp sofError 74 | foundK: ;[-12] 75 | ;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling] 76 | ;we have 1 bit time for setup purposes, then sample again. Numbers in brackets 77 | ;are cycles from center of first sync (double K) bit after the instruction 78 | push bitcnt ;[-12] 79 | ; [---] ;[-11] 80 | lds YL, usbInputBufOffset;[-10] 81 | ; [---] ;[-9] 82 | clr YH ;[-8] 83 | subi YL, lo8(-(usbRxBuf));[-7] [rx loop init] 84 | sbci YH, hi8(-(usbRxBuf));[-6] [rx loop init] 85 | push shift ;[-5] 86 | ; [---] ;[-4] 87 | ldi bitcnt, 0x55 ;[-3] [rx loop init] 88 | sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early) 89 | rjmp haveTwoBitsK ;[-1] 90 | pop shift ;[0] undo the push from before 91 | pop bitcnt ;[2] undo the push from before 92 | rjmp waitForK ;[4] this was not the end of sync, retry 93 | ; The entire loop from waitForK until rjmp waitForK above must not exceed two 94 | ; bit times (= 21 cycles). 95 | 96 | ;---------------------------------------------------------------------------- 97 | ; push more registers and initialize values while we sample the first bits: 98 | ;---------------------------------------------------------------------------- 99 | haveTwoBitsK: 100 | push x1 ;[1] 101 | push x2 ;[3] 102 | push x3 ;[5] 103 | ldi shift, 0 ;[7] 104 | ldi x3, 1<<4 ;[8] [rx loop init] first sample is inverse bit, compensate that 105 | push x4 ;[9] == leap 106 | 107 | in x1, USBIN ;[11] <-- sample bit 0 108 | andi x1, USBMASK ;[12] 109 | bst x1, USBMINUS ;[13] 110 | bld shift, 7 ;[14] 111 | push cnt ;[15] 112 | ldi leap, 0 ;[17] [rx loop init] 113 | ldi cnt, USB_BUFSIZE;[18] [rx loop init] 114 | rjmp rxbit1 ;[19] arrives at [21] 115 | 116 | ;---------------------------------------------------------------------------- 117 | ; Receiver loop (numbers in brackets are cycles within byte after instr) 118 | ;---------------------------------------------------------------------------- 119 | 120 | ; duration of unstuffing code should be 10.66666667 cycles. We adjust "leap" 121 | ; accordingly to approximate this value in the long run. 122 | 123 | unstuff6: 124 | andi x2, USBMASK ;[03] 125 | ori x3, 1<<6 ;[04] will not be shifted any more 126 | andi shift, ~0x80;[05] 127 | mov x1, x2 ;[06] sampled bit 7 is actually re-sampled bit 6 128 | subi leap, -1 ;[07] total duration = 11 bits -> subtract 1/3 129 | rjmp didUnstuff6 ;[08] 130 | 131 | unstuff7: 132 | ori x3, 1<<7 ;[09] will not be shifted any more 133 | in x2, USBIN ;[00] [10] re-sample bit 7 134 | andi x2, USBMASK ;[01] 135 | andi shift, ~0x80;[02] 136 | subi leap, 2 ;[03] total duration = 10 bits -> add 1/3 137 | rjmp didUnstuff7 ;[04] 138 | 139 | unstuffEven: 140 | ori x3, 1<<6 ;[09] will be shifted right 6 times for bit 0 141 | in x1, USBIN ;[00] [10] 142 | andi shift, ~0x80;[01] 143 | andi x1, USBMASK ;[02] 144 | breq se0 ;[03] 145 | subi leap, -1 ;[04] total duration = 11 bits -> subtract 1/3 146 | nop2 ;[05] 147 | rjmp didUnstuffE ;[06] 148 | 149 | unstuffOdd: 150 | ori x3, 1<<5 ;[09] will be shifted right 4 times for bit 1 151 | in x2, USBIN ;[00] [10] 152 | andi shift, ~0x80;[01] 153 | andi x2, USBMASK ;[02] 154 | breq se0 ;[03] 155 | subi leap, -1 ;[04] total duration = 11 bits -> subtract 1/3 156 | nop2 ;[05] 157 | rjmp didUnstuffO ;[06] 158 | 159 | rxByteLoop: 160 | andi x1, USBMASK ;[03] 161 | eor x2, x1 ;[04] 162 | subi leap, 1 ;[05] 163 | brpl skipLeap ;[06] 164 | subi leap, -3 ;1 one leap cycle every 3rd byte -> 85 + 1/3 cycles per byte 165 | nop ;1 166 | skipLeap: 167 | subi x2, 1 ;[08] 168 | ror shift ;[09] 169 | didUnstuff6: 170 | cpi shift, 0xfc ;[10] 171 | in x2, USBIN ;[00] [11] <-- sample bit 7 172 | brcc unstuff6 ;[01] 173 | andi x2, USBMASK ;[02] 174 | eor x1, x2 ;[03] 175 | subi x1, 1 ;[04] 176 | ror shift ;[05] 177 | didUnstuff7: 178 | cpi shift, 0xfc ;[06] 179 | brcc unstuff7 ;[07] 180 | eor x3, shift ;[08] reconstruct: x3 is 1 at bit locations we changed, 0 at others 181 | st y+, x3 ;[09] store data 182 | rxBitLoop: 183 | in x1, USBIN ;[00] [11] <-- sample bit 0/2/4 184 | andi x1, USBMASK ;[01] 185 | eor x2, x1 ;[02] 186 | andi x3, 0x3f ;[03] topmost two bits reserved for 6 and 7 187 | subi x2, 1 ;[04] 188 | ror shift ;[05] 189 | cpi shift, 0xfc ;[06] 190 | brcc unstuffEven ;[07] 191 | didUnstuffE: 192 | lsr x3 ;[08] 193 | lsr x3 ;[09] 194 | rxbit1: 195 | in x2, USBIN ;[00] [10] <-- sample bit 1/3/5 196 | andi x2, USBMASK ;[01] 197 | breq se0 ;[02] 198 | eor x1, x2 ;[03] 199 | subi x1, 1 ;[04] 200 | ror shift ;[05] 201 | cpi shift, 0xfc ;[06] 202 | brcc unstuffOdd ;[07] 203 | didUnstuffO: 204 | subi bitcnt, 0xab;[08] == addi 0x55, 0x55 = 0x100/3 205 | brcs rxBitLoop ;[09] 206 | 207 | subi cnt, 1 ;[10] 208 | in x1, USBIN ;[00] [11] <-- sample bit 6 209 | brcc rxByteLoop ;[01] 210 | rjmp overflow 211 | 212 | macro POP_STANDARD ; 14 cycles 213 | pop cnt 214 | pop x4 215 | pop x3 216 | pop x2 217 | pop x1 218 | pop shift 219 | pop bitcnt 220 | endm 221 | macro POP_RETI ; 7 cycles 222 | pop YH 223 | pop YL 224 | out SREG, YL 225 | pop YL 226 | endm 227 | 228 | #include "asmcommon.inc" 229 | 230 | ; USB spec says: 231 | ; idle = J 232 | ; J = (D+ = 0), (D- = 1) 233 | ; K = (D+ = 1), (D- = 0) 234 | ; Spec allows 7.5 bit times from EOP to SOP for replies 235 | 236 | bitstuffN: 237 | eor x1, x4 ;[5] 238 | ldi x2, 0 ;[6] 239 | nop2 ;[7] 240 | nop ;[9] 241 | out USBOUT, x1 ;[10] <-- out 242 | rjmp didStuffN ;[0] 243 | 244 | bitstuff6: 245 | eor x1, x4 ;[5] 246 | ldi x2, 0 ;[6] Carry is zero due to brcc 247 | rol shift ;[7] compensate for ror shift at branch destination 248 | rjmp didStuff6 ;[8] 249 | 250 | bitstuff7: 251 | ldi x2, 0 ;[2] Carry is zero due to brcc 252 | rjmp didStuff7 ;[3] 253 | 254 | 255 | sendNakAndReti: 256 | ldi x3, USBPID_NAK ;[-18] 257 | rjmp sendX3AndReti ;[-17] 258 | sendAckAndReti: 259 | ldi cnt, USBPID_ACK ;[-17] 260 | sendCntAndReti: 261 | mov x3, cnt ;[-16] 262 | sendX3AndReti: 263 | ldi YL, 20 ;[-15] x3==r20 address is 20 264 | ldi YH, 0 ;[-14] 265 | ldi cnt, 2 ;[-13] 266 | ; rjmp usbSendAndReti fallthrough 267 | 268 | ;usbSend: 269 | ;pointer to data in 'Y' 270 | ;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] 271 | ;uses: x1...x4, btcnt, shift, cnt, Y 272 | ;Numbers in brackets are time since first bit of sync pattern is sent 273 | ;We don't match the transfer rate exactly (don't insert leap cycles every third 274 | ;byte) because the spec demands only 1.5% precision anyway. 275 | usbSendAndReti: ; 12 cycles until SOP 276 | in x2, USBDDR ;[-12] 277 | ori x2, USBMASK ;[-11] 278 | sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) 279 | in x1, USBOUT ;[-8] port mirror for tx loop 280 | out USBDDR, x2 ;[-7] <- acquire bus 281 | ; need not init x2 (bitstuff history) because sync starts with 0 282 | ldi x4, USBMASK ;[-6] exor mask 283 | ldi shift, 0x80 ;[-5] sync byte is first byte sent 284 | txByteLoop: 285 | ldi bitcnt, 0x35 ;[-4] [6] binary 0011 0101 286 | txBitLoop: 287 | sbrs shift, 0 ;[-3] [7] 288 | eor x1, x4 ;[-2] [8] 289 | out USBOUT, x1 ;[-1] [9] <-- out N 290 | ror shift ;[0] [10] 291 | ror x2 ;[1] 292 | didStuffN: 293 | cpi x2, 0xfc ;[2] 294 | brcc bitstuffN ;[3] 295 | lsr bitcnt ;[4] 296 | brcc txBitLoop ;[5] 297 | brne txBitLoop ;[6] 298 | 299 | sbrs shift, 0 ;[7] 300 | eor x1, x4 ;[8] 301 | didStuff6: 302 | out USBOUT, x1 ;[-1] [9] <-- out 6 303 | ror shift ;[0] [10] 304 | ror x2 ;[1] 305 | cpi x2, 0xfc ;[2] 306 | brcc bitstuff6 ;[3] 307 | ror shift ;[4] 308 | didStuff7: 309 | ror x2 ;[5] 310 | sbrs x2, 7 ;[6] 311 | eor x1, x4 ;[7] 312 | nop ;[8] 313 | cpi x2, 0xfc ;[9] 314 | out USBOUT, x1 ;[-1][10] <-- out 7 315 | brcc bitstuff7 ;[0] [11] 316 | ld shift, y+ ;[1] 317 | dec cnt ;[3] 318 | brne txByteLoop ;[4] 319 | ;make SE0: 320 | cbr x1, USBMASK ;[5] prepare SE0 [spec says EOP may be 21 to 25 cycles] 321 | lds x2, usbNewDeviceAddr;[6] 322 | lsl x2 ;[8] we compare with left shifted address 323 | subi YL, 20 + 2 ;[9] Only assign address on data packets, not ACK/NAK in x3 324 | sbci YH, 0 ;[10] 325 | out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle 326 | ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: 327 | ;set address only after data packet was sent, not after handshake 328 | breq skipAddrAssign ;[0] 329 | sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer 330 | skipAddrAssign: 331 | ;end of usbDeviceAddress transfer 332 | ldi x2, 1< max 52 cycles interrupt disable 32 | ;max stack usage: [ret(2), r0, SREG, YL, YH, shift, x1, x2, x3, x4, cnt] = 12 bytes 33 | ;nominal frequency: 16.5 MHz -> 11 cycles per bit 34 | ; 16.3125 MHz < F_CPU < 16.6875 MHz (+/- 1.1%) 35 | ; Numbers in brackets are clocks counted from center of last sync bit 36 | ; when instruction starts 37 | 38 | 39 | USB_INTR_VECTOR: 40 | ;order of registers pushed: YL, SREG [sofError], r0, YH, shift, x1, x2, x3, x4, cnt 41 | push YL ;[-23] push only what is necessary to sync with edge ASAP 42 | in YL, SREG ;[-21] 43 | push YL ;[-20] 44 | ;---------------------------------------------------------------------------- 45 | ; Synchronize with sync pattern: 46 | ;---------------------------------------------------------------------------- 47 | ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 48 | ;sync up with J to K edge during sync pattern -- use fastest possible loops 49 | ;The first part waits at most 1 bit long since we must be in sync pattern. 50 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 51 | ;waitForJ, ensure that this prerequisite is met. 52 | waitForJ: 53 | inc YL 54 | sbis USBIN, USBMINUS 55 | brne waitForJ ; just make sure we have ANY timeout 56 | waitForK: 57 | ;The following code results in a sampling window of < 1/4 bit which meets the spec. 58 | sbis USBIN, USBMINUS ;[-15] 59 | rjmp foundK ;[-14] 60 | sbis USBIN, USBMINUS 61 | rjmp foundK 62 | sbis USBIN, USBMINUS 63 | rjmp foundK 64 | sbis USBIN, USBMINUS 65 | rjmp foundK 66 | sbis USBIN, USBMINUS 67 | rjmp foundK 68 | sbis USBIN, USBMINUS 69 | rjmp foundK 70 | #if USB_COUNT_SOF 71 | lds YL, usbSofCount 72 | inc YL 73 | sts usbSofCount, YL 74 | #endif /* USB_COUNT_SOF */ 75 | #ifdef USB_SOF_HOOK 76 | USB_SOF_HOOK 77 | #endif 78 | rjmp sofError 79 | foundK: ;[-12] 80 | ;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling] 81 | ;we have 1 bit time for setup purposes, then sample again. Numbers in brackets 82 | ;are cycles from center of first sync (double K) bit after the instruction 83 | push r0 ;[-12] 84 | ; [---] ;[-11] 85 | push YH ;[-10] 86 | ; [---] ;[-9] 87 | lds YL, usbInputBufOffset;[-8] 88 | ; [---] ;[-7] 89 | clr YH ;[-6] 90 | subi YL, lo8(-(usbRxBuf));[-5] [rx loop init] 91 | sbci YH, hi8(-(usbRxBuf));[-4] [rx loop init] 92 | mov r0, x2 ;[-3] [rx loop init] 93 | sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early) 94 | rjmp haveTwoBitsK ;[-1] 95 | pop YH ;[0] undo the pushes from before 96 | pop r0 ;[2] 97 | rjmp waitForK ;[4] this was not the end of sync, retry 98 | ; The entire loop from waitForK until rjmp waitForK above must not exceed two 99 | ; bit times (= 22 cycles). 100 | 101 | ;---------------------------------------------------------------------------- 102 | ; push more registers and initialize values while we sample the first bits: 103 | ;---------------------------------------------------------------------------- 104 | haveTwoBitsK: ;[1] 105 | push shift ;[1] 106 | push x1 ;[3] 107 | push x2 ;[5] 108 | push x3 ;[7] 109 | ldi shift, 0xff ;[9] [rx loop init] 110 | ori x3, 0xff ;[10] [rx loop init] == ser x3, clear zero flag 111 | 112 | in x1, USBIN ;[11] <-- sample bit 0 113 | bst x1, USBMINUS ;[12] 114 | bld shift, 0 ;[13] 115 | push x4 ;[14] == phase 116 | ; [---] ;[15] 117 | push cnt ;[16] 118 | ; [---] ;[17] 119 | ldi phase, 0 ;[18] [rx loop init] 120 | ldi cnt, USB_BUFSIZE;[19] [rx loop init] 121 | rjmp rxbit1 ;[20] 122 | ; [---] ;[21] 123 | 124 | ;---------------------------------------------------------------------------- 125 | ; Receiver loop (numbers in brackets are cycles within byte after instr) 126 | ;---------------------------------------------------------------------------- 127 | /* 128 | byte oriented operations done during loop: 129 | bit 0: store data 130 | bit 1: SE0 check 131 | bit 2: overflow check 132 | bit 3: catch up 133 | bit 4: rjmp to achieve conditional jump range 134 | bit 5: PLL 135 | bit 6: catch up 136 | bit 7: jump, fixup bitstuff 137 | ; 87 [+ 2] cycles 138 | ------------------------------------------------------------------ 139 | */ 140 | continueWithBit5: 141 | in x2, USBIN ;[055] <-- bit 5 142 | eor r0, x2 ;[056] 143 | or phase, r0 ;[057] 144 | sbrc phase, USBMINUS ;[058] 145 | lpm ;[059] optional nop3; modifies r0 146 | in phase, USBIN ;[060] <-- phase 147 | eor x1, x2 ;[061] 148 | bst x1, USBMINUS ;[062] 149 | bld shift, 5 ;[063] 150 | andi shift, 0x3f ;[064] 151 | in x1, USBIN ;[065] <-- bit 6 152 | breq unstuff5 ;[066] *** unstuff escape 153 | eor phase, x1 ;[067] 154 | eor x2, x1 ;[068] 155 | bst x2, USBMINUS ;[069] 156 | bld shift, 6 ;[070] 157 | didUnstuff6: ;[ ] 158 | in r0, USBIN ;[071] <-- phase 159 | cpi shift, 0x02 ;[072] 160 | brlo unstuff6 ;[073] *** unstuff escape 161 | didUnstuff5: ;[ ] 162 | nop2 ;[074] 163 | ; [---] ;[075] 164 | in x2, USBIN ;[076] <-- bit 7 165 | eor x1, x2 ;[077] 166 | bst x1, USBMINUS ;[078] 167 | bld shift, 7 ;[079] 168 | didUnstuff7: ;[ ] 169 | eor r0, x2 ;[080] 170 | or phase, r0 ;[081] 171 | in r0, USBIN ;[082] <-- phase 172 | cpi shift, 0x04 ;[083] 173 | brsh rxLoop ;[084] 174 | ; [---] ;[085] 175 | unstuff7: ;[ ] 176 | andi x3, ~0x80 ;[085] 177 | ori shift, 0x80 ;[086] 178 | in x2, USBIN ;[087] <-- sample stuffed bit 7 179 | nop ;[088] 180 | rjmp didUnstuff7 ;[089] 181 | ; [---] ;[090] 182 | ;[080] 183 | 184 | unstuff5: ;[067] 185 | eor phase, x1 ;[068] 186 | andi x3, ~0x20 ;[069] 187 | ori shift, 0x20 ;[070] 188 | in r0, USBIN ;[071] <-- phase 189 | mov x2, x1 ;[072] 190 | nop ;[073] 191 | nop2 ;[074] 192 | ; [---] ;[075] 193 | in x1, USBIN ;[076] <-- bit 6 194 | eor r0, x1 ;[077] 195 | or phase, r0 ;[078] 196 | eor x2, x1 ;[079] 197 | bst x2, USBMINUS ;[080] 198 | bld shift, 6 ;[081] no need to check bitstuffing, we just had one 199 | in r0, USBIN ;[082] <-- phase 200 | rjmp didUnstuff5 ;[083] 201 | ; [---] ;[084] 202 | ;[074] 203 | 204 | unstuff6: ;[074] 205 | andi x3, ~0x40 ;[075] 206 | in x1, USBIN ;[076] <-- bit 6 again 207 | ori shift, 0x40 ;[077] 208 | nop2 ;[078] 209 | ; [---] ;[079] 210 | rjmp didUnstuff6 ;[080] 211 | ; [---] ;[081] 212 | ;[071] 213 | 214 | unstuff0: ;[013] 215 | eor r0, x2 ;[014] 216 | or phase, r0 ;[015] 217 | andi x2, USBMASK ;[016] check for SE0 218 | in r0, USBIN ;[017] <-- phase 219 | breq didUnstuff0 ;[018] direct jump to se0 would be too long 220 | andi x3, ~0x01 ;[019] 221 | ori shift, 0x01 ;[020] 222 | mov x1, x2 ;[021] mov existing sample 223 | in x2, USBIN ;[022] <-- bit 1 again 224 | rjmp didUnstuff0 ;[023] 225 | ; [---] ;[024] 226 | ;[014] 227 | 228 | unstuff1: ;[024] 229 | eor r0, x1 ;[025] 230 | or phase, r0 ;[026] 231 | andi x3, ~0x02 ;[027] 232 | in r0, USBIN ;[028] <-- phase 233 | ori shift, 0x02 ;[029] 234 | mov x2, x1 ;[030] 235 | rjmp didUnstuff1 ;[031] 236 | ; [---] ;[032] 237 | ;[022] 238 | 239 | unstuff2: ;[035] 240 | eor r0, x2 ;[036] 241 | or phase, r0 ;[037] 242 | andi x3, ~0x04 ;[038] 243 | in r0, USBIN ;[039] <-- phase 244 | ori shift, 0x04 ;[040] 245 | mov x1, x2 ;[041] 246 | rjmp didUnstuff2 ;[042] 247 | ; [---] ;[043] 248 | ;[033] 249 | 250 | unstuff3: ;[043] 251 | in x2, USBIN ;[044] <-- bit 3 again 252 | eor r0, x2 ;[045] 253 | or phase, r0 ;[046] 254 | andi x3, ~0x08 ;[047] 255 | ori shift, 0x08 ;[048] 256 | nop ;[049] 257 | in r0, USBIN ;[050] <-- phase 258 | rjmp didUnstuff3 ;[051] 259 | ; [---] ;[052] 260 | ;[042] 261 | 262 | unstuff4: ;[053] 263 | andi x3, ~0x10 ;[054] 264 | in x1, USBIN ;[055] <-- bit 4 again 265 | ori shift, 0x10 ;[056] 266 | rjmp didUnstuff4 ;[057] 267 | ; [---] ;[058] 268 | ;[048] 269 | 270 | rxLoop: ;[085] 271 | eor x3, shift ;[086] reconstruct: x3 is 0 at bit locations we changed, 1 at others 272 | in x1, USBIN ;[000] <-- bit 0 273 | st y+, x3 ;[001] 274 | ; [---] ;[002] 275 | eor r0, x1 ;[003] 276 | or phase, r0 ;[004] 277 | eor x2, x1 ;[005] 278 | in r0, USBIN ;[006] <-- phase 279 | ser x3 ;[007] 280 | bst x2, USBMINUS ;[008] 281 | bld shift, 0 ;[009] 282 | andi shift, 0xf9 ;[010] 283 | rxbit1: ;[ ] 284 | in x2, USBIN ;[011] <-- bit 1 285 | breq unstuff0 ;[012] *** unstuff escape 286 | andi x2, USBMASK ;[013] SE0 check for bit 1 287 | didUnstuff0: ;[ ] Z only set if we detected SE0 in bitstuff 288 | breq se0 ;[014] 289 | eor r0, x2 ;[015] 290 | or phase, r0 ;[016] 291 | in r0, USBIN ;[017] <-- phase 292 | eor x1, x2 ;[018] 293 | bst x1, USBMINUS ;[019] 294 | bld shift, 1 ;[020] 295 | andi shift, 0xf3 ;[021] 296 | didUnstuff1: ;[ ] 297 | in x1, USBIN ;[022] <-- bit 2 298 | breq unstuff1 ;[023] *** unstuff escape 299 | eor r0, x1 ;[024] 300 | or phase, r0 ;[025] 301 | subi cnt, 1 ;[026] overflow check 302 | brcs overflow ;[027] 303 | in r0, USBIN ;[028] <-- phase 304 | eor x2, x1 ;[029] 305 | bst x2, USBMINUS ;[030] 306 | bld shift, 2 ;[031] 307 | andi shift, 0xe7 ;[032] 308 | didUnstuff2: ;[ ] 309 | in x2, USBIN ;[033] <-- bit 3 310 | breq unstuff2 ;[034] *** unstuff escape 311 | eor r0, x2 ;[035] 312 | or phase, r0 ;[036] 313 | eor x1, x2 ;[037] 314 | bst x1, USBMINUS ;[038] 315 | in r0, USBIN ;[039] <-- phase 316 | bld shift, 3 ;[040] 317 | andi shift, 0xcf ;[041] 318 | didUnstuff3: ;[ ] 319 | breq unstuff3 ;[042] *** unstuff escape 320 | nop ;[043] 321 | in x1, USBIN ;[044] <-- bit 4 322 | eor x2, x1 ;[045] 323 | bst x2, USBMINUS ;[046] 324 | bld shift, 4 ;[047] 325 | didUnstuff4: ;[ ] 326 | eor r0, x1 ;[048] 327 | or phase, r0 ;[049] 328 | in r0, USBIN ;[050] <-- phase 329 | andi shift, 0x9f ;[051] 330 | breq unstuff4 ;[052] *** unstuff escape 331 | rjmp continueWithBit5;[053] 332 | ; [---] ;[054] 333 | 334 | macro POP_STANDARD ; 16 cycles 335 | pop cnt 336 | pop x4 337 | pop x3 338 | pop x2 339 | pop x1 340 | pop shift 341 | pop YH 342 | pop r0 343 | endm 344 | macro POP_RETI ; 5 cycles 345 | pop YL 346 | out SREG, YL 347 | pop YL 348 | endm 349 | 350 | #include "asmcommon.inc" 351 | 352 | 353 | ; USB spec says: 354 | ; idle = J 355 | ; J = (D+ = 0), (D- = 1) 356 | ; K = (D+ = 1), (D- = 0) 357 | ; Spec allows 7.5 bit times from EOP to SOP for replies 358 | 359 | bitstuff7: 360 | eor x1, x4 ;[4] 361 | ldi x2, 0 ;[5] 362 | nop2 ;[6] C is zero (brcc) 363 | rjmp didStuff7 ;[8] 364 | 365 | bitstuffN: 366 | eor x1, x4 ;[5] 367 | ldi x2, 0 ;[6] 368 | lpm ;[7] 3 cycle NOP, modifies r0 369 | out USBOUT, x1 ;[10] <-- out 370 | rjmp didStuffN ;[0] 371 | 372 | #define bitStatus x3 373 | 374 | sendNakAndReti: 375 | ldi cnt, USBPID_NAK ;[-19] 376 | rjmp sendCntAndReti ;[-18] 377 | sendAckAndReti: 378 | ldi cnt, USBPID_ACK ;[-17] 379 | sendCntAndReti: 380 | mov r0, cnt ;[-16] 381 | ldi YL, 0 ;[-15] R0 address is 0 382 | ldi YH, 0 ;[-14] 383 | ldi cnt, 2 ;[-13] 384 | ; rjmp usbSendAndReti fallthrough 385 | 386 | ;usbSend: 387 | ;pointer to data in 'Y' 388 | ;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] 389 | ;uses: x1...x4, shift, cnt, Y 390 | ;Numbers in brackets are time since first bit of sync pattern is sent 391 | usbSendAndReti: ; 12 cycles until SOP 392 | in x2, USBDDR ;[-12] 393 | ori x2, USBMASK ;[-11] 394 | sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) 395 | in x1, USBOUT ;[-8] port mirror for tx loop 396 | out USBDDR, x2 ;[-7] <- acquire bus 397 | ; need not init x2 (bitstuff history) because sync starts with 0 398 | ldi x4, USBMASK ;[-6] exor mask 399 | ldi shift, 0x80 ;[-5] sync byte is first byte sent 400 | ldi bitStatus, 0xff ;[-4] init bit loop counter, works for up to 12 bytes 401 | byteloop: 402 | bitloop: 403 | sbrs shift, 0 ;[8] [-3] 404 | eor x1, x4 ;[9] [-2] 405 | out USBOUT, x1 ;[10] [-1] <-- out 406 | ror shift ;[0] 407 | ror x2 ;[1] 408 | didStuffN: 409 | cpi x2, 0xfc ;[2] 410 | brcc bitstuffN ;[3] 411 | nop ;[4] 412 | subi bitStatus, 37 ;[5] 256 / 7 ~=~ 37 413 | brcc bitloop ;[6] when we leave the loop, bitStatus has almost the initial value 414 | sbrs shift, 0 ;[7] 415 | eor x1, x4 ;[8] 416 | ror shift ;[9] 417 | didStuff7: 418 | out USBOUT, x1 ;[10] <-- out 419 | ror x2 ;[0] 420 | cpi x2, 0xfc ;[1] 421 | brcc bitstuff7 ;[2] 422 | ld shift, y+ ;[3] 423 | dec cnt ;[5] 424 | brne byteloop ;[6] 425 | ;make SE0: 426 | cbr x1, USBMASK ;[7] prepare SE0 [spec says EOP may be 21 to 25 cycles] 427 | lds x2, usbNewDeviceAddr;[8] 428 | lsl x2 ;[10] we compare with left shifted address 429 | out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle 430 | ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: 431 | ;set address only after data packet was sent, not after handshake 432 | subi YL, 2 ;[0] Only assign address on data packets, not ACK/NAK in r0 433 | sbci YH, 0 ;[1] 434 | breq skipAddrAssign ;[2] 435 | sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer 436 | skipAddrAssign: 437 | ;end of usbDeviceAddress transfer 438 | ldi x2, 1< 13.333333 cycles per bit, 106.666667 cycles per byte 38 | ; Numbers in brackets are clocks counted from center of last sync bit 39 | ; when instruction starts 40 | ;register use in receive loop: 41 | ; shift assembles the byte currently being received 42 | ; x1 holds the D+ and D- line state 43 | ; x2 holds the previous line state 44 | ; x4 (leap) is used to add a leap cycle once every three bytes received 45 | ; X3 (leap2) is used to add a leap cycle once every three stuff bits received 46 | ; bitcnt is used to determine when a stuff bit is due 47 | ; cnt holds the number of bytes left in the receive buffer 48 | 49 | USB_INTR_VECTOR: 50 | ;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt 51 | push YL ;[-28] push only what is necessary to sync with edge ASAP 52 | in YL, SREG ;[-26] 53 | push YL ;[-25] 54 | push YH ;[-23] 55 | ;---------------------------------------------------------------------------- 56 | ; Synchronize with sync pattern: 57 | ;---------------------------------------------------------------------------- 58 | ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 59 | ;sync up with J to K edge during sync pattern -- use fastest possible loops 60 | ;The first part waits at most 1 bit long since we must be in sync pattern. 61 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 62 | ;waitForJ, ensure that this prerequisite is met. 63 | waitForJ: 64 | inc YL 65 | sbis USBIN, USBMINUS 66 | brne waitForJ ; just make sure we have ANY timeout 67 | waitForK: 68 | ;The following code results in a sampling window of < 1/4 bit which meets the spec. 69 | sbis USBIN, USBMINUS ;[-19] 70 | rjmp foundK ;[-18] 71 | sbis USBIN, USBMINUS 72 | rjmp foundK 73 | sbis USBIN, USBMINUS 74 | rjmp foundK 75 | sbis USBIN, USBMINUS 76 | rjmp foundK 77 | sbis USBIN, USBMINUS 78 | rjmp foundK 79 | sbis USBIN, USBMINUS 80 | rjmp foundK 81 | sbis USBIN, USBMINUS 82 | rjmp foundK 83 | sbis USBIN, USBMINUS 84 | rjmp foundK 85 | sbis USBIN, USBMINUS 86 | rjmp foundK 87 | #if USB_COUNT_SOF 88 | lds YL, usbSofCount 89 | inc YL 90 | sts usbSofCount, YL 91 | #endif /* USB_COUNT_SOF */ 92 | #ifdef USB_SOF_HOOK 93 | USB_SOF_HOOK 94 | #endif 95 | rjmp sofError 96 | foundK: ;[-16] 97 | ;{3, 5} after falling D- edge, average delay: 4 cycles 98 | ;bit0 should be at 34 for center sampling. Currently at 4 so 30 cylces till bit 0 sample 99 | ;use 1 bit time for setup purposes, then sample again. Numbers in brackets 100 | ;are cycles from center of first sync (double K) bit after the instruction 101 | push bitcnt ;[-16] 102 | ; [---] ;[-15] 103 | lds YL, usbInputBufOffset;[-14] 104 | ; [---] ;[-13] 105 | clr YH ;[-12] 106 | subi YL, lo8(-(usbRxBuf));[-11] [rx loop init] 107 | sbci YH, hi8(-(usbRxBuf));[-10] [rx loop init] 108 | push shift ;[-9] 109 | ; [---] ;[-8] 110 | ldi shift,0x40 ;[-7] set msb to "1" so processing bit7 can be detected 111 | nop2 ;[-6] 112 | ; [---] ;[-5] 113 | ldi bitcnt, 5 ;[-4] [rx loop init] 114 | sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early) 115 | rjmp haveTwoBitsK ;[-2] 116 | pop shift ;[-1] undo the push from before 117 | pop bitcnt ;[1] 118 | rjmp waitForK ;[3] this was not the end of sync, retry 119 | ; The entire loop from waitForK until rjmp waitForK above must not exceed two 120 | ; bit times (= 27 cycles). 121 | 122 | ;---------------------------------------------------------------------------- 123 | ; push more registers and initialize values while we sample the first bits: 124 | ;---------------------------------------------------------------------------- 125 | haveTwoBitsK: 126 | push x1 ;[0] 127 | push x2 ;[2] 128 | push x3 ;[4] (leap2) 129 | ldi leap2, 0x55 ;[6] add leap cycle on 2nd,5th,8th,... stuff bit 130 | push x4 ;[7] == leap 131 | ldi leap, 0x55 ;[9] skip leap cycle on 2nd,5th,8th,... byte received 132 | push cnt ;[10] 133 | ldi cnt, USB_BUFSIZE ;[12] [rx loop init] 134 | ldi x2, 1< 39 | #ifndef __IAR_SYSTEMS_ASM__ 40 | # include 41 | #endif 42 | 43 | #define __attribute__(arg) /* not supported on IAR */ 44 | 45 | #ifdef __IAR_SYSTEMS_ASM__ 46 | # define __ASSEMBLER__ /* IAR does not define standard macro for asm */ 47 | #endif 48 | 49 | #ifdef __HAS_ELPM__ 50 | # define PROGMEM __farflash 51 | #else 52 | # define PROGMEM __flash 53 | #endif 54 | 55 | #define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr)) 56 | 57 | /* The following definitions are not needed by the driver, but may be of some 58 | * help if you port a gcc based project to IAR. 59 | */ 60 | #define cli() __disable_interrupt() 61 | #define sei() __enable_interrupt() 62 | #define wdt_reset() __watchdog_reset() 63 | #define _BV(x) (1 << (x)) 64 | 65 | /* assembler compatibility macros */ 66 | #define nop2 rjmp $+2 /* jump to next instruction */ 67 | #define XL r26 68 | #define XH r27 69 | #define YL r28 70 | #define YH r29 71 | #define ZL r30 72 | #define ZH r31 73 | #define lo8(x) LOW(x) 74 | #define hi8(x) (((x)>>8) & 0xff) /* not HIGH to allow XLINK to make a proper range check */ 75 | 76 | /* Depending on the device you use, you may get problems with the way usbdrv.h 77 | * handles the differences between devices. Since IAR does not use #defines 78 | * for MCU registers, we can't check for the existence of a particular 79 | * register with an #ifdef. If the autodetection mechanism fails, include 80 | * definitions for the required USB_INTR_* macros in your usbconfig.h. See 81 | * usbconfig-prototype.h and usbdrv.h for details. 82 | */ 83 | 84 | /* ------------------------------------------------------------------------- */ 85 | #elif __CODEVISIONAVR__ /* check for CodeVision AVR */ 86 | /* ------------------------------------------------------------------------- */ 87 | /* This port is not working (yet) */ 88 | 89 | /* #define F_CPU _MCU_CLOCK_FREQUENCY_ seems to be defined automatically */ 90 | 91 | #include 92 | #include 93 | 94 | #define __attribute__(arg) /* not supported on IAR */ 95 | 96 | #define PROGMEM __flash 97 | #define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr)) 98 | 99 | #ifndef __ASSEMBLER__ 100 | static inline void cli(void) 101 | { 102 | #asm("cli"); 103 | } 104 | static inline void sei(void) 105 | { 106 | #asm("sei"); 107 | } 108 | #endif 109 | #define _delay_ms(t) delay_ms(t) 110 | #define _BV(x) (1 << (x)) 111 | #define USB_CFG_USE_SWITCH_STATEMENT 1 /* macro for if() cascase fails for unknown reason */ 112 | 113 | #define macro .macro 114 | #define endm .endmacro 115 | #define nop2 rjmp .+0 /* jump to next instruction */ 116 | 117 | /* ------------------------------------------------------------------------- */ 118 | #else /* default development environment is avr-gcc/avr-libc */ 119 | /* ------------------------------------------------------------------------- */ 120 | 121 | #include 122 | #ifdef __ASSEMBLER__ 123 | # define _VECTOR(N) __vector_ ## N /* io.h does not define this for asm */ 124 | #else 125 | # include 126 | #endif 127 | 128 | #define USB_READ_FLASH(addr) pgm_read_byte(addr) 129 | 130 | #define macro .macro 131 | #define endm .endm 132 | #define nop2 rjmp .+0 /* jump to next instruction */ 133 | 134 | #endif /* development environment */ 135 | 136 | /* for conveniecne, ensure that PRG_RDB exists */ 137 | #ifndef PRG_RDB 138 | # define PRG_RDB(addr) USB_READ_FLASH(addr) 139 | #endif 140 | #endif /* __usbportability_h_INCLUDED__ */ 141 | --------------------------------------------------------------------------------