├── .gitattributes ├── .gitignore ├── Document.hex ├── Makefile ├── Readme.md ├── avr_boot.h ├── bootloaderconfig.h ├── main.c ├── optiboot.c ├── optiboot.h ├── pin_defs.h ├── protrinket_12mhz.hex ├── protrinket_16mhz.hex ├── stk500.h ├── usbconfig.h └── usbdrv ├── Changelog.txt ├── CommercialLicense.txt ├── License.txt ├── Readme.txt ├── USB-ID-FAQ.txt ├── USB-IDs-for-free.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 /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.d 3 | 4 | ################# 5 | ## Eclipse 6 | ################# 7 | 8 | *.pydevproject 9 | .project 10 | .metadata 11 | bin/ 12 | tmp/ 13 | *.tmp 14 | *.bak 15 | *.swp 16 | *~.nib 17 | local.properties 18 | .classpath 19 | .settings/ 20 | .loadpath 21 | 22 | # External tool builders 23 | .externalToolBuilders/ 24 | 25 | # Locally stored "Eclipse launch configurations" 26 | *.launch 27 | 28 | # CDT-specific 29 | .cproject 30 | 31 | # PDT-specific 32 | .buildpath 33 | 34 | 35 | ################# 36 | ## Visual Studio 37 | ################# 38 | 39 | ## Ignore Visual Studio temporary files, build results, and 40 | ## files generated by popular Visual Studio add-ons. 41 | 42 | # User-specific files 43 | *.suo 44 | *.user 45 | *.sln.docstates 46 | 47 | # Build results 48 | 49 | [Dd]ebug/ 50 | [Rr]elease/ 51 | x64/ 52 | build/ 53 | [Bb]in/ 54 | [Oo]bj/ 55 | 56 | # MSTest test Results 57 | [Tt]est[Rr]esult*/ 58 | [Bb]uild[Ll]og.* 59 | 60 | *_i.c 61 | *_p.c 62 | *.ilk 63 | *.meta 64 | *.obj 65 | *.pch 66 | *.pdb 67 | *.pgc 68 | *.pgd 69 | *.rsp 70 | *.sbr 71 | *.tlb 72 | *.tli 73 | *.tlh 74 | *.tmp 75 | *.tmp_proj 76 | *.log 77 | *.vspscc 78 | *.vssscc 79 | .builds 80 | *.pidb 81 | *.log 82 | *.scc 83 | 84 | # Visual C++ cache files 85 | ipch/ 86 | *.aps 87 | *.ncb 88 | *.opensdf 89 | *.sdf 90 | *.cachefile 91 | 92 | # Visual Studio profiler 93 | *.psess 94 | *.vsp 95 | *.vspx 96 | 97 | # Guidance Automation Toolkit 98 | *.gpState 99 | 100 | # ReSharper is a .NET coding add-in 101 | _ReSharper*/ 102 | *.[Rr]e[Ss]harper 103 | 104 | # TeamCity is a build add-in 105 | _TeamCity* 106 | 107 | # DotCover is a Code Coverage Tool 108 | *.dotCover 109 | 110 | # NCrunch 111 | *.ncrunch* 112 | .*crunch*.local.xml 113 | 114 | # Installshield output folder 115 | [Ee]xpress/ 116 | 117 | # DocProject is a documentation generator add-in 118 | DocProject/buildhelp/ 119 | DocProject/Help/*.HxT 120 | DocProject/Help/*.HxC 121 | DocProject/Help/*.hhc 122 | DocProject/Help/*.hhk 123 | DocProject/Help/*.hhp 124 | DocProject/Help/Html2 125 | DocProject/Help/html 126 | 127 | # Click-Once directory 128 | publish/ 129 | 130 | # Publish Web Output 131 | *.Publish.xml 132 | *.pubxml 133 | 134 | # NuGet Packages Directory 135 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 136 | #packages/ 137 | 138 | # Windows Azure Build Output 139 | csx 140 | *.build.csdef 141 | 142 | # Windows Store app package directory 143 | AppPackages/ 144 | 145 | # Others 146 | sql/ 147 | *.Cache 148 | ClientBin/ 149 | [Ss]tyle[Cc]op.* 150 | ~$* 151 | *~ 152 | *.dbmdl 153 | *.[Pp]ublish.xml 154 | *.pfx 155 | *.publishsettings 156 | 157 | # RIA/Silverlight projects 158 | Generated_Code/ 159 | 160 | # Backup & report files from converting an old project file to a newer 161 | # Visual Studio version. Backup files are not needed, because we have git ;-) 162 | _UpgradeReport_Files/ 163 | Backup*/ 164 | UpgradeLog*.XML 165 | UpgradeLog*.htm 166 | 167 | # SQL Server files 168 | App_Data/*.mdf 169 | App_Data/*.ldf 170 | 171 | ############# 172 | ## Windows detritus 173 | ############# 174 | 175 | # Windows image file caches 176 | Thumbs.db 177 | ehthumbs.db 178 | 179 | # Folder config file 180 | Desktop.ini 181 | 182 | # Recycle Bin used on file shares 183 | $RECYCLE.BIN/ 184 | 185 | # Mac crap 186 | .DS_Store 187 | 188 | 189 | ############# 190 | ## Python 191 | ############# 192 | 193 | *.py[co] 194 | 195 | # Packages 196 | *.egg 197 | *.egg-info 198 | dist/ 199 | build/ 200 | eggs/ 201 | parts/ 202 | var/ 203 | sdist/ 204 | develop-eggs/ 205 | .installed.cfg 206 | 207 | # Installer logs 208 | pip-log.txt 209 | 210 | # Unit test / coverage reports 211 | .coverage 212 | .tox 213 | 214 | #Translations 215 | *.mo 216 | 217 | #Mr Developer 218 | .mr.developer.cfg 219 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Name: Makefile 2 | # Project: VUsbTinyBoot, for Trinket Pro 3 | # Author: Frank Zhao 4 | # Creation Date: 2013-06-06 5 | # Tabsize: 4 6 | # Copyright: (c) 2013 by Adafruit Industries 7 | # License: GNU GPL v2 (see License.txt) 8 | 9 | # This makefile is derived from the USBaspLoader makefile 10 | # works best with AVR GCC 4.2.2 (WinAVR 20071221) 11 | ############################################################################### 12 | # Configure the following variables according to your AVR. 13 | # Program the device with 14 | # make fuse # to set the clock generator, boot section size etc. 15 | # make flash # to load the boot loader into flash 16 | # make lock # to protect the boot loader from overwriting 17 | 18 | F_CPU = 16000000 19 | DEVICE = atmega328p 20 | # if the code size is over 2K (under 4K), the BOOTLOADER_ADDRESS is 1000 for 8K devices, 3000 for 16K and 7000 for 32K 21 | # if the code size is under 2K, the BOOTLOADER_ADDRESS is 1800 for 8K devices, 3800 for 16K and 7800 for 32K 22 | # ATmega8, ATmega88, ATmega168 do not support 4K bootloaders 23 | BOOTLOADER_ADDRESS = 7000 24 | FUSEOPT = $(FUSEOPT_328) 25 | LOCKOPT = -U lock:w:0x2F:m 26 | UNLOCKOPT = -U lock:w:0x3F:m 27 | 28 | PROGRAMMER = -c usbtiny 29 | # PROGRAMMER contains AVRDUDE options to address your programmer 30 | 31 | FUSEOPT_8 = -U hfuse:w:0xD0:m -U lfuse:w:0xBF:m 32 | FUSEOPT_88 = -U hfuse:w:0xD5:m -U lfuse:w:0xFF:m -U efuse:w:0xF8:m 33 | FUSEOPT_168 = -U hfuse:w:0xD5:m -U lfuse:w:0xFF:m -U efuse:w:0xF8:m 34 | FUSEOPT_328 = -U lfuse:w:0xFF:m -U hfuse:w:0xD0:m -U efuse:w:0x05:m 35 | # You may have to change the order of these -U commands. 36 | 37 | ############################################################################### 38 | 39 | # Tools: 40 | AVRDUDE = avrdude $(PROGRAMMER) -p $(DEVICE) 41 | CC = avr-gcc 42 | 43 | # Options: 44 | DEFINES = 45 | # Remove the -fno-* options when you use gcc 3, it does not understand them ( -fno-move-loop-invariants -fno-tree-scev-cprop -fno-inline-small-functions ) 46 | CFLAGS = -Wall -Os -I. -mmcu=$(DEVICE) -DF_CPU=$(F_CPU) -DBOOTLOADER_ADDRESS=0x$(BOOTLOADER_ADDRESS) $(DEFINES) 47 | LDFLAGS = -Wl,--relax,--gc-sections -Wl,--section-start=.text=$(BOOTLOADER_ADDRESS) 48 | 49 | OBJECTS = usbdrv/usbdrvasm.o main.o optiboot.o 50 | 51 | # symbolic targets: 52 | all: main.hex 53 | 54 | .c.o: 55 | $(CC) $(CFLAGS) -c $< -o $@ 56 | 57 | .S.o: 58 | $(CC) $(CFLAGS) -x assembler-with-cpp -c $< -o $@ 59 | # "-x assembler-with-cpp" should not be necessary since this is the default 60 | # file type for the .S (with capital S) extension. However, upper case 61 | # characters are not always preserved on Windows. To ensure WinAVR 62 | # compatibility define the file type manually. 63 | 64 | .c.s: 65 | $(CC) $(CFLAGS) -S $< -o $@ 66 | 67 | flash: all 68 | $(AVRDUDE) -B 1 -U flash:w:main.hex:i 69 | 70 | readflash: 71 | $(AVRDUDE) -B 1 -U flash:r:read.hex:i 72 | 73 | fuse: 74 | $(AVRDUDE) $(FUSEOPT) 75 | 76 | unlock: 77 | $(AVRDUDE) $(UNLOCKOPT) 78 | 79 | lock: 80 | $(AVRDUDE) $(LOCKOPT) 81 | 82 | read_fuses: 83 | $(UISP) --rd_fuses 84 | 85 | clean: 86 | rm -f main.hex main.bin $(OBJECTS) 87 | 88 | # file targets: 89 | main.bin: $(OBJECTS) 90 | $(CC) $(CFLAGS) -o main.bin $(OBJECTS) $(LDFLAGS) 91 | 92 | main.hex: main.bin 93 | rm -f main.hex main.eep.hex 94 | avr-objcopy -j .text -j .data -O ihex main.bin main.hex 95 | avr-size main.hex 96 | 97 | disasm: main.bin 98 | avr-objdump -d main.bin 99 | 100 | cpp: 101 | $(CC) $(CFLAGS) -E main.c 102 | 103 | # Special rules for generating hex files for various devices and clock speeds 104 | ALLHEXFILES = hexfiles/mega8_12mhz.hex hexfiles/mega8_15mhz.hex hexfiles/mega8_16mhz.hex \ 105 | hexfiles/mega88_12mhz.hex hexfiles/mega88_15mhz.hex hexfiles/mega88_16mhz.hex hexfiles/mega88_20mhz.hex\ 106 | hexfiles/mega168_12mhz.hex hexfiles/mega168_15mhz.hex hexfiles/mega168_16mhz.hex hexfiles/mega168_20mhz.hex\ 107 | hexfiles/mega328p_12mhz.hex hexfiles/mega328p_15mhz.hex hexfiles/mega328p_16mhz.hex hexfiles/mega328p_20mhz.hex 108 | 109 | allhexfiles: $(ALLHEXFILES) 110 | $(MAKE) clean 111 | avr-size hexfiles/*.hex 112 | 113 | $(ALLHEXFILES): 114 | @[ -d hexfiles ] || mkdir hexfiles 115 | @device=`echo $@ | sed -e 's|.*/mega||g' -e 's|_.*||g'`; \ 116 | clock=`echo $@ | sed -e 's|.*_||g' -e 's|mhz.*||g'`; \ 117 | addr=`echo $$device | sed -e 's/\([0-9]\)8/\1/g' | awk '{printf("%x", ($$1 - 2) * 1024)}'`; \ 118 | echo "### Make with F_CPU=$${clock}000000 DEVICE=atmega$$device BOOTLOADER_ADDRESS=$$addr"; \ 119 | $(MAKE) clean; \ 120 | $(MAKE) main.hex F_CPU=$${clock}000000 DEVICE=atmega$$device BOOTLOADER_ADDRESS=$$addr DEFINES=-DUSE_AUTOCONFIG=1 121 | mv main.hex $@ 122 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | Adafruit Pro Trinket Bootloader 2 | 3 | This is the code for the Pro Trinket bootloader. There are two versions, HV (16MHz 5V) and LV (12MHz 3V), adjust Makefile and recompile. 4 | 5 | Check the Makefile for fuses, etc. For advanced users only - we do not offer any support for this code! 6 | 7 | **Please note: you cannot use the Adafruit USB VID/PID for your own non-Trinket products or projects. Purchase a USB VID for yourself at http://www.usb.org/developers/vendor/** 8 | 9 | Written by Frank Zhao for Adafruit Industries, 2013! 10 | 11 | This code is heavily derived from USBaspLoader, but also from USBtiny, with USBtinyISP's settings 12 | 13 | Copyright (c) 2013,2014 Adafruit Industries All rights reserved. 14 | 15 | ProTrinketBoot is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | 17 | ProTrinketBoot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 18 | 19 | You should have received a copy of the GNU Lesser General Public License along with ProTrinketBoot. If not, see http://www.gnu.org/licenses/. -------------------------------------------------------------------------------- /bootloaderconfig.h: -------------------------------------------------------------------------------- 1 | /* Name: bootloaderconfig.h 2 | * Project: USBaspLoader 3 | * Author: Christian Starkjohann 4 | * Creation Date: 2007-12-08 5 | * Tabsize: 4 6 | * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH 7 | * License: GNU GPL v2 (see License.txt) 8 | * This Revision: $Id$ 9 | */ 10 | 11 | /* Modified by me@frank-zhao.com for project VUSBtinyBoot 12 | * 13 | * VUSBtinyBoot is a bootloader that emulates a USBtinyISP (from Adafruit Industries) 14 | * 15 | * Trinket Pro will use VUSBtinyBoot 16 | * 17 | * This code is heavily derived from USBaspLoader, but also from USBtiny, with USBtinyISP's settings 18 | */ 19 | 20 | #ifndef __bootloaderconfig_h_included__ 21 | #define __bootloaderconfig_h_included__ 22 | 23 | /* 24 | General Description: 25 | This file (together with some settings in Makefile) configures the boot loader 26 | according to the hardware. 27 | */ 28 | 29 | /* ---------------------------- Hardware Config ---------------------------- */ 30 | 31 | #define USB_CFG_IOPORTNAME D 32 | /* This is the port where the USB bus is connected. When you configure it to 33 | * "B", the registers PORTB, PINB and DDRB will be used. 34 | */ 35 | #define USB_CFG_DMINUS_BIT 7 36 | /* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected. 37 | * This may be any bit in the port. 38 | */ 39 | #define USB_CFG_DPLUS_BIT 2 40 | /* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected. 41 | * This may be any bit in the port. Please note that D+ must also be connected 42 | * to interrupt pin INT0! 43 | */ 44 | #define USB_CFG_CLOCK_KHZ (F_CPU/1000) 45 | /* Clock rate of the AVR in MHz. Legal values are 12000, 16000 or 16500. 46 | * The 16.5 MHz version of the code requires no crystal, it tolerates +/- 1% 47 | * deviation from the nominal frequency. All other rates require a precision 48 | * of 2000 ppm and thus a crystal! 49 | * Default if not specified: 12 MHz 50 | */ 51 | 52 | /* ----------------------- Optional Hardware Config ------------------------ */ 53 | 54 | /* #define USB_CFG_PULLUP_IOPORTNAME D */ 55 | /* If you connect the 1.5k pullup resistor from D- to a port pin instead of 56 | * V+, you can connect and disconnect the device from firmware by calling 57 | * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h). 58 | * This constant defines the port on which the pullup resistor is connected. 59 | */ 60 | /* #define USB_CFG_PULLUP_BIT 4 */ 61 | /* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined 62 | * above) where the 1.5k pullup resistor is connected. See description 63 | * above for details. 64 | */ 65 | 66 | #ifndef __ASSEMBLER__ /* assembler cannot parse function definitions */ 67 | 68 | #ifndef MCUCSR /* compatibility between ATMega8 and ATMega88 */ 69 | # define MCUCSR MCUSR 70 | #endif 71 | 72 | #endif /* __ASSEMBLER__ */ 73 | 74 | /* ------------------------------------------------------------------------- */ 75 | 76 | #endif /* __bootloader_h_included__ */ 77 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* VUSBtinyBoot by me@frank-zhao.com 2 | * 3 | * VUSBtinyBoot is a bootloader that emulates a USBtinyISP (from Adafruit Industries) 4 | * 5 | * Trinket Pro (from Adafruit Industries) will use VUSBtinyBoot 6 | * 7 | * This code is heavily derived from USBaspLoader, but also from USBtiny, with USBtinyISP's settings 8 | 9 | Copyright (c) 2013 Adafruit Industries 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions 14 | are met: 15 | 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | * Neither the name of the authors nor the names of its contributors 22 | may be used to endorse or promote products derived from this software 23 | without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 29 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | POSSIBILITY OF SUCH DAMAGE. 36 | */ 37 | 38 | #include 39 | #ifndef MCUSR 40 | #define MCUSR MCUCSR // hack for enabling ATmega8 support 41 | #endif 42 | #define SIGRD 5 // this is missing from some of the io.h files, this is a hack so avr/boot.h can be used 43 | #include "avr_boot.h" 44 | #include 45 | //#include 46 | #include 47 | #include 48 | //#include 49 | #include "pin_defs.h" 50 | #include "optiboot.h" 51 | #include 52 | #include 53 | #include // must be included, because of static function declarations are being used, which saves flash space 54 | 55 | // enable features here 56 | #define ENABLE_FLASH_WRITING 57 | #define ENABLE_FLASH_READING 58 | #define ENABLE_EEPROM_WRITING 59 | #define ENABLE_EEPROM_READING 60 | //#define ENABLE_CHIP_ERASE 61 | //#define ENABLE_CHIP_ERASE_EEPROM_FUSE_CHECK 62 | #define ENABLE_SIG_READING 63 | #define ENABLE_FUSE_READING 64 | #define ENABLE_REQUEST_EXIT // note: enabling this actually decreases code size 65 | #define ENABLE_CLEAN_EXIT // must be used with ENABLE_REQUEST_EXIT 66 | #define ENABLE_OPTIBOOT 67 | #define ENABLE_BLANK_CHECK 68 | 69 | // timeout for the bootloader 70 | #define USBBOOTLOADER_TIMEOUT 10 71 | #define UARTBOOTLOADER_TIMEOUT 3 72 | 73 | enum 74 | { 75 | // Generic requests 76 | USBTINY_ECHO, // echo test 77 | USBTINY_READ, // read byte 78 | USBTINY_WRITE, // write byte 79 | USBTINY_CLR, // clear bit 80 | USBTINY_SET, // set bit 81 | // Programming requests 82 | USBTINY_POWERUP, // apply power (wValue:SCK-period, wIndex:RESET) 83 | USBTINY_POWERDOWN, // remove power from chip 84 | USBTINY_SPI, // issue SPI command (wValue:c1c0, wIndex:c3c2) 85 | USBTINY_POLL_BYTES, // set poll bytes for write (wValue:p1p2) 86 | USBTINY_FLASH_READ, // read flash (wIndex:address) 87 | USBTINY_FLASH_WRITE, // write flash (wIndex:address, wValue:timeout) 88 | USBTINY_EEPROM_READ, // read eeprom (wIndex:address) 89 | USBTINY_EEPROM_WRITE, // write eeprom (wIndex:address, wValue:timeout) 90 | USBTINY_DDRWRITE, // set port direction 91 | USBTINY_SPI1 // a single SPI command 92 | }; 93 | 94 | #if (FLASHEND) > 0xFFFF // need long addressing for large flash 95 | # define CUR_ADDR cur_addr.addr 96 | # define addr_t uint32_t 97 | #else 98 | # define CUR_ADDR cur_addr.u16[0] 99 | # define addr_t uint16_t 100 | #endif 101 | 102 | typedef union longConverter { // utility for manipulating address pointer with proper endianness 103 | addr_t addr; 104 | uint16_t u16[sizeof(addr_t)/2]; 105 | uint8_t u8[sizeof(addr_t)]; 106 | } longConverter_t; 107 | 108 | #ifdef ENABLE_REQUEST_EXIT 109 | static uint8_t req_boot_exit; 110 | #endif 111 | static longConverter_t cur_addr; 112 | static uchar dirty = 0; // if flash needs to be written 113 | static uchar cmd0; // current read/write command byte 114 | static uint8_t remaining; // bytes remaining in current transaction 115 | static uchar buffer[8]; // talk via setup 116 | static uint8_t timeout = 0; // timeout counter for USB comm 117 | volatile char usbHasRxed = 0; // whether or not USB comm is active 118 | #ifdef ENABLE_BLANK_CHECK 119 | static uchar isBlank; // only allow exit if chip isn't blank 120 | #endif 121 | 122 | void (*app_start)(void) = 0x0000; // function at start of flash memory, call to exit bootloader 123 | 124 | // ---------------------------------------------------------------------- 125 | // finishes a write operation if already started 126 | // ---------------------------------------------------------------------- 127 | static void finalize_flash_if_dirty() 128 | { 129 | if (dirty != 0) 130 | { 131 | #ifdef ENABLE_FLASH_WRITING 132 | cli(); 133 | boot_page_write(CUR_ADDR - 2); 134 | sei(); 135 | boot_spm_busy_wait(); 136 | cli(); 137 | boot_rww_enable(); 138 | sei(); 139 | #endif 140 | dirty = 0; 141 | } 142 | } 143 | 144 | #ifdef ENABLE_CHIP_ERASE 145 | // ---------------------------------------------------------------------- 146 | // chip erase 147 | // ---------------------------------------------------------------------- 148 | static void perform_chip_erase() 149 | { 150 | addr_t i; 151 | 152 | for (i = 0; i 153 | #ifdef BOOTLOADER_ADDRESS 154 | < (addr_t)BOOTLOADER_ADDRESS; 155 | #else 156 | <= (addr_t)FLASHEND; 157 | #endif 158 | i += SPM_PAGESIZE) 159 | { 160 | boot_spm_busy_wait(); 161 | cli(); 162 | boot_page_erase(i); 163 | sei(); 164 | } 165 | 166 | #ifdef ENABLE_CHIP_ERASE_EEPROM_FUSE_CHECK 167 | uint8_t hfuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); 168 | if ((hfuse & (1 << 3)) != 0) // the bit location of EESAVE 169 | { 170 | #else 171 | { 172 | #endif 173 | for (i = 0; i <= E2END; i++) 174 | { 175 | eeprom_update_byte((uint8_t *)i, 0xFF); 176 | } 177 | } 178 | } 179 | #endif 180 | 181 | // ---------------------------------------------------------------------- 182 | // Handle a non-standard SETUP packet. 183 | // ---------------------------------------------------------------------- 184 | uchar usbFunctionSetup ( uchar data[8] ) 185 | { 186 | uchar req; 187 | usbRequest_t *rq = (void *)data; 188 | 189 | // reset the bootloader timeout timer 190 | timeout = 0; 191 | // indicate activity 192 | LED_PORT |= _BV(LED); 193 | 194 | // Generic requests 195 | req = data[1]; 196 | if ( req == USBTINY_ECHO ) 197 | { 198 | //usbMsgPtr = data; 199 | return 8; 200 | } 201 | /* 202 | else if ( req == USBTINY_SET || req == USBTINY_CLR || req == USBTINY_WRITE || req == USBTINY_DDRWRITE || req == USBTINY_POWERUP) { 203 | // do nothing 204 | return 0; 205 | } 206 | //*/ 207 | else if ( req == USBTINY_READ) { 208 | // do nothing 209 | return 1; 210 | } 211 | else if ( req == USBTINY_POWERDOWN ) 212 | { 213 | finalize_flash_if_dirty(); 214 | #ifdef ENABLE_REQUEST_EXIT 215 | req_boot_exit = 1; 216 | #endif 217 | return 0; 218 | } 219 | else if ( req == USBTINY_SPI ) 220 | { 221 | finalize_flash_if_dirty(); // partial page writes are not fully written unless this is called here, it must be HERE 222 | 223 | usbMsgPtr = (usbMsgPtr_t)buffer; 224 | 225 | // this tricks "usbtiny_cmd" into succeeding 226 | buffer[2] = data[3]; 227 | 228 | // for the commands, refer to ATmega datasheet under "Serial Programming Instruction Set" 229 | // usage of avr/boot.h here is experimental 230 | 231 | #ifdef ENABLE_SIG_READING 232 | if (data[2] == 0x30 && data[3] == 0x00) { 233 | // read signature byte 234 | buffer[3] = boot_signature_byte_get(data[4] * 2); 235 | } 236 | #ifndef ENABLE_FUSE_READING 237 | else 238 | { 239 | buffer[3] = 0; 240 | } 241 | #endif 242 | #endif 243 | #ifdef ENABLE_FUSE_READING 244 | if (data[2] == 0x50 && data[3] == 0x00 && data[4] == 0x00) { 245 | // read LFUSE 246 | buffer[3] = boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS); 247 | } 248 | else if (data[2] == 0x58 && data[3] == 0x08 && data[4] == 0x00) { 249 | // read HFUSE 250 | buffer[3] = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); 251 | } 252 | else if (data[2] == 0x50 && data[3] == 0x08 && data[4] == 0x00) { 253 | // read EFUSE 254 | buffer[3] = boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS); 255 | } 256 | else if (data[2] == 0x58 && data[3] == 0x00 && data[4] == 0x00) { 257 | // read lock bits 258 | buffer[3] = boot_lock_fuse_bits_get(GET_LOCK_BITS); 259 | } 260 | else if (data[2] == 0x38 && data[3] == 0x00 && data[4] == 0x00) { 261 | // read calibration 262 | buffer[3] = boot_signature_byte_get(0); 263 | } 264 | #endif 265 | #if !defined(ENABLE_SIG_READING) && !defined(ENABLE_FUSE_READING) 266 | buffer[3] = 0; 267 | #endif 268 | 269 | #ifdef ENABLE_CHIP_ERASE 270 | if (data[2] == 0xAC && data[3] == 0x80 && data[4] == 0x00 && data[5] == 0x00) { 271 | perform_chip_erase(); 272 | } 273 | #endif 274 | 275 | // all other commands are unhandled 276 | 277 | return 4; 278 | } 279 | else if ( req == USBTINY_SPI1 ) 280 | { 281 | // I don't know what this is used for, there are no single SPI transactions in the ISP protocol 282 | finalize_flash_if_dirty(); 283 | return 1; 284 | } 285 | else if ( req == USBTINY_POLL_BYTES ) 286 | { 287 | finalize_flash_if_dirty(); 288 | return 0; 289 | } 290 | CUR_ADDR = *((uint16_t*)(&data[4])); 291 | remaining = rq->wLength.bytes[0]; 292 | if ( req >= USBTINY_FLASH_READ && req <= USBTINY_EEPROM_WRITE ) 293 | { 294 | cmd0 = req; 295 | if ( cmd0 != USBTINY_FLASH_WRITE ) { 296 | finalize_flash_if_dirty(); 297 | } 298 | return USB_NO_MSG; // usbFunctionRead() or usbFunctionWrite() will be called to handle the data 299 | } 300 | 301 | // do nothing if nothing done 302 | return 0; 303 | } 304 | 305 | // ---------------------------------------------------------------------- 306 | // Handle an IN packet. 307 | // ---------------------------------------------------------------------- 308 | uchar usbFunctionRead ( uchar* data, uchar len ) 309 | { 310 | uchar i; 311 | 312 | if(len > remaining) { 313 | len = remaining; 314 | } 315 | 316 | remaining -= len; 317 | 318 | for ( i = 0; i < len; i++ ) 319 | { 320 | if (cmd0 == USBTINY_EEPROM_READ) { 321 | #ifdef ENABLE_EEPROM_READING 322 | *data = eeprom_read_byte((void *)cur_addr.u16[0]); 323 | #endif 324 | } 325 | else if (cmd0 == USBTINY_FLASH_READ) { 326 | #ifdef ENABLE_FLASH_READING 327 | *data = pgm_read_byte((void *)CUR_ADDR); 328 | #endif 329 | } 330 | data++; 331 | CUR_ADDR++; 332 | } 333 | return len; 334 | } 335 | 336 | // ---------------------------------------------------------------------- 337 | // Handle an OUT packet. 338 | // ---------------------------------------------------------------------- 339 | uchar usbFunctionWrite ( uchar* data, uchar len ) 340 | { 341 | uchar i, isLast; 342 | 343 | if(len > remaining) { 344 | len = remaining; 345 | } 346 | remaining -= len; 347 | isLast = remaining == 0; 348 | 349 | if (cmd0 == USBTINY_EEPROM_WRITE) 350 | { 351 | #ifdef ENABLE_EEPROM_WRITING 352 | for ( i = 0; i < len; i++ ) { 353 | eeprom_write_byte((void *)(cur_addr.u16[0]++), *data++); 354 | } 355 | #endif 356 | } 357 | else if (cmd0 == USBTINY_FLASH_WRITE) 358 | { 359 | #ifdef ENABLE_FLASH_WRITING 360 | for ( i = 0; i < len; ) 361 | { 362 | if ((cur_addr.u16[0] & (SPM_PAGESIZE - 1)) == 0) { 363 | // page start, erase 364 | cli(); 365 | boot_page_erase(CUR_ADDR); 366 | sei(); 367 | boot_spm_busy_wait(); 368 | } 369 | 370 | dirty = 1; 371 | cli(); 372 | boot_page_fill(CUR_ADDR, *(short *)data); 373 | sei(); 374 | 375 | CUR_ADDR += 2; 376 | data += 2; 377 | i += 2; 378 | 379 | if ((cur_addr.u16[0] & (SPM_PAGESIZE - 1)) == 0) { 380 | // end of page 381 | finalize_flash_if_dirty(); 382 | } 383 | } 384 | #endif 385 | #ifdef ENABLE_BLANK_CHECK 386 | isBlank = 0; 387 | #endif 388 | } 389 | 390 | return isLast; 391 | } 392 | 393 | // ---------------------------------------------------------------------- 394 | // Bootloader main entry point 395 | // ---------------------------------------------------------------------- 396 | int main ( void ) 397 | { 398 | // disable watchdog if previously enabled 399 | MCUSR &= ~(1 << WDRF); 400 | wdt_disable(); 401 | 402 | #ifdef ENABLE_BLANK_CHECK 403 | if (pgm_read_word(0) == 0xFFFF) { 404 | isBlank = 1; 405 | } 406 | else { 407 | isBlank = 0; 408 | } 409 | #endif 410 | 411 | MCUCR = (1 << IVCE); // enable change of interrupt vectors 412 | MCUCR = (1 << IVSEL); // move interrupts to boot flash section 413 | 414 | // start 16-bit timer1 for slow counting time 415 | TCCR1B = 0x05; 416 | 417 | LED_DDR |= _BV(LED); // LED pin on Trinket Pro 418 | 419 | // start USB and force a re-enumeration by faking a disconnect 420 | usbInit(); 421 | usbDeviceDisconnect(); 422 | LED_PORT |= _BV(LED); 423 | while (TCNT1 < 4000); 424 | LED_PORT &= ~_BV(LED); 425 | usbDeviceConnect(); 426 | sei(); 427 | 428 | TCCR1B = 0x01; // speed up timer for PWM LED pulsing 429 | uint8_t t1ovf = 0; 430 | uint16_t duty = 0; 431 | char dutyDir = 0; 432 | 433 | #ifdef ENABLE_OPTIBOOT 434 | optiboot_init(); 435 | #endif 436 | 437 | // main program loop 438 | while (1) 439 | { 440 | usbPoll(); 441 | 442 | #ifdef ENABLE_OPTIBOOT 443 | char ob = optibootPoll(); 444 | if (ob == 1) { 445 | timeout = 0; 446 | } 447 | else if (ob == 2 448 | #ifdef ENABLE_BLANK_CHECK 449 | && isBlank == 0 450 | #endif 451 | ) { 452 | break; 453 | } 454 | #endif 455 | 456 | if ( ((usbHasRxed != 0) && (timeout > USBBOOTLOADER_TIMEOUT) 457 | #ifdef ENABLE_BLANK_CHECK 458 | && isBlank == 0 459 | #endif 460 | ) || ((usbHasRxed == 0) && (timeout > UARTBOOTLOADER_TIMEOUT) 461 | #ifdef ENABLE_BLANK_CHECK 462 | && isBlank == 0 463 | #endif 464 | ) 465 | #ifdef ENABLE_REQUEST_EXIT 466 | || req_boot_exit != 0 467 | #endif 468 | 469 | ) { 470 | // requested exit 471 | // or timed out waiting for activity (timeout means not connected to computer) 472 | break; 473 | } 474 | 475 | uint16_t t = TCNT1; 476 | if ((TIFR1 & _BV(TOV1)) != 0) // if timer has overflowed 477 | { 478 | TIFR1 |= _BV(TOV1); // clear the flag 479 | if (usbHasRxed != 0) 480 | { 481 | LED_PORT |= _BV(LED); 482 | if (duty == 0) { 483 | dutyDir = dutyDir ? 0 : 1; 484 | } 485 | 486 | #define WAITING_LED_FADE_RATE 512 // must be power of 2 487 | if (dutyDir == 0) { 488 | duty -= WAITING_LED_FADE_RATE; 489 | } 490 | else { 491 | duty += WAITING_LED_FADE_RATE; 492 | } 493 | } 494 | t1ovf++; 495 | 496 | // roughly 1 second 497 | #if (F_CPU == 12000000) 498 | if (t1ovf > 183) { 499 | #elif (F_CPU == 16000000) 500 | if (t1ovf > 244) { 501 | #endif 502 | t1ovf = 0; 503 | timeout++; 504 | } 505 | } 506 | 507 | if (usbHasRxed != 0) 508 | { 509 | // fade the LED 510 | if (t > duty) { 511 | LED_PORT &= ~_BV(LED); 512 | } 513 | } 514 | else 515 | { 516 | #define WAITING_LED_BLINK_RATE 16 517 | if ((t1ovf > (WAITING_LED_BLINK_RATE * 0) 518 | && t1ovf < (WAITING_LED_BLINK_RATE * 1)) 519 | || (t1ovf > (WAITING_LED_BLINK_RATE * 2) 520 | && t1ovf < (WAITING_LED_BLINK_RATE * 3)) 521 | #if (F_CPU == 16000000) 522 | || (t1ovf > (WAITING_LED_BLINK_RATE * 4) 523 | && t1ovf < (WAITING_LED_BLINK_RATE * 5)) 524 | #endif 525 | ) { 526 | LED_PORT |= _BV(LED); 527 | } 528 | else { 529 | LED_PORT &= ~_BV(LED); 530 | } 531 | } 532 | } 533 | 534 | // turn off and return port to normal 535 | LED_PORT &= ~_BV(LED); 536 | LED_DDR &= ~_BV(LED); 537 | 538 | #if defined(ENABLE_REQUEST_EXIT) && defined(ENABLE_CLEAN_EXIT) 539 | // wait to finish all USB comms, avoids "avrdude: error: usbtiny_transmit: usb_control_msg: sending control message failed" 540 | TCCR1B = 0x05; // slow down timer 541 | TCNT1 = 0; 542 | while (req_boot_exit != 0 && TCNT1 < 4000) usbPoll(); 543 | #endif 544 | 545 | // cleanup! 546 | 547 | // reset timer 548 | TCCR1B = 0; 549 | TCNT1 = 0; 550 | 551 | // deinitialize USB 552 | USB_INTR_ENABLE = 0; 553 | USB_INTR_CFG = 0; 554 | 555 | // move interrupt back 556 | MCUCR = (1 << IVCE); // enable change of interrupt vectors 557 | MCUCR = (0 << IVSEL); // move interrupts to app flash section 558 | 559 | cli();// disable interrupts 560 | 561 | app_start(); // jump to user app 562 | 563 | return 0; 564 | } 565 | -------------------------------------------------------------------------------- /optiboot.c: -------------------------------------------------------------------------------- 1 | /* VUSBtinyBoot by me@frank-zhao.com 2 | * 3 | * VUSBtinyBoot is a bootloader that emulates a USBtinyISP (from Adafruit Industries) 4 | * 5 | * Trinket Pro (from Adafruit Industries) will use VUSBtinyBoot 6 | * 7 | * This code is heavily derived from USBaspLoader, but also from USBtiny, with USBtinyISP's settings 8 | 9 | * This particular file is mostly a copy of optiboot (April 11, 2013 version) http://optiboot.googlecode.com 10 | * so that Trinket Pro supports both USB and UART bootloading 11 | 12 | Copyright (c) 2013 Adafruit Industries 13 | All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions 17 | are met: 18 | 19 | * Redistributions of source code must retain the above copyright 20 | notice, this list of conditions and the following disclaimer. 21 | * Redistributions in binary form must reproduce the above copyright 22 | notice, this list of conditions and the following disclaimer in the 23 | documentation and/or other materials provided with the distribution. 24 | * Neither the name of the authors nor the names of its contributors 25 | may be used to endorse or promote products derived from this software 26 | without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 29 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 32 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 | POSSIBILITY OF SUCH DAMAGE. 39 | */ 40 | 41 | #define FROM_OPTIBOOT_C 42 | #include "optiboot.h" 43 | #include 44 | #include 45 | 46 | static uint8_t buff[SPM_PAGESIZE * 2]; 47 | static uint16_t address = 0; 48 | static uint8_t length; 49 | 50 | char optibootPoll() 51 | { 52 | unsigned char ch; 53 | if (UART_SRA & _BV(RXC0)) 54 | { 55 | ch = getch(); 56 | 57 | if(ch == STK_GET_PARAMETER) { 58 | unsigned char which = getch(); 59 | if (verifySpace()) return 2; 60 | if (which == 0x82) { 61 | /* 62 | * Send optiboot version as "minor SW version" 63 | */ 64 | putch(OPTIBOOT_MINVER); 65 | } else if (which == 0x81) { 66 | putch(OPTIBOOT_MAJVER); 67 | } else { 68 | /* 69 | * GET PARAMETER returns a generic 0x03 reply for 70 | * other parameters - enough to keep Avrdude happy 71 | */ 72 | putch(0x03); 73 | } 74 | } 75 | else if(ch == STK_SET_DEVICE) { 76 | // SET DEVICE is ignored 77 | if (getNch(20)) return 2; 78 | } 79 | else if(ch == STK_SET_DEVICE_EXT) { 80 | // SET DEVICE EXT is ignored 81 | if (getNch(5)) return 2; 82 | } 83 | else if(ch == STK_LOAD_ADDRESS) { 84 | // LOAD ADDRESS 85 | uint16_t newAddress; 86 | newAddress = getch(); 87 | newAddress = (newAddress & 0xff) | (getch() << 8); 88 | #ifdef RAMPZ 89 | // Transfer top bit to RAMPZ 90 | RAMPZ = (newAddress & 0x8000) ? 1 : 0; 91 | #endif 92 | newAddress += newAddress; // Convert from word address to byte address 93 | address = newAddress; 94 | if (verifySpace()) return 2; 95 | } 96 | else if(ch == STK_UNIVERSAL) { 97 | // UNIVERSAL command is ignored 98 | if (getNch(4)) return 2; 99 | putch(0x00); 100 | } 101 | /* Write memory, length is big endian and is in bytes */ 102 | else if(ch == STK_PROG_PAGE) { 103 | // PROGRAM PAGE - we support flash programming only, not EEPROM 104 | uint8_t *bufPtr; 105 | uint16_t addrPtr; 106 | 107 | getch(); /* getlen() */ 108 | length = getch(); 109 | getch(); 110 | 111 | // If we are in RWW section, immediately start page erase 112 | if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); 113 | 114 | // While that is going on, read in page contents 115 | bufPtr = buff; 116 | do *bufPtr++ = getch(); 117 | while (--length); 118 | 119 | // If we are in NRWW section, page erase has to be delayed until now. 120 | // Todo: Take RAMPZ into account (not doing so just means that we will 121 | // treat the top of both "pages" of flash as NRWW, for a slight speed 122 | // decrease, so fixing this is not urgent.) 123 | if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address); 124 | 125 | // Read command terminator, start reply 126 | if (verifySpace()) return 2; 127 | 128 | // If only a partial page is to be programmed, the erase might not be complete. 129 | // So check that here 130 | boot_spm_busy_wait(); 131 | 132 | // Copy buffer into programming buffer 133 | bufPtr = buff; 134 | addrPtr = (uint16_t)(void*)address; 135 | ch = SPM_PAGESIZE / 2; 136 | do { 137 | uint16_t a; 138 | a = *bufPtr++; 139 | a |= (*bufPtr++) << 8; 140 | __boot_page_fill_short((uint16_t)(void*)addrPtr,a); 141 | addrPtr += 2; 142 | } while (--ch); 143 | 144 | // Write from programming buffer 145 | __boot_page_write_short((uint16_t)(void*)address); 146 | boot_spm_busy_wait(); 147 | 148 | #if defined(RWWSRE) 149 | // Reenable read access to flash 150 | boot_rww_enable(); 151 | #endif 152 | 153 | } 154 | /* Read memory block mode, length is big endian. */ 155 | else if(ch == STK_READ_PAGE) { 156 | // READ PAGE - we only read flash 157 | getch(); /* getlen() */ 158 | length = getch(); 159 | getch(); 160 | 161 | if (verifySpace()) return 2; 162 | do { 163 | #if defined(RAMPZ) 164 | // Since RAMPZ should already be set, we need to use EPLM directly. 165 | // Also, we can use the autoincrement version of lpm to update "address" 166 | // do putch(pgm_read_byte_near(address++)); 167 | // while (--length); 168 | // read a Flash and increment the address (may increment RAMPZ) 169 | __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address)); 170 | #else 171 | // read a Flash byte and increment the address 172 | __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address)); 173 | #endif 174 | putch(ch); 175 | } while (--length); 176 | } 177 | 178 | /* Get device signature bytes */ 179 | else if(ch == STK_READ_SIGN) { 180 | // READ SIGN - return what Avrdude wants to hear 181 | if (verifySpace()) return 2; 182 | putch(SIGNATURE_0); 183 | putch(SIGNATURE_1); 184 | putch(SIGNATURE_2); 185 | } 186 | else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */ 187 | // Adaboot no-wait mod 188 | wdt_enable(WDTO_30MS); 189 | if (verifySpace()) return 2; 190 | putch(STK_OK); 191 | //app_start(); // jump to user app 192 | return 2; // never reached! 193 | } 194 | else { 195 | // This covers the response to commands like STK_ENTER_PROGMODE 196 | if (verifySpace()) return 2; 197 | } 198 | putch(STK_OK); 199 | return 1; 200 | } 201 | return 0; 202 | } 203 | 204 | void putch(char ch) { 205 | while (!(UART_SRA & _BV(UDRE0))); 206 | UART_UDR = ch; 207 | } 208 | 209 | uint8_t getch(void) { 210 | uint8_t ch; 211 | 212 | #ifdef LED_DATA_FLASH 213 | #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) 214 | LED_PORT ^= _BV(LED); 215 | #else 216 | LED_PIN |= _BV(LED); 217 | #endif 218 | #endif 219 | 220 | int32_t timeout = OPTIBOOT_UART_TIMEOUT; 221 | while(!(UART_SRA & _BV(RXC0))) { 222 | timeout-=10; 223 | if (timeout <= 0) { 224 | app_start(); // jump to user app 225 | } 226 | _delay_us(10); 227 | } 228 | 229 | ch = UART_UDR; 230 | 231 | #ifdef LED_DATA_FLASH 232 | #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) 233 | LED_PORT ^= _BV(LED); 234 | #else 235 | LED_PIN |= _BV(LED); 236 | #endif 237 | #endif 238 | 239 | return ch; 240 | } 241 | 242 | // return 0 on success 243 | char getNch(uint8_t count) { 244 | do getch(); while (--count); 245 | if (verifySpace()) return 2; 246 | return 0; 247 | } 248 | 249 | // return 0 on success 250 | char verifySpace() { 251 | if (getch() != CRC_EOP) { 252 | return 1; 253 | } 254 | putch(STK_INSYNC); 255 | return 0; 256 | } 257 | 258 | void optiboot_init(void) 259 | { 260 | #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) 261 | UCSRA = _BV(U2X); //Double speed mode USART 262 | UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx 263 | UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1 264 | UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); 265 | #else 266 | UART_SRA = _BV(U2X0); //Double speed mode USART0 267 | UART_SRB = _BV(RXEN0) | _BV(TXEN0); 268 | UART_SRC = _BV(UCSZ00) | _BV(UCSZ01); 269 | UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 ); 270 | // set RX pin to have a pullup? 271 | DDRD |= _BV(PD0); 272 | #endif 273 | } 274 | -------------------------------------------------------------------------------- /optiboot.h: -------------------------------------------------------------------------------- 1 | /* VUSBtinyBoot by me@frank-zhao.com 2 | * 3 | * VUSBtinyBoot is a bootloader that emulates a USBtinyISP (from Adafruit Industries) 4 | * 5 | * Trinket Pro (from Adafruit Industries) will use VUSBtinyBoot 6 | * 7 | * This code is heavily derived from USBaspLoader, but also from USBtiny, with USBtinyISP's settings 8 | 9 | * This particular file is mostly a copy of optiboot (April 11, 2013 version) http://optiboot.googlecode.com 10 | * so that Trinket Pro supports both USB and UART bootloading 11 | 12 | Copyright (c) 2013 Adafruit Industries 13 | All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions 17 | are met: 18 | 19 | * Redistributions of source code must retain the above copyright 20 | notice, this list of conditions and the following disclaimer. 21 | * Redistributions in binary form must reproduce the above copyright 22 | notice, this list of conditions and the following disclaimer in the 23 | documentation and/or other materials provided with the distribution. 24 | * Neither the name of the authors nor the names of its contributors 25 | may be used to endorse or promote products derived from this software 26 | without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 29 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 32 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 | POSSIBILITY OF SUCH DAMAGE. 39 | */ 40 | 41 | #ifndef OPTIBOOT_H_ 42 | #define OPTIBOOT_H_ 43 | 44 | #define OPTIBOOT_UART_TIMEOUT 1000000 // in microseconds 45 | 46 | char optibootPoll(void); 47 | void optiboot_init(void); 48 | 49 | #ifdef FROM_OPTIBOOT_C 50 | 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include "avr_boot.h" 56 | #include "stk500.h" 57 | #include "pin_defs.h" 58 | 59 | void putch(char); 60 | uint8_t getch(void); 61 | static inline char getNch(uint8_t); /* "static inline" is a compiler hint to reduce code size */ 62 | char verifySpace(void); 63 | uint8_t getLen(void); 64 | 65 | #define OPTIBOOT_MAJVER 5 66 | #define OPTIBOOT_MINVER 0 67 | 68 | #define LED_DATA_FLASH 69 | 70 | #ifndef BAUD_RATE 71 | #if F_CPU >= 8000000L 72 | #define BAUD_RATE 115200L // Highest rate Avrdude win32 will support 73 | #elif F_CPU >= 1000000L 74 | #define BAUD_RATE 9600L // 19200 also supported, but with significant error 75 | #elif F_CPU >= 128000L 76 | #define BAUD_RATE 4800L // Good for 128kHz internal RC 77 | #else 78 | #define BAUD_RATE 1200L // Good even at 32768Hz 79 | #endif 80 | #endif 81 | 82 | #define BAUD_SETTING (( (F_CPU + BAUD_RATE * 4L) / ((BAUD_RATE * 8L))) - 1 ) 83 | #define BAUD_ACTUAL (F_CPU/(8 * ((BAUD_SETTING)+1))) 84 | #define BAUD_ERROR (( 100*(BAUD_RATE - BAUD_ACTUAL) ) / BAUD_RATE) 85 | 86 | #if BAUD_ERROR >= 5 87 | #error BAUD_RATE error greater than 5% 88 | #elif BAUD_ERROR <= -5 89 | #error BAUD_RATE error greater than -5% 90 | #elif BAUD_ERROR >= 2 91 | #warning BAUD_RATE error greater than 2% 92 | #elif BAUD_ERROR <= -2 93 | #warning BAUD_RATE error greater than -2% 94 | #endif 95 | 96 | #ifndef UART 97 | #define UART 0 98 | #endif 99 | 100 | #if defined(__AVR_ATmega168__) 101 | #define RAMSTART (0x100) 102 | #define NRWWSTART (0x3800) 103 | #elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega32__) 104 | #define RAMSTART (0x100) 105 | #define NRWWSTART (0x7000) 106 | #elif defined (__AVR_ATmega644P__) 107 | #define RAMSTART (0x100) 108 | #define NRWWSTART (0xE000) 109 | // correct for a bug in avr-libc 110 | #undef SIGNATURE_2 111 | #define SIGNATURE_2 0x0A 112 | #elif defined (__AVR_ATmega1284P__) 113 | #define RAMSTART (0x100) 114 | #define NRWWSTART (0xE000) 115 | #elif defined(__AVR_ATtiny84__) 116 | #define RAMSTART (0x100) 117 | #define NRWWSTART (0x0000) 118 | #elif defined(__AVR_ATmega1280__) 119 | #define RAMSTART (0x200) 120 | #define NRWWSTART (0xE000) 121 | #elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__) 122 | #define RAMSTART (0x100) 123 | #define NRWWSTART (0x1800) 124 | #endif 125 | 126 | #if UART == 0 127 | # define UART_SRA UCSR0A 128 | # define UART_SRB UCSR0B 129 | # define UART_SRC UCSR0C 130 | # define UART_SRL UBRR0L 131 | # define UART_UDR UDR0 132 | #elif UART == 1 133 | #if !defined(UDR1) 134 | #error UART == 1, but no UART1 on device 135 | #endif 136 | # define UART_SRA UCSR1A 137 | # define UART_SRB UCSR1B 138 | # define UART_SRC UCSR1C 139 | # define UART_SRL UBRR1L 140 | # define UART_UDR UDR1 141 | #elif UART == 2 142 | #if !defined(UDR2) 143 | #error UART == 2, but no UART2 on device 144 | #endif 145 | # define UART_SRA UCSR2A 146 | # define UART_SRB UCSR2B 147 | # define UART_SRC UCSR2C 148 | # define UART_SRL UBRR2L 149 | # define UART_UDR UDR2 150 | #elif UART == 3 151 | #if !defined(UDR1) 152 | #error UART == 3, but no UART3 on device 153 | #endif 154 | # define UART_SRA UCSR3A 155 | # define UART_SRB UCSR3B 156 | # define UART_SRC UCSR3C 157 | # define UART_SRL UBRR3L 158 | # define UART_UDR UDR3 159 | #endif 160 | 161 | #endif 162 | 163 | #endif 164 | -------------------------------------------------------------------------------- /protrinket_12mhz.hex: -------------------------------------------------------------------------------- 1 | :1070000058C000008BC000006FC000006DC00000C1 2 | :107010006BC0000069C0000067C0000065C00000D0 3 | :1070200063C0000061C000005FC000005DC00000E0 4 | :107030005BC0000059C0000057C0000055C00000F0 5 | :1070400053C0000051C000004FC000004DC0000000 6 | :107050004BC0000049C0000047C0000045C0000010 7 | :1070600043C0000041C0000009021200010100807D 8 | :107070003209040000000000000012011001FF00AE 9 | :10708000000881179F0C0501010200011003550043 10 | :1070900053004200740069006E0079001203410041 11 | :1070A00064006100660072007500690074000403EA 12 | :1070B000090411241FBECFEFD8E0DEBFCDBF11E021 13 | :1070C000A0E0B1E0EAE1FCE702C005900D92A23039 14 | :1070D000B107D9F712E0A2E0B1E001C01D92A334DC 15 | :1070E000B107E1F7B7D497C58BCFA82FB92F80E0B0 16 | :1070F00090E041E050EA609530E009C02D91822790 17 | :107100009795879510F084279527305EC8F36F5FB9 18 | :10711000A8F30895EADF8D939D930895CF93CFB799 19 | :10712000CF93C3954F9BE9F74F9B09C04F9B07C077 20 | :107130004F9B05C04F9B03C04F9B01C0A1C0DF9375 21 | :10714000C0912602DD27C35DDD4F4F9B02C0DF915A 22 | :10715000EBCF2F930F931F9309B12FEF07FB20F96C 23 | :107160004F933F9319B14FEF012707FB21F93BE004 24 | :1071700031C04E7F012F19B1216028C0102F4D7FE3 25 | :107180002260000009B129C04B7F2460012F00005C 26 | :1071900019B12BC019B1477F28602AC04F7E09B1B1 27 | :1071A00020612CC04F7D19B120622FC04F7B09B1E7 28 | :1071B000206432C0422709B149934FEF00001027E5 29 | :1071C00017FB20F919B11478C9F1297F91F2012731 30 | :1071D00007FB21F909B1237F89F2315058F11027BB 31 | :1071E00017FB22F919B1277E79F2012707FB23F952 32 | :1071F0002F7C81F209B1102717FB24F92F7971F246 33 | :1072000000C019B1012707FB25F92F7359F200C0FF 34 | :1072100009B1102717FB26F9223040F200C019B13E 35 | :10722000012707FB27F9243028F64F77206819B18A 36 | :107230000000F9CF11E01CBB002717C03B5031956F 37 | :10724000C31BD04011E01CBB0881033CE9F00B34A8 38 | :10725000D9F0209124021981110F1213EDCF0936B4 39 | :1072600041F10D3211F0013E39F700932B023F91AD 40 | :107270004F911F910F912F91DF91CCB3C0FD51CF52 41 | :10728000CF91CFBFCF91189520912B02222379F374 42 | :1072900010912902112311F5343012F13093290293 43 | :1072A00020932502109126023BE0311B30932602E9 44 | :1072B00017C00091290201308CF40AE530910001D9 45 | :1072C00034FD10C000930001C9E1D2E00FC0279542 46 | :1072D000A8F45150A9F4220F0000F9CF4AE503C0E9 47 | :1072E00042ED01C0432FC4E1D0E032E01AB114688E 48 | :1072F0005F9A1AB90BB120E414E85F93012756E0B6 49 | :107300000BB9279520F4515021F4220FF9CF012712 50 | :1073100056E000003B5A0BB9D0F2279528F45150A3 51 | :1073200029F4220F0000F9CF012756E027950BB969 52 | :1073300020F4515021F4220FF9CF012756E0299172 53 | :1073400033230BB921F60B7710912A02110FC65186 54 | :10735000D0400BB911F01093240211E01CBB00685F 55 | :107360001AB11B77402F4B775F9100C000C00BB95B 56 | :107370001AB94BB97CCF809115018823A1F0F894FC 57 | :10738000E0911101F0911201329785E087BFE895F5 58 | :10739000789407B600FCFDCFF89481E187BFE895AB 59 | :1073A0007894109215010895AF92BF92CF92DF9218 60 | :1073B000EF92FF920F931F93CF93DF931F92CDB75E 61 | :1073C000DEB780912902835087FD96C190912602F5 62 | :1073D0004CE0A42EB12CA91AB1082DE232E0A20E85 63 | :1073E000B31E11E010930401909125029D3209F023 64 | :1073F00013C1883009F07EC183EC809319028AE5BD 65 | :107400008093000110920801D5018C91807609F4D7 66 | :1074100091C0109206012D9A11962C91222309F405 67 | :1074200003C2213009F402C2263021F4A4DF1093F4 68 | :10743000070169C0273009F05FC09DDF89E091E056 69 | :107440009093280280932702F501838180930B019A 70 | :107450009281903339F4811114C0E481F0E0EE0F91 71 | :10746000FF1F43C0903579F481111FC084818111C1 72 | :1074700008C089E0E0E0F0E08093570084918093B9 73 | :107480000C0124E0BEC0983539F5883019F0882306 74 | :10749000C1F0F7CFF50184818111F3CF89E0E3E0FA 75 | :1074A000F0E0809357008491EACF883051F78481CF 76 | :1074B0008111E7CF89E0E2E0F0E08093570084910A 77 | :1074C000DECFF50184818111DCCF89E0E1E0F0E0DD 78 | :1074D000809357008491D3CF983399F68111D1CFFF 79 | :1074E00084818111CECFE0E0F0E081E2809357000B 80 | :1074F000E491E0930C01C5CF2E3011F43CDF96C12E 81 | :10750000283019F438DF20E07CC0F50184819581B2 82 | :107510009093120180931101868180931301822F31 83 | :107520008950843080F7209314012A3009F476C101 84 | :1075300022DF74C1D50112969C91129710922202FB 85 | :1075400011968C91811106C01092230282E292E082 86 | :1075500022E04BC0853019F490932A023CC086305B 87 | :1075600089F5F5018381813019F48AE790E704C039 88 | :10757000823041F488E690E79093280280932702B6 89 | :1075800022E11CC08330C9F4911108C08EEA90E753 90 | :10759000909328028093270224E010C0913019F4C0 91 | :1075A0008CE990E7E9CF923041F48CE890E7909332 92 | :1075B00028028093270220E101C020E080E480932C 93 | :1075C00008011FC0883059F0893019F490932C02BB 94 | :1075D00002C08A3039F082E292E020E006C08CE2FC 95 | :1075E00092E002C082E292E021E090932802809330 96 | :1075F000270207C0D50116962C9180E880930801D8 97 | :1076000008C0F5018781811104C08681821708F4C2 98 | :10761000282F209301016EC09091080197FF6AC046 99 | :10762000F0901301E82EF81608F4EF2CFE18F092F3 100 | :107630001301809114018C30B1F485010FC0D80181 101 | :107640006D918D0180911101909112019C012F5F2C 102 | :107650003F4F3093120120931101CFD2802F8A190E 103 | :107660008E1568F343C08A3009F040C0850123E0DD 104 | :10767000C22EDD24D39433C0809111019091120168 105 | :107680008F779927892BF1F0D0921501F894E0912A 106 | :107690001101F0911201D8018D919D918D010C0184 107 | :1076A000D7BEE89511247894809111019091120130 108 | :1076B000029690931201809311018F779927892B5D 109 | :1076C00071F40CC0F894E0911101F0911201C7BE61 110 | :1076D000E895789407B600FCFDCFD6CF4CDE802F1E 111 | :1076E0008A198E1508F4C8CF10920501F11002C056 112 | :1076F00010920101109229028091000184FF83C041 113 | :10770000809101018F3F09F47EC0F82E893010F07E 114 | :1077100098E0F92E8F19809301018091190298E861 115 | :10772000892780931902FF2009F45BC0209108018A 116 | :1077300027FF31C0809113018F1508F4F82E8F199F 117 | :1077400080931301209114018AE1C82E82E0D82E83 118 | :10775000EC2C1CC000911101109112012B3039F456 119 | :10776000C801298342D2F6018083298106C02930CD 120 | :1077700021F4F8018491D6018C93BFEFCB1ADB0A78 121 | :107780000F5F1F4F10931201009311018C2D8E1962 122 | :107790008F1500F323C0809127029091280226FFC5 123 | :1077A0000BC0FC01AAE1B2E02F2D2A0F34913D93CA 124 | :1077B00031962A13FBCF09C0DC01EAE1F2E02F2D5C 125 | :1077C0002E0F3D9131932E13FCCF01962F2D21507A 126 | :1077D000820F911D9093280280932702E8E0EF1515 127 | :1077E00060F06F2D8AE192E095DC8F2D8C5F8C30FC 128 | :1077F00041F09FEF9093010104C08FEF809301014E 129 | :107800008EE18093000184E199B1947889F48150EC 130 | :10781000D9F710922A02109224020AC0D5018C9145 131 | :1078200087FDE8CE2FEFE9CE28E0EBCE21E0E9CED0 132 | :107830000F90DF91CF911F910F91FF90EF90DF900C 133 | :10784000CF90BF90AF9008959091C00095FFFCCF6E 134 | :107850008093C60008951D9A8091C00087FFFCCFD9 135 | :107860008091C6001D9A0895F6DF803221F484E1EC 136 | :10787000EBDF80E0089581E00895CF93C82FEBDF20 137 | :10788000C150E9F7F1DF882311F082E001C080E008 138 | :10789000CF910895EF92FF920F931F93CF93DF93B1 139 | :1078A0008091C00087FFC1C0D6DF813479F4D3DF77 140 | :1078B000C82FDADF8111B1C0C23811F480E0A4C052 141 | :1078C000C13811F485E0A0C083E09EC0823411F479 142 | :1078D00084E103C0853429F485E0CFDF81119DC0A8 143 | :1078E000A0C0853569F4B7DFC82FB5DF382F20E099 144 | :1078F0002C2B220F331F30931701209316018FC0BA 145 | :10790000863529F484E0B9DF811187C0D7CF84366A 146 | :1079100009F054C0A0DF9FDF809318019CDFC09165 147 | :107920001601D0911701C11560E7D60720F483E056 148 | :10793000FE0187BFE89509E111E08DDFF801819331 149 | :107940008F01809118018150809318018111F5CF2A 150 | :10795000C115F0E7DF0720F083E0FE0187BFE8955F 151 | :1079600083DF81115AC007B600FCFDCF20911901B9 152 | :1079700080E090E041E0DC01A75EBE4FFC01EC0F2F 153 | :10798000FD1F1196FC901197E12CB701622B9B0112 154 | :10799000090147BFE89511248E37910521F0129611 155 | :1079A0002C910296E8CF85E0FE0187BFE89507B6E7 156 | :1079B00000FCFDCF81E187BFE89533C08437D1F467 157 | :1079C0004ADF49DF8093180146DF4EDF811125C071 158 | :1079D000E0911601F09117018591F0931701E09362 159 | :1079E000160132DF809118018150809318018111B6 160 | :1079F000EFCF17C0853751F437DF81110EC08EE10C 161 | :107A000023DF85E921DF8FE01FDF0BC0813539F4EB 162 | :107A10002BDF811102C080E117DF82E007C024DF85 163 | :107A20005DCF80E111DF81E001C080E0DF91CF9187 164 | :107A30001F910F91FF90EF90089582E08093C00016 165 | :107A400088E18093C10086E08093C2008CE080933F 166 | :107A5000C40008950F931F93CF93DF9384B7877F5C 167 | :107A600084BF88E10FB6F8948093600010926000A4 168 | :107A70000FBEE0E0F0E085919491019621F481E061 169 | :107A80008093050102C01092050181E085BF82E06C 170 | :107A900085BF85E080938100259A8091690082608E 171 | :107AA00080936900E89A579A2D9A8091840090916A 172 | :107AB0008500803A9F40C8F32D985798789481E0CC 173 | :107AC00080938100BADF00E0C0E0D0E010E06CDC21 174 | :107AD000E1DE813019F41092060107C0823029F4EA 175 | :107AE00080910501882309F451C080910401882305 176 | :107AF00049F0809106018B3028F0809105018823A0 177 | :107B000009F444C080910401811108C080910601EC 178 | :107B1000843020F0809105018823C1F18091070114 179 | :107B2000811134C08091840090918500B09B1AC06F 180 | :107B3000B09A20910401222361F02D9A209721F41C 181 | :107B400021E0011120E0022F011102C0D25001C03A 182 | :107B5000DE5F1F5F183B30F0209106012F5F2093FE 183 | :107B6000060110E020910401222329F0C817D9074B 184 | :107B700008F0ADCF09C0812F81508F3018F08052AE 185 | :107B80008F3010F42D9AA3CF2D98A1CF2D98259842 186 | :107B900085E080938100109285001092840001C0DE 187 | :107BA00003DC80910701882339F080918400909153 188 | :107BB0008500803A9F40A0F31092810010928500CA 189 | :107BC000109284001DBA1092690081E085BF15BE35 190 | :107BD000F894E0910201F0910301099580E090E0B2 191 | :107BE000DF91CF911F910F910895F999FECF92BD2A 192 | :107BF00081BDF89A992780B50895262FF999FECF6F 193 | :107C00001FBA92BD81BD20BD0FB6F894FA9AF99AB9 194 | :0A7C10000FBE01960895F894FFCF0F 195 | :027C1A005AFF0F 196 | :040000030000700089 197 | :00000001FF 198 | -------------------------------------------------------------------------------- /protrinket_16mhz.hex: -------------------------------------------------------------------------------- 1 | :1070000058C000008BC000006FC000006DC00000C1 2 | :107010006BC0000069C0000067C0000065C00000D0 3 | :1070200063C0000061C000005FC000005DC00000E0 4 | :107030005BC0000059C0000057C0000055C00000F0 5 | :1070400053C0000051C000004FC000004DC0000000 6 | :107050004BC0000049C0000047C0000045C0000010 7 | :1070600043C0000041C0000009021200010100807D 8 | :107070003209040000000000000012011001FF00AE 9 | :10708000000881179F0C0501010200011003550043 10 | :1070900053004200740069006E0079001203410041 11 | :1070A00064006100660072007500690074000403EA 12 | :1070B000090411241FBECFEFD8E0DEBFCDBF11E021 13 | :1070C000A0E0B1E0E6E4FCE702C005900D92A2303A 14 | :1070D000B107D9F712E0A2E0B1E001C01D92A334DC 15 | :1070E000B107E1F7CAD4ADC58BCFA82FB92F80E087 16 | :1070F00090E041E050EA609530E009C02D91822790 17 | :107100009795879510F084279527305EC8F36F5FB9 18 | :10711000A8F30895EADF8D939D930895CF93CFB799 19 | :10712000CF93DF93C3954F9BE9F74F9B0BC04F9BCA 20 | :1071300009C04F9B07C04F9B05C04F9B03C04F9B8F 21 | :1071400001C089C06F93C0912602DD27C35DDD4F6A 22 | :107150002F9365E54F9B03C02F916F91E6CF0F935F 23 | :107160001F934F9320E040E15F9309B1047807FB40 24 | :1071700027F93F9350E03BE039C0147840642F7703 25 | :10718000012F5F5F1EC0406819B114782F775250ED 26 | :107190001FC0406409B12F770478D1F15F5F00C050 27 | :1071A00023C0406219B12F77147891F15F5F00C05E 28 | :1071B00025C004781027515012F45D5F0000115073 29 | :1071C00027952C3F19B1C8F614780127015027954F 30 | :1071D0002C3FC8F64227499309B1047810274F7312 31 | :1071E000115027952C3FA8F64695469519B114786D 32 | :1071F00079F00127015027952C3F98F66B5A60F3E0 33 | :10720000315009B1B0F600C011E01CBB002717C017 34 | :107210003B503195C31BD04011E01CBB0881033C9F 35 | :10722000F9F00B34E9F0209124021981110F1213A7 36 | :10723000EDCF093651F10D3211F0013E39F70093CF 37 | :107240002B023F915F914F911F910F912F916F9161 38 | :10725000CCB3C0FD67CFDF91CF91CFBFCF91189551 39 | :1072600020912B02222369F310912902112339F571 40 | :1072700034303AF1309329022093250210912602EE 41 | :107280003BE0311B309326021CC0009129020130E3 42 | :10729000B4F40AE53091000134FD14C000930001FC 43 | :1072A000C9E1D2E013C0052710E000C000000BB90F 44 | :1072B0001AC0052710E0221F1DC010E021C04AE5BA 45 | :1072C00002C032ED432FC4E1D0E032E01AB11468BD 46 | :1072D0005F9A0BB11AB954E820E865E320FF05274F 47 | :1072E0000BB9279517951C3FF0F66695B8F7B1F7DF 48 | :1072F00020FF05270BB9279517951C3FD0F627953A 49 | :10730000179517FF052700001C3F0BB9B0F6299110 50 | :107310003A9519F70B7710912A02110FC651D040F8 51 | :107320000BB911F01093240211E01CBB00681AB1D4 52 | :107330001B77402F4B7754E05A95F1F70BB91AB9E8 53 | :107340004BB97FCF809115018823A1F0F894E0918B 54 | :107350001101F0911201329785E087BFE89578948A 55 | :1073600007B600FCFDCFF89481E187BFE8957894DB 56 | :10737000109215010895AF92BF92CF92DF92EF92D3 57 | :10738000FF920F931F93CF93DF931F92CDB7DEB77A 58 | :1073900080912902835087FD96C1909126024CE08E 59 | :1073A000A42EB12CA91AB1082DE232E0A20EB31E10 60 | :1073B00011E010930401909125029D3209F013C150 61 | :1073C000883009F07EC183EC809319028AE58093AE 62 | :1073D000000110920801D5018C91807609F491C0CA 63 | :1073E000109206012D9A11962C91222309F403C2C2 64 | :1073F000213009F402C2263021F4A4DF10930701E2 65 | :1074000069C0273009F05FC09DDF89E091E090936B 66 | :10741000280280932702F501838180930B019281DA 67 | :10742000903339F4811114C0E481F0E0EE0FFF1FB6 68 | :1074300043C0903579F481111FC08481811108C047 69 | :1074400089E0E0E0F0E080935700849180930C01A4 70 | :1074500024E0BEC0983539F5883019F08823C1F092 71 | :10746000F7CFF50184818111F3CF89E0E3E0F0E00B 72 | :10747000809357008491EACF883051F7848181113D 73 | :10748000E7CF89E0E2E0F0E0809357008491DECF1F 74 | :10749000F50184818111DCCF89E0E1E0F0E08093A7 75 | :1074A00057008491D3CF983399F68111D1CF84813D 76 | :1074B0008111CECFE0E0F0E081E280935700E491CB 77 | :1074C000E0930C01C5CF2E3011F43CDF96C128307B 78 | :1074D00019F438DF20E07CC0F50184819581909318 79 | :1074E000120180931101868180931301822F8950AC 80 | :1074F000843080F7209314012A3009F476C122DF0A 81 | :1075000074C1D50112969C91129710922202119685 82 | :107510008C91811106C01092230282E292E022E057 83 | :107520004BC0853019F490932A023CC0863089F50F 84 | :10753000F5018381813019F48AE790E704C0823035 85 | :1075400041F488E690E7909328028093270222E195 86 | :107550001CC08330C9F4911108C08EEA90E7909363 87 | :1075600028028093270224E010C0913019F48CE99E 88 | :1075700090E7E9CF923041F48CE890E790932802AD 89 | :107580008093270220E101C020E080E4809308017D 90 | :107590001FC0883059F0893019F490932C0202C032 91 | :1075A0008A3039F082E292E020E006C08CE292E07C 92 | :1075B00002C082E292E021E09093280280932702A9 93 | :1075C00007C0D50116962C9180E88093080108C069 94 | :1075D000F5018781811104C08681821708F4282F64 95 | :1075E000209301016EC09091080197FF6AC0F0904E 96 | :1075F0001301E82EF81608F4EF2CFE18F092130190 97 | :10760000809114018C30B1F485010FC0D8016D91C7 98 | :107610008D0180911101909112019C012F5F3F4FCC 99 | :107620003093120120931101FED2802F8A198E15FA 100 | :1076300068F343C08A3009F040C0850123E0C22EC0 101 | :10764000DD24D39433C080911101909112018F7782 102 | :107650009927892BF1F0D0921501F894E09111014E 103 | :10766000F0911201D8018D919D918D010C01D7BE31 104 | :10767000E89511247894809111019091120102965D 105 | :1076800090931201809311018F779927892B71F4C0 106 | :107690000CC0F894E0911101F0911201C7BEE89579 107 | :1076A000789407B600FCFDCFD6CF4CDE802F8A1928 108 | :1076B0008E1508F4C8CF10920501F11002C0109287 109 | :1076C0000101109229028091000184FF83C0809102 110 | :1076D00001018F3F09F47EC0F82E893010F098E048 111 | :1076E000F92E8F19809301018091190298E889275A 112 | :1076F00080931902FF2009F45BC02091080127FF45 113 | :1077000031C0809113018F1508F4F82E8F198093E2 114 | :107710001301209114018AE1C82E82E0D82EEC2CAE 115 | :107720001CC000911101109112012B3039F4C801D5 116 | :10773000298371D2F6018083298106C0293021F482 117 | :10774000F8018491D6018C93BFEFCB1ADB0A0F5F4F 118 | :107750001F4F10931201009311018C2D8E198F155C 119 | :1077600000F323C0809127029091280226FF0BC0CE 120 | :10777000FC01AAE1B2E02F2D2A0F34913D933196FE 121 | :107780002A13FBCF09C0DC01EAE1F2E02F2D2E0F16 122 | :107790003D9131932E13FCCF01962F2D2150820F56 123 | :1077A000911D9093280280932702E8E0EF1560F086 124 | :1077B0006F2D8AE192E0AEDC8F2D8C5F8C3041F032 125 | :1077C0009FEF9093010104C08FEF809301018EE140 126 | :1077D0008093000184E199B1947889F48150D9F7BC 127 | :1077E00010922A02109224020AC0D5018C9187FDC2 128 | :1077F000E8CE2FEFE9CE28E0EBCE21E0E9CE0F90E6 129 | :10780000DF91CF911F910F91FF90EF90DF90CF907C 130 | :10781000BF90AF9008959091C00095FFFCCF8093EA 131 | :10782000C6000895CF92DF92EF92FF921D9A80E4F6 132 | :10783000C82E82E4D82E8FE0E82EF12C10C08AE00A 133 | :10784000C81AD108E108F1081C141D041E041F0405 134 | :1078500014F00E94810085E38A95F1F70000809181 135 | :10786000C00087FFECCF8091C6001D9AFF90EF907B 136 | :10787000DF90CF900895D6DF803221F484E1CBDF12 137 | :1078800080E0089581E00895CF93C82FCBDFC150E9 138 | :10789000E9F7F1DF882311F082E001C080E0CF91A9 139 | :1078A00008950F931F93CF93DF938091C00087FFBC 140 | :1078B000D0C0B8DF813479F4B5DFC82FDCDF8111A7 141 | :1078C000C0C0C23811F480E0A8C0C13811F485E00E 142 | :1078D000A4C083E0A2C0823411F484E103C08534E3 143 | :1078E00029F485E0D1DF8111ACC0AFC0853569F4E2 144 | :1078F00099DFC82F97DF382F20E02C2B220F331F62 145 | :1079000030931701209316019EC0863529F484E038 146 | :10791000BBDF811196C0D7CF843609F058C082DF13 147 | :1079200081DF809318017EDFE0911601F09117014D 148 | :10793000E11580E7F80718F483E087BFE895C9E10F 149 | :10794000D1E070DF899380911801815080931801F4 150 | :107950008111F7CFE0911601F0911701E115C0E711 151 | :10796000FC0718F083E087BFE89585DF811169C0C7 152 | :1079700007B600FCFDCF2091160130911701409110 153 | :10798000190180E090E061E0DC01A75EBE4FFC01E0 154 | :10799000E20FF31F11961C91119700E0E801C42B30 155 | :1079A000AE010A0167BFE89511248E37910521F0D9 156 | :1079B00012964C910296E8CF85E0F90187BFE895D1 157 | :1079C00007B600FCFDCF81E187BFE8953EC0843754 158 | :1079D000D1F428DF27DF8093180124DF4CDF8111E9 159 | :1079E00030C0E0911601F09117018591F0931701D5 160 | :1079F000E093160110DF80911801815080931801E7 161 | :107A00008111EFCF22C0853751F435DF811119C0C4 162 | :107A10008EE101DF85E9FFDE8FE0FDDE16C08135F6 163 | :107A200091F429E088E190E00FB6F894A89580934E 164 | :107A300060000FBE209360001EDF811102C080E154 165 | :107A4000EADE82E007C017DF4ECF80E1E4DE81E0AE 166 | :107A500001C080E0DF91CF911F910F91089582E0E6 167 | :107A60008093C00088E18093C10086E08093C200CB 168 | :107A700080E18093C400509A08950F931F93CF9391 169 | :107A8000DF9384B7877F84BF88E10FB6F894809333 170 | :107A90006000109260000FBEE0E0F0E085919491EC 171 | :107AA000019621F481E08093050102C01092050146 172 | :107AB00081E085BF82E085BF85E080938100259AC3 173 | :107AC00080916900826080936900E89A579A2D9AA4 174 | :107AD0008091840090918500803A9F40C8F32D9852 175 | :107AE0005798789481E080938100B9DF00E0C0E08E 176 | :107AF000D0E010E040DCD5DE813019F410920601B0 177 | :107B000007C0823029F480910501882309F454C00C 178 | :107B100080910401882349F0809106018B3028F080 179 | :107B200080910501882309F447C0809104018111E7 180 | :107B300008C080910601843020F0809105018823DF 181 | :107B4000D9F180910701811137C080918400909113 182 | :107B50008500B09B1AC0B09A20910401222361F0E5 183 | :107B60002D9A209721F421E0011120E0022F01112C 184 | :107B700002C0D25001C0DE5F1F5F153F30F0209180 185 | :107B800006012F5F2093060110E0209104012223BB 186 | :107B900029F0C817D90708F0ADCF0CC0812F81504C 187 | :107BA0008F3030F080528F3018F080528F3010F4C8 188 | :107BB0002D9AA0CF2D989ECF2D98259885E0809363 189 | :107BC0008100109285001092840001C0D4DB809166 190 | :107BD0000701882339F08091840090918500803AD4 191 | :107BE0009F40A0F3109281001092850010928400B3 192 | :107BF0001DBA1092690081E085BF15BEF894E0912E 193 | :107C00000201F0910301099580E090E0DF91CF91AE 194 | :107C10001F910F910895F999FECF92BD81BDF89AF9 195 | :107C2000992780B50895262FF999FECF1FBA92BDE6 196 | :107C300081BD20BD0FB6F894FA9AF99A0FBE01964D 197 | :067C40000895F894FFCF47 198 | :027C46005AFFE3 199 | :040000030000700089 200 | :00000001FF 201 | -------------------------------------------------------------------------------- /stk500.h: -------------------------------------------------------------------------------- 1 | #ifndef STK500_H_ 2 | #define STK500_H_ 3 | 4 | /* STK500 constants list, from AVRDUDE */ 5 | #define STK_OK 0x10 6 | #define STK_FAILED 0x11 // Not used 7 | #define STK_UNKNOWN 0x12 // Not used 8 | #define STK_NODEVICE 0x13 // Not used 9 | #define STK_INSYNC 0x14 // ' ' 10 | #define STK_NOSYNC 0x15 // Not used 11 | #define ADC_CHANNEL_ERROR 0x16 // Not used 12 | #define ADC_MEASURE_OK 0x17 // Not used 13 | #define PWM_CHANNEL_ERROR 0x18 // Not used 14 | #define PWM_ADJUST_OK 0x19 // Not used 15 | #define CRC_EOP 0x20 // 'SPACE' 16 | #define STK_GET_SYNC 0x30 // '0' 17 | #define STK_GET_SIGN_ON 0x31 // '1' 18 | #define STK_SET_PARAMETER 0x40 // '@' 19 | #define STK_GET_PARAMETER 0x41 // 'A' 20 | #define STK_SET_DEVICE 0x42 // 'B' 21 | #define STK_SET_DEVICE_EXT 0x45 // 'E' 22 | #define STK_ENTER_PROGMODE 0x50 // 'P' 23 | #define STK_LEAVE_PROGMODE 0x51 // 'Q' 24 | #define STK_CHIP_ERASE 0x52 // 'R' 25 | #define STK_CHECK_AUTOINC 0x53 // 'S' 26 | #define STK_LOAD_ADDRESS 0x55 // 'U' 27 | #define STK_UNIVERSAL 0x56 // 'V' 28 | #define STK_PROG_FLASH 0x60 // '`' 29 | #define STK_PROG_DATA 0x61 // 'a' 30 | #define STK_PROG_FUSE 0x62 // 'b' 31 | #define STK_PROG_LOCK 0x63 // 'c' 32 | #define STK_PROG_PAGE 0x64 // 'd' 33 | #define STK_PROG_FUSE_EXT 0x65 // 'e' 34 | #define STK_READ_FLASH 0x70 // 'p' 35 | #define STK_READ_DATA 0x71 // 'q' 36 | #define STK_READ_FUSE 0x72 // 'r' 37 | #define STK_READ_LOCK 0x73 // 's' 38 | #define STK_READ_PAGE 0x74 // 't' 39 | #define STK_READ_SIGN 0x75 // 'u' 40 | #define STK_READ_OSCCAL 0x76 // 'v' 41 | #define STK_READ_FUSE_EXT 0x77 // 'w' 42 | #define STK_READ_OSCCAL_EXT 0x78 // 'x' 43 | 44 | #endif -------------------------------------------------------------------------------- /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$ 9 | */ 10 | 11 | /* Modified by me@frank-zhao.com for project VUSBtinyBoot 12 | * 13 | * VUSBtinyBoot is a bootloader that emulates a USBtinyISP (from Adafruit Industries) 14 | * 15 | * Trinket Pro will use VUSBtinyBoot 16 | * 17 | * This code is heavily derived from USBaspLoader, but also from USBtiny, with USBtinyISP's settings 18 | */ 19 | 20 | #ifndef __usbconfig_h_included__ 21 | #define __usbconfig_h_included__ 22 | 23 | /* YOU SHOULD NOT NEED TO MODIFY THIS FILE! All configurations are supposed 24 | * to go into bootloaderconfig.h! 25 | */ 26 | 27 | /* ---------------------------- Hardware Config ---------------------------- */ 28 | 29 | /* All the port and pin assignments, as well as the clock speed and CRC 30 | setting are now in bootloaderconfig.h: */ 31 | 32 | #include "bootloaderconfig.h" 33 | 34 | /* --------------------------- Functional Range ---------------------------- */ 35 | 36 | #define USB_CFG_HAVE_INTRIN_ENDPOINT 0 37 | /* Define this to 1 if you want to compile a version with two endpoints: The 38 | * default control endpoint 0 and an interrupt-in endpoint (any other endpoint 39 | * number). 40 | */ 41 | #define USB_CFG_HAVE_INTRIN_ENDPOINT3 0 42 | /* Define this to 1 if you want to compile a version with three endpoints: The 43 | * default control endpoint 0, an interrupt-in endpoint 3 (or the number 44 | * configured below) and a catch-all default interrupt-in endpoint as above. 45 | * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature. 46 | */ 47 | #define USB_CFG_EP3_NUMBER 3 48 | /* If the so-called endpoint 3 is used, it can now be configured to any other 49 | * endpoint number (except 0) with this macro. Default if undefined is 3. 50 | */ 51 | /* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */ 52 | /* The above macro defines the startup condition for data toggling on the 53 | * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1. 54 | * Since the token is toggled BEFORE sending any data, the first packet is 55 | * sent with the oposite value of this configuration! 56 | */ 57 | #define USB_CFG_IMPLEMENT_HALT 0 58 | /* Define this to 1 if you also want to implement the ENDPOINT_HALT feature 59 | * for endpoint 1 (interrupt endpoint). Although you may not need this feature, 60 | * it is required by the standard. We have made it a config option because it 61 | * bloats the code considerably. 62 | */ 63 | #define USB_CFG_SUPPRESS_INTR_CODE 0 64 | /* Define this to 1 if you want to declare interrupt-in endpoints, but don't 65 | * want to send any data over them. If this macro is defined to 1, functions 66 | * usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if 67 | * you need the interrupt-in endpoints in order to comply to an interface 68 | * (e.g. HID), but never want to send any data. This option saves a couple 69 | * of bytes in flash memory and the transmit buffers in RAM. 70 | */ 71 | #define USB_CFG_INTR_POLL_INTERVAL 10 72 | /* If you compile a version with endpoint 1 (interrupt-in), this is the poll 73 | * interval. The value is in milliseconds and must not be less than 10 ms for 74 | * low speed devices. 75 | */ 76 | #ifndef USB_CFG_IS_SELF_POWERED // allow bootloaderconfig.h to override 77 | #define USB_CFG_IS_SELF_POWERED 0 78 | #endif 79 | /* Define this to 1 if the device has its own power supply. Set it to 0 if the 80 | * device is powered from the USB bus. 81 | */ 82 | #ifndef USB_CFG_MAX_BUS_POWER // allow bootloaderconfig.h to override 83 | #define USB_CFG_MAX_BUS_POWER 100 84 | #endif 85 | /* Set this variable to the maximum USB bus power consumption of your device. 86 | * The value is in milliamperes. [It will be divided by two since USB 87 | * communicates power requirements in units of 2 mA.] 88 | */ 89 | #define USB_CFG_IMPLEMENT_FN_WRITE 1 90 | /* Set this to 1 if you want usbFunctionWrite() to be called for control-out 91 | * transfers. Set it to 0 if you don't need it and want to save a couple of 92 | * bytes. 93 | */ 94 | #define USB_CFG_IMPLEMENT_FN_READ 1 95 | /* Set this to 1 if you need to send control replies which are generated 96 | * "on the fly" when usbFunctionRead() is called. If you only want to send 97 | * data from a static buffer, set it to 0 and return the data from 98 | * usbFunctionSetup(). This saves a couple of bytes. 99 | */ 100 | #define USB_CFG_IMPLEMENT_FN_WRITEOUT 0 101 | /* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints. 102 | * You must implement the function usbFunctionWriteOut() which receives all 103 | * interrupt/bulk data sent to any endpoint other than 0. The endpoint number 104 | * can be found in 'usbRxToken'. 105 | */ 106 | #define USB_CFG_HAVE_FLOWCONTROL 0 107 | /* Define this to 1 if you want flowcontrol over USB data. See the definition 108 | * of the macros usbDisableAllRequests() and usbEnableAllRequests() in 109 | * usbdrv.h. 110 | */ 111 | #define USB_CFG_DRIVER_FLASH_PAGE 0 112 | /* If the device has more than 64 kBytes of flash, define this to the 64 k page 113 | * where the driver's constants (descriptors) are located. Or in other words: 114 | * Define this to 1 for boot loaders on the ATMega128. 115 | */ 116 | #define USB_CFG_LONG_TRANSFERS 0 117 | /* Define this to 1 if you want to send/receive blocks of more than 254 bytes 118 | * in a single control-in or control-out transfer. Note that the capability 119 | * for long transfers increases the driver size. 120 | */ 121 | #ifndef __ASSEMBLER__ 122 | extern volatile char usbHasRxed; 123 | #endif 124 | #define USB_RX_USER_HOOK(data, len) do { usbHasRxed = 1; } while (0); 125 | /* This macro is a hook if you want to do unconventional things. If it is 126 | * defined, it's inserted at the beginning of received message processing. 127 | * If you eat the received message and don't want default processing to 128 | * proceed, do a return after doing your things. One possible application 129 | * (besides debugging) is to flash a status LED on each packet. 130 | */ 131 | /* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */ 132 | /* This macro is a hook if you need to know when an USB RESET occurs. It has 133 | * one parameter which distinguishes between the start of RESET state and its 134 | * end. 135 | */ 136 | /* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */ 137 | /* This macro (if defined) is executed when a USB SET_ADDRESS request was 138 | * received. 139 | */ 140 | #define USB_COUNT_SOF 0 141 | /* define this macro to 1 if you need the global variable "usbSofCount" which 142 | * counts SOF packets. This feature requires that the hardware interrupt is 143 | * connected to D- instead of D+. 144 | */ 145 | /* #ifdef __ASSEMBLER__ 146 | * macro myAssemblerMacro 147 | * in YL, TCNT0 148 | * sts timer0Snapshot, YL 149 | * endm 150 | * #endif 151 | * #define USB_SOF_HOOK myAssemblerMacro 152 | * This macro (if defined) is executed in the assembler module when a 153 | * Start Of Frame condition is detected. It is recommended to define it to 154 | * the name of an assembler macro which is defined here as well so that more 155 | * than one assembler instruction can be used. The macro may use the register 156 | * YL and modify SREG. If it lasts longer than a couple of cycles, USB messages 157 | * immediately after an SOF pulse may be lost and must be retried by the host. 158 | * What can you do with this hook? Since the SOF signal occurs exactly every 159 | * 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in 160 | * designs running on the internal RC oscillator. 161 | * Please note that Start Of Frame detection works only if D- is wired to the 162 | * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES! 163 | */ 164 | #define USB_CFG_CHECK_DATA_TOGGLING 0 165 | /* define this macro to 1 if you want to filter out duplicate data packets 166 | * sent by the host. Duplicates occur only as a consequence of communication 167 | * errors, when the host does not receive an ACK. Please note that you need to 168 | * implement the filtering yourself in usbFunctionWriteOut() and 169 | * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable 170 | * for each control- and out-endpoint to check for duplicate packets. 171 | */ 172 | #define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0 173 | /* define this macro to 1 if you want the function usbMeasureFrameLength() 174 | * compiled in. This function can be used to calibrate the AVR's RC oscillator. 175 | */ 176 | #define USB_USE_FAST_CRC 0 177 | /* The assembler module has two implementations for the CRC algorithm. One is 178 | * faster, the other is smaller. This CRC routine is only used for transmitted 179 | * messages where timing is not critical. The faster routine needs 31 cycles 180 | * per byte while the smaller one needs 61 to 69 cycles. The faster routine 181 | * may be worth the 32 bytes bigger code size if you transmit lots of data and 182 | * run the AVR close to its limit. 183 | */ 184 | 185 | /* -------------------------- Device Description --------------------------- */ 186 | 187 | #define USB_CFG_VENDOR_ID 0x81, 0x17 /* = 0x16c0 = 5824 = voti.nl */ 188 | /* USB vendor ID for the device, low byte first. If you have registered your 189 | * own Vendor ID, define it here. Otherwise you may use one of obdev's free 190 | * shared VID/PID pairs. Be sure to read USB-IDs-for-free.txt for rules! 191 | */ 192 | #define USB_CFG_DEVICE_ID 0x9F, 0x0C /* = 0x05dc = 1500 */ 193 | /* This is the ID of the product, low byte first. It is interpreted in the 194 | * scope of the vendor ID. If you have registered your own VID with usb.org 195 | * or if you have licensed a PID from somebody else, define it here. Otherwise 196 | * you may use one of obdev's free shared VID/PID pairs. See the file 197 | * USB-IDs-for-free.txt for details! 198 | */ 199 | #define USB_CFG_DEVICE_VERSION 0x05, 0x01 200 | /* Version number of the device: Minor number first, then major number. 201 | */ 202 | #define USB_CFG_VENDOR_NAME 'A','d','a','f','r','u','i','t' 203 | #define USB_CFG_VENDOR_NAME_LEN 8 204 | /* These two values define the vendor name returned by the USB device. The name 205 | * must be given as a list of characters under single quotes. The characters 206 | * are interpreted as Unicode (UTF-16) entities. 207 | * If you don't want a vendor name string, undefine these macros. 208 | * ALWAYS define a vendor name containing your Internet domain name if you use 209 | * obdev's free shared VID/PID pair. See the file USB-IDs-for-free.txt for 210 | * details. 211 | */ 212 | #define USB_CFG_DEVICE_NAME 'U','S','B','t','i','n','y' 213 | #define USB_CFG_DEVICE_NAME_LEN 7 214 | /* Same as above for the device name. If you don't want a device name, undefine 215 | * the macros. See the file USB-IDs-for-free.txt before you assign a name if 216 | * you use a shared VID/PID. 217 | */ 218 | /*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */ 219 | /*#define USB_CFG_SERIAL_NUMBER_LEN 0 */ 220 | /* Same as above for the serial number. If you don't want a serial number, 221 | * undefine the macros. 222 | * It may be useful to provide the serial number through other means than at 223 | * compile time. See the section about descriptor properties below for how 224 | * to fine tune control over USB descriptors such as the string descriptor 225 | * for the serial number. 226 | */ 227 | #define USB_CFG_DEVICE_CLASS 0xFF /* set to 0 if deferred to interface */ 228 | #define USB_CFG_DEVICE_SUBCLASS 0 229 | /* See USB specification if you want to conform to an existing device class. 230 | * Class 0xff is "vendor specific". 231 | */ 232 | #define USB_CFG_INTERFACE_CLASS 0 /* define class here if not at device level */ 233 | #define USB_CFG_INTERFACE_SUBCLASS 0 234 | #define USB_CFG_INTERFACE_PROTOCOL 0 235 | /* See USB specification if you want to conform to an existing device class or 236 | * protocol. The following classes must be set at interface level: 237 | * HID class is 3, no subclass and protocol required (but may be useful!) 238 | * CDC class is 2, use subclass 2 and protocol 1 for ACM 239 | */ 240 | /* #define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 42 */ 241 | /* Define this to the length of the HID report descriptor, if you implement 242 | * an HID device. Otherwise don't define it or define it to 0. 243 | * If you use this define, you must add a PROGMEM character array named 244 | * "usbHidReportDescriptor" to your code which contains the report descriptor. 245 | * Don't forget to keep the array and this define in sync! 246 | */ 247 | 248 | #define USB_PUBLIC static 249 | /* Use the define above if you #include usbdrv.c instead of linking against it. 250 | * This technique saves a couple of bytes in flash memory. 251 | */ 252 | 253 | /* ------------------- Fine Control over USB Descriptors ------------------- */ 254 | /* If you don't want to use the driver's default USB descriptors, you can 255 | * provide our own. These can be provided as (1) fixed length static data in 256 | * flash memory, (2) fixed length static data in RAM or (3) dynamically at 257 | * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more 258 | * information about this function. 259 | * Descriptor handling is configured through the descriptor's properties. If 260 | * no properties are defined or if they are 0, the default descriptor is used. 261 | * Possible properties are: 262 | * + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched 263 | * at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is 264 | * used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if 265 | * you want RAM pointers. 266 | * + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found 267 | * in static memory is in RAM, not in flash memory. 268 | * + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash), 269 | * the driver must know the descriptor's length. The descriptor itself is 270 | * found at the address of a well known identifier (see below). 271 | * List of static descriptor names (must be declared PROGMEM if in flash): 272 | * char usbDescriptorDevice[]; 273 | * char usbDescriptorConfiguration[]; 274 | * char usbDescriptorHidReport[]; 275 | * char usbDescriptorString0[]; 276 | * int usbDescriptorStringVendor[]; 277 | * int usbDescriptorStringDevice[]; 278 | * int usbDescriptorStringSerialNumber[]; 279 | * Other descriptors can't be provided statically, they must be provided 280 | * dynamically at runtime. 281 | * 282 | * Descriptor properties are or-ed or added together, e.g.: 283 | * #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18)) 284 | * 285 | * The following descriptors are defined: 286 | * USB_CFG_DESCR_PROPS_DEVICE 287 | * USB_CFG_DESCR_PROPS_CONFIGURATION 288 | * USB_CFG_DESCR_PROPS_STRINGS 289 | * USB_CFG_DESCR_PROPS_STRING_0 290 | * USB_CFG_DESCR_PROPS_STRING_VENDOR 291 | * USB_CFG_DESCR_PROPS_STRING_PRODUCT 292 | * USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 293 | * USB_CFG_DESCR_PROPS_HID 294 | * USB_CFG_DESCR_PROPS_HID_REPORT 295 | * USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver) 296 | * 297 | * Note about string descriptors: String descriptors are not just strings, they 298 | * are Unicode strings prefixed with a 2 byte header. Example: 299 | * int serialNumberDescriptor[] = { 300 | * USB_STRING_DESCRIPTOR_HEADER(6), 301 | * 'S', 'e', 'r', 'i', 'a', 'l' 302 | * }; 303 | */ 304 | 305 | #define USB_CFG_DESCR_PROPS_DEVICE 0 306 | #define USB_CFG_DESCR_PROPS_CONFIGURATION 0 307 | #define USB_CFG_DESCR_PROPS_STRINGS 0 308 | #define USB_CFG_DESCR_PROPS_STRING_0 0 309 | #define USB_CFG_DESCR_PROPS_STRING_VENDOR 0 310 | #define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0 311 | #define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0 312 | #define USB_CFG_DESCR_PROPS_HID 0 313 | #define USB_CFG_DESCR_PROPS_HID_REPORT 0 314 | #define USB_CFG_DESCR_PROPS_UNKNOWN 0 315 | 316 | #define usbMsgPtr_t unsigned short // scalar type yields shortest code 317 | 318 | /* ----------------------- Optional MCU Description ------------------------ */ 319 | 320 | /* The following configurations have working defaults in usbdrv.h. You 321 | * usually don't need to set them explicitly. Only if you want to run 322 | * the driver on a device which is not yet supported or with a compiler 323 | * which is not fully supported (such as IAR C) or if you use a differnt 324 | * interrupt than INT0, you may have to define some of these. 325 | */ 326 | /* #define USB_INTR_CFG MCUCR */ 327 | /* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */ 328 | /* #define USB_INTR_CFG_CLR 0 */ 329 | /* #define USB_INTR_ENABLE GIMSK */ 330 | /* #define USB_INTR_ENABLE_BIT INT0 */ 331 | /* #define USB_INTR_PENDING GIFR */ 332 | /* #define USB_INTR_PENDING_BIT INTF0 */ 333 | /* #define USB_INTR_VECTOR INT0_vect */ 334 | 335 | #endif /* __usbconfig_h_included__ */ 336 | -------------------------------------------------------------------------------- /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 | 298 | - Moved first DBG1() after odDebugInit() in all examples. 299 | - Use vector INT0_vect instead of SIG_INTERRUPT0 if defined. This makes 300 | V-USB compatible with the new "p" suffix devices (e.g. ATMega328p). 301 | - USB_CFG_CLOCK_KHZ setting is now required in usbconfig.h (no default any 302 | more). 303 | - New option USB_CFG_DRIVER_FLASH_PAGE allows boot loaders on devices with 304 | more than 64 kB flash. 305 | - Built-in configuration descriptor allows custom definition for second 306 | endpoint now. 307 | 308 | * Release 2010-07-15 309 | 310 | - Fixed bug in usbDriverSetup() which prevented descriptor sizes above 255 311 | bytes. 312 | - Avoid a compiler warning for unused parameter in usbHandleResetHook() when 313 | compiler option -Wextra is enabled. 314 | - Fixed wrong hex value for some IDs in USB-IDs-for-free.txt. 315 | - Keep a define for USBATTR_BUSPOWER, although the flag does not exist 316 | in USB 1.1 any more. Set it to 0. This is for backward compatibility. 317 | 318 | * Release 2012-01-09 319 | 320 | - Define a separate (defined) type for usbMsgPtr so that projects using a 321 | tiny memory model can define it to an 8 bit type in usbconfig.h. This 322 | change also saves a couple of bytes when using a scalar 16 bit type. 323 | - Inserted "const" keyword for all PROGMEM declarations because new GCC 324 | requires it. 325 | - Fixed problem with dependence of usbportability.h on usbconfig.h. This 326 | problem occurred with IAR CC only. 327 | - Prepared repository for github.com. 328 | 329 | * Release 2012-12-06 -------------------------------------------------------------------------------- /usbdrv/CommercialLicense.txt: -------------------------------------------------------------------------------- 1 | V-USB Driver Software License Agreement 2 | Version 2012-07-09 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 (now flirc.tv, Inc.). Both owners of the Vendor IDs have 41 | obtained these IDs from the USB Implementers Forum, Inc. (www.usb.org). 42 | OBJECTIVE DEVELOPMENT disclaims all liability which might arise from the 43 | 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 usbconfig.h. 53 | 54 | 12 MHz Clock 55 | This is the traditional clock rate of V-USB because it's the lowest clock 56 | rate where the timing constraints of the USB spec can be met. 57 | 58 | 15 MHz Clock 59 | Similar to 12 MHz, but some NOPs inserted. On the other hand, the higher clock 60 | rate allows for some loops which make the resulting code size somewhat smaller 61 | than the 12 MHz version. 62 | 63 | 16 MHz Clock 64 | This clock rate has been added for users of the Arduino board and other 65 | ready-made boards which come with a fixed 16 MHz crystal. It's also an option 66 | if you need the slightly higher clock rate for performance reasons. Since 67 | 16 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code 68 | is somewhat tricky and has to insert a leap cycle every third byte. 69 | 70 | 12.8 MHz and 16.5 MHz Clock 71 | The assembler modules for these clock rates differ from the other modules 72 | because they have been built for an RC oscillator with only 1% precision. The 73 | receiver code inserts leap cycles to compensate for clock deviations. 1% is 74 | also the precision which can be achieved by calibrating the internal RC 75 | oscillator of the AVR. Please note that only AVRs with internal 64 MHz PLL 76 | oscillator can reach 16.5 MHz with the RC oscillator. This includes the very 77 | popular ATTiny25, ATTiny45, ATTiny85 series as well as the ATTiny26. Almost 78 | all AVRs can reach 12.8 MHz, although this is outside the specified range. 79 | 80 | See the EasyLogger example at http://www.obdev.at/vusb/easylogger.html for 81 | code which calibrates the RC oscillator based on the USB frame clock. 82 | 83 | 18 MHz Clock 84 | This module is closer to the USB specification because it performs an on the 85 | fly CRC check for incoming packets. Packets with invalid checksum are 86 | discarded as required by the spec. If you also implement checks for data 87 | PID toggling on application level (see option USB_CFG_CHECK_DATA_TOGGLING 88 | in usbconfig.h for more info), this ensures data integrity. Due to the CRC 89 | tables and alignment requirements, this code is bigger than modules for other 90 | clock rates. To activate this module, you must define USB_CFG_CHECK_CRC to 1 91 | and USB_CFG_CLOCK_KHZ to 18000 in usbconfig.h. 92 | 93 | 20 MHz Clock 94 | This module is for people who won't do it with less than the maximum. Since 95 | 20 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code 96 | uses similar tricks as the 16 MHz module to insert leap cycles. 97 | 98 | 99 | USB IDENTIFIERS 100 | =============== 101 | Every USB device needs a vendor- and a product-identifier (VID and PID). VIDs 102 | are obtained from usb.org for a price of 1,500 USD. Once you have a VID, you 103 | can assign PIDs at will. 104 | 105 | Since an entry level cost of 1,500 USD is too high for most small companies 106 | and hobbyists, we provide some VID/PID pairs for free. See the file 107 | USB-IDs-for-free.txt for details. 108 | 109 | Objective Development also has some license offerings which include product 110 | IDs. See http://www.obdev.at/vusb/ for details. 111 | 112 | 113 | DEVELOPMENT SYSTEM 114 | ================== 115 | This driver has been developed and optimized for the GNU compiler version 3 116 | and 4. We recommend that you use the GNU compiler suite because it is freely 117 | available. V-USB has also been ported to the IAR compiler and assembler. It 118 | has been tested with IAR 4.10B/W32 and 4.12A/W32 on an ATmega8 with the 119 | "small" and "tiny" memory model. Not every release is tested with IAR CC and 120 | the driver may therefore fail to compile with IAR. Please note that gcc is 121 | more efficient for usbdrv.c because this module has been deliberately 122 | optimized for gcc. 123 | 124 | Gcc version 3 produces smaller code than version 4 due to new optimizing 125 | capabilities which don't always improve things on 8 bit CPUs. The code size 126 | generated by gcc 4 can be reduced with the compiler options 127 | -fno-move-loop-invariants, -fno-tree-scev-cprop and 128 | -fno-inline-small-functions in addition to -Os. On devices with more than 129 | 8k of flash memory, we also recommend the linker option --relax (written as 130 | -Wl,--relax for gcc) to convert absolute calls into relative where possible. 131 | 132 | For more information about optimizing options see: 133 | 134 | http://www.tty1.net/blog/2008-04-29-avr-gcc-optimisations_en.html 135 | 136 | These optimizations are good for gcc 4.x. Version 3.x of gcc does not support 137 | most of these options and produces good code anyway. 138 | 139 | 140 | USING V-USB FOR FREE 141 | ==================== 142 | The AVR firmware driver is published under the GNU General Public License 143 | Version 2 (GPL2) and the GNU General Public License Version 3 (GPL3). It is 144 | your choice whether you apply the terms of version 2 or version 3. 145 | 146 | If you decide for the free GPL2 or GPL3, we STRONGLY ENCOURAGE you to do the 147 | following things IN ADDITION to the obligations from the GPL: 148 | 149 | (1) Publish your entire project on a web site and drop us a note with the URL. 150 | Use the form at http://www.obdev.at/vusb/feedback.html for your submission. 151 | If you don't have a web site, you can publish the project in obdev's 152 | documentation wiki at 153 | http://www.obdev.at/goto.php?t=vusb-wiki&p=hosted-projects. 154 | 155 | (2) Adhere to minimum publication standards. Please include AT LEAST: 156 | - a circuit diagram in PDF, PNG or GIF format 157 | - full source code for the host software 158 | - a Readme.txt file in ASCII format which describes the purpose of the 159 | project and what can be found in which directories and which files 160 | - a reference to http://www.obdev.at/vusb/ 161 | 162 | (3) If you improve the driver firmware itself, please give us a free license 163 | to your modifications for our commercial license offerings. 164 | 165 | 166 | COMMERCIAL LICENSES FOR V-USB 167 | ============================= 168 | If you don't want to publish your source code under the terms of the GPL, 169 | you can simply pay money for V-USB. As an additional benefit you get 170 | USB PIDs for free, reserved exclusively to you. See the file 171 | "CommercialLicense.txt" for details. 172 | 173 | -------------------------------------------------------------------------------- /usbdrv/USB-ID-FAQ.txt: -------------------------------------------------------------------------------- 1 | Version 2012-07-09 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 (now flirc.tv, Inc.). Both VID owners have received their Vendor-ID 111 | 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, unless ONLY the operating system's default class driver is used. 90 | The serial number string MUST be available at least in USB language 0x0409 91 | (English/US). 92 | 93 | (2) The serial number MUST start with either an Internet domain name (e.g. 94 | "mycompany.com") registered and owned by you, or an e-mail address under your 95 | control (e.g. "myname@gmx.net"), both terminated with a colon (":") character. 96 | You MAY append any string you like for further discrimination of your devices. 97 | 98 | (3) You are responsible for retaining ownership of the domain or e-mail 99 | address for as long as any of your products are in use. 100 | 101 | (5) Application side device look-up MUST be based on the serial number string 102 | in addition to VID/PID matching. The matching must start at the first 103 | character of the serial number string and include the colon character 104 | terminating your domain or e-mail address. It MAY stop anywhere after that. 105 | 106 | (6) For devices which implement a particular USB device class (e.g. HID), the 107 | operating system's default class driver MUST be used. If an operating system 108 | driver for Vendor Class devices is needed, this driver must be libusb or 109 | libusb-win32 (see http://libusb.org/ and 110 | http://libusb-win32.sourceforge.net/). 111 | 112 | (7) If ONLY the operating system's default class driver is used, e.g. for 113 | mice, keyboards, joysticks, CDC or MIDI devices and no discrimination by an 114 | application is needed, the serial number may be omitted. 115 | 116 | 117 | Table if IDs for discrimination by serial number string: 118 | 119 | PID dec (hex) | VID dec (hex) | Description of use 120 | ===============+===============+=========================================== 121 | 10200 (0x27d8) | 5824 (0x16c0) | For Vendor Class devices with libusb 122 | ---------------+---------------+------------------------------------------- 123 | 10201 (0x27d9) | 5824 (0x16c0) | For generic HID class devices (which are 124 | | | NOT mice, keyboards or joysticks) 125 | ---------------+---------------+------------------------------------------- 126 | 10202 (0x27da) | 5824 (0x16c0) | For USB Mice 127 | ---------------+---------------+------------------------------------------- 128 | 10203 (0x27db) | 5824 (0x16c0) | For USB Keyboards 129 | ---------------+---------------+------------------------------------------- 130 | 10204 (0x27dc) | 5824 (0x16c0) | For USB Joysticks 131 | ---------------+---------------+------------------------------------------- 132 | 10205 (0x27dd) | 5824 (0x16c0) | For CDC-ACM class devices (modems) 133 | ---------------+---------------+------------------------------------------- 134 | 10206 (0x27de) | 5824 (0x16c0) | For MIDI class devices 135 | ---------------+---------------+------------------------------------------- 136 | 137 | 138 | ================= 139 | ORIGIN OF USB-IDs 140 | ================= 141 | 142 | OBJECTIVE DEVELOPMENT Software GmbH has obtained all VID/PID pairs listed 143 | here from Wouter van Ooijen (see www.voti.nl) for exclusive disposition. 144 | Wouter van Ooijen has obtained the VID from the USB Implementers Forum, Inc. 145 | (see www.usb.org). The VID is registered for the company name "Van Ooijen 146 | Technische Informatica". 147 | 148 | 149 | ========== 150 | DISCLAIMER 151 | ========== 152 | 153 | OBJECTIVE DEVELOPMENT Software GmbH disclaims all liability for any 154 | problems which are caused by the shared use of these VID/PID pairs. 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 | */ 9 | 10 | /* Do not link this file! Link usbdrvasm.S instead, which includes the 11 | * appropriate implementation! 12 | */ 13 | 14 | /* 15 | General Description: 16 | This file contains assembler code which is shared among the USB driver 17 | implementations for different CPU cocks. Since the code must be inserted 18 | in the middle of the module, it's split out into this file and #included. 19 | 20 | Jump destinations called from outside: 21 | sofError: Called when no start sequence was found. 22 | se0: Called when a package has been successfully received. 23 | overflow: Called when receive buffer overflows. 24 | doReturn: Called after sending data. 25 | 26 | Outside jump destinations used by this module: 27 | waitForJ: Called to receive an already arriving packet. 28 | sendAckAndReti: 29 | sendNakAndReti: 30 | sendCntAndReti: 31 | usbSendAndReti: 32 | 33 | The following macros must be defined before this file is included: 34 | .macro POP_STANDARD 35 | .endm 36 | .macro POP_RETI 37 | .endm 38 | */ 39 | 40 | #define token x1 41 | 42 | overflow: 43 | ldi x2, 1< 0 13 | 14 | #warning "Never compile production devices with debugging enabled" 15 | 16 | static void uartPutc(char c) 17 | { 18 | while(!(ODDBG_USR & (1 << ODDBG_UDRE))); /* wait for data register empty */ 19 | ODDBG_UDR = c; 20 | } 21 | 22 | static uchar hexAscii(uchar h) 23 | { 24 | h &= 0xf; 25 | if(h >= 10) 26 | h += 'a' - (uchar)10 - '0'; 27 | h += '0'; 28 | return h; 29 | } 30 | 31 | static void printHex(uchar c) 32 | { 33 | uartPutc(hexAscii(c >> 4)); 34 | uartPutc(hexAscii(c)); 35 | } 36 | 37 | void odDebug(uchar prefix, uchar *data, uchar len) 38 | { 39 | printHex(prefix); 40 | uartPutc(':'); 41 | while(len--){ 42 | uartPutc(' '); 43 | printHex(*data++); 44 | } 45 | uartPutc('\r'); 46 | uartPutc('\n'); 47 | } 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /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 | */ 9 | 10 | #ifndef __oddebug_h_included__ 11 | #define __oddebug_h_included__ 12 | 13 | /* 14 | General Description: 15 | This module implements a function for debug logs on the serial line of the 16 | AVR microcontroller. Debugging can be configured with the define 17 | 'DEBUG_LEVEL'. If this macro is not defined or defined to 0, all debugging 18 | calls are no-ops. If it is 1, DBG1 logs will appear, but not DBG2. If it is 19 | 2, DBG1 and DBG2 logs will be printed. 20 | 21 | A debug log consists of a label ('prefix') to indicate which debug log created 22 | the output and a memory block to dump in hex ('data' and 'len'). 23 | */ 24 | 25 | 26 | #ifndef F_CPU 27 | # define F_CPU 12000000 /* 12 MHz */ 28 | #endif 29 | 30 | /* make sure we have the UART defines: */ 31 | #include "usbportability.h" 32 | 33 | #ifndef uchar 34 | # define uchar unsigned char 35 | #endif 36 | 37 | #if DEBUG_LEVEL > 0 && !(defined TXEN || defined TXEN0) /* no UART in device */ 38 | # warning "Debugging disabled because device has no UART" 39 | # undef DEBUG_LEVEL 40 | #endif 41 | 42 | #ifndef DEBUG_LEVEL 43 | # define DEBUG_LEVEL 0 44 | #endif 45 | 46 | /* ------------------------------------------------------------------------- */ 47 | 48 | #if DEBUG_LEVEL > 0 49 | # define DBG1(prefix, data, len) odDebug(prefix, data, len) 50 | #else 51 | # define DBG1(prefix, data, len) 52 | #endif 53 | 54 | #if DEBUG_LEVEL > 1 55 | # define DBG2(prefix, data, len) odDebug(prefix, data, len) 56 | #else 57 | # define DBG2(prefix, data, len) 58 | #endif 59 | 60 | /* ------------------------------------------------------------------------- */ 61 | 62 | #if DEBUG_LEVEL > 0 63 | extern void odDebug(uchar prefix, uchar *data, uchar len); 64 | 65 | /* Try to find our control registers; ATMEL likes to rename these */ 66 | 67 | #if defined UBRR 68 | # define ODDBG_UBRR UBRR 69 | #elif defined UBRRL 70 | # define ODDBG_UBRR UBRRL 71 | #elif defined UBRR0 72 | # define ODDBG_UBRR UBRR0 73 | #elif defined UBRR0L 74 | # define ODDBG_UBRR UBRR0L 75 | #endif 76 | 77 | #if defined UCR 78 | # define ODDBG_UCR UCR 79 | #elif defined UCSRB 80 | # define ODDBG_UCR UCSRB 81 | #elif defined UCSR0B 82 | # define ODDBG_UCR UCSR0B 83 | #endif 84 | 85 | #if defined TXEN 86 | # define ODDBG_TXEN TXEN 87 | #else 88 | # define ODDBG_TXEN TXEN0 89 | #endif 90 | 91 | #if defined USR 92 | # define ODDBG_USR USR 93 | #elif defined UCSRA 94 | # define ODDBG_USR UCSRA 95 | #elif defined UCSR0A 96 | # define ODDBG_USR UCSR0A 97 | #endif 98 | 99 | #if defined UDRE 100 | # define ODDBG_UDRE UDRE 101 | #else 102 | # define ODDBG_UDRE UDRE0 103 | #endif 104 | 105 | #if defined UDR 106 | # define ODDBG_UDR UDR 107 | #elif defined UDR0 108 | # define ODDBG_UDR UDR0 109 | #endif 110 | 111 | static inline void odDebugInit(void) 112 | { 113 | ODDBG_UCR |= (1< max 25 cycles interrupt disable 38 | ;max stack usage: [ret(2), YL, SREG, YH, shift, x1, x2, x3, cnt, x4] = 11 bytes 39 | ;Numbers in brackets are maximum cycles since SOF. 40 | USB_INTR_VECTOR: 41 | ;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt 42 | push YL ;2 [35] push only what is necessary to sync with edge ASAP 43 | in YL, SREG ;1 [37] 44 | push YL ;2 [39] 45 | ;---------------------------------------------------------------------------- 46 | ; Synchronize with sync pattern: 47 | ;---------------------------------------------------------------------------- 48 | ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 49 | ;sync up with J to K edge during sync pattern -- use fastest possible loops 50 | ;The first part waits at most 1 bit long since we must be in sync pattern. 51 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 52 | ;waitForJ, ensure that this prerequisite is met. 53 | waitForJ: 54 | inc YL 55 | sbis USBIN, USBMINUS 56 | brne waitForJ ; just make sure we have ANY timeout 57 | waitForK: 58 | ;The following code results in a sampling window of 1/4 bit which meets the spec. 59 | sbis USBIN, USBMINUS 60 | rjmp foundK 61 | sbis USBIN, USBMINUS 62 | rjmp foundK 63 | sbis USBIN, USBMINUS 64 | rjmp foundK 65 | sbis USBIN, USBMINUS 66 | rjmp foundK 67 | sbis USBIN, USBMINUS 68 | rjmp foundK 69 | #if USB_COUNT_SOF 70 | lds YL, usbSofCount 71 | inc YL 72 | sts usbSofCount, YL 73 | #endif /* USB_COUNT_SOF */ 74 | #ifdef USB_SOF_HOOK 75 | USB_SOF_HOOK 76 | #endif 77 | rjmp sofError 78 | foundK: 79 | ;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling] 80 | ;we have 1 bit time for setup purposes, then sample again. Numbers in brackets 81 | ;are cycles from center of first sync (double K) bit after the instruction 82 | push YH ;2 [2] 83 | lds YL, usbInputBufOffset;2 [4] 84 | clr YH ;1 [5] 85 | subi YL, lo8(-(usbRxBuf));1 [6] 86 | sbci YH, hi8(-(usbRxBuf));1 [7] 87 | 88 | sbis USBIN, USBMINUS ;1 [8] we want two bits K [sample 1 cycle too early] 89 | rjmp haveTwoBitsK ;2 [10] 90 | pop YH ;2 [11] undo the push from before 91 | rjmp waitForK ;2 [13] this was not the end of sync, retry 92 | haveTwoBitsK: 93 | ;---------------------------------------------------------------------------- 94 | ; push more registers and initialize values while we sample the first bits: 95 | ;---------------------------------------------------------------------------- 96 | push shift ;2 [16] 97 | push x1 ;2 [12] 98 | push x2 ;2 [14] 99 | 100 | in x1, USBIN ;1 [17] <-- sample bit 0 101 | ldi shift, 0xff ;1 [18] 102 | bst x1, USBMINUS ;1 [19] 103 | bld shift, 0 ;1 [20] 104 | push x3 ;2 [22] 105 | push cnt ;2 [24] 106 | 107 | in x2, USBIN ;1 [25] <-- sample bit 1 108 | ser x3 ;1 [26] [inserted init instruction] 109 | eor x1, x2 ;1 [27] 110 | bst x1, USBMINUS ;1 [28] 111 | bld shift, 1 ;1 [29] 112 | ldi cnt, USB_BUFSIZE;1 [30] [inserted init instruction] 113 | rjmp rxbit2 ;2 [32] 114 | 115 | ;---------------------------------------------------------------------------- 116 | ; Receiver loop (numbers in brackets are cycles within byte after instr) 117 | ;---------------------------------------------------------------------------- 118 | 119 | unstuff0: ;1 (branch taken) 120 | andi x3, ~0x01 ;1 [15] 121 | mov x1, x2 ;1 [16] x2 contains last sampled (stuffed) bit 122 | in x2, USBIN ;1 [17] <-- sample bit 1 again 123 | ori shift, 0x01 ;1 [18] 124 | rjmp didUnstuff0 ;2 [20] 125 | 126 | unstuff1: ;1 (branch taken) 127 | mov x2, x1 ;1 [21] x1 contains last sampled (stuffed) bit 128 | andi x3, ~0x02 ;1 [22] 129 | ori shift, 0x02 ;1 [23] 130 | nop ;1 [24] 131 | in x1, USBIN ;1 [25] <-- sample bit 2 again 132 | rjmp didUnstuff1 ;2 [27] 133 | 134 | unstuff2: ;1 (branch taken) 135 | andi x3, ~0x04 ;1 [29] 136 | ori shift, 0x04 ;1 [30] 137 | mov x1, x2 ;1 [31] x2 contains last sampled (stuffed) bit 138 | nop ;1 [32] 139 | in x2, USBIN ;1 [33] <-- sample bit 3 140 | rjmp didUnstuff2 ;2 [35] 141 | 142 | unstuff3: ;1 (branch taken) 143 | in x2, USBIN ;1 [34] <-- sample stuffed bit 3 [one cycle too late] 144 | andi x3, ~0x08 ;1 [35] 145 | ori shift, 0x08 ;1 [36] 146 | rjmp didUnstuff3 ;2 [38] 147 | 148 | unstuff4: ;1 (branch taken) 149 | andi x3, ~0x10 ;1 [40] 150 | in x1, USBIN ;1 [41] <-- sample stuffed bit 4 151 | ori shift, 0x10 ;1 [42] 152 | rjmp didUnstuff4 ;2 [44] 153 | 154 | unstuff5: ;1 (branch taken) 155 | andi x3, ~0x20 ;1 [48] 156 | in x2, USBIN ;1 [49] <-- sample stuffed bit 5 157 | ori shift, 0x20 ;1 [50] 158 | rjmp didUnstuff5 ;2 [52] 159 | 160 | unstuff6: ;1 (branch taken) 161 | andi x3, ~0x40 ;1 [56] 162 | in x1, USBIN ;1 [57] <-- sample stuffed bit 6 163 | ori shift, 0x40 ;1 [58] 164 | rjmp didUnstuff6 ;2 [60] 165 | 166 | ; extra jobs done during bit interval: 167 | ; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs] 168 | ; bit 1: se0 check 169 | ; bit 2: overflow check 170 | ; bit 3: recovery from delay [bit 0 tasks took too long] 171 | ; bit 4: none 172 | ; bit 5: none 173 | ; bit 6: none 174 | ; bit 7: jump, eor 175 | rxLoop: 176 | eor x3, shift ;1 [0] reconstruct: x3 is 0 at bit locations we changed, 1 at others 177 | in x1, USBIN ;1 [1] <-- sample bit 0 178 | st y+, x3 ;2 [3] store data 179 | ser x3 ;1 [4] 180 | nop ;1 [5] 181 | eor x2, x1 ;1 [6] 182 | bst x2, USBMINUS;1 [7] 183 | bld shift, 0 ;1 [8] 184 | in x2, USBIN ;1 [9] <-- sample bit 1 (or possibly bit 0 stuffed) 185 | andi x2, USBMASK ;1 [10] 186 | breq se0 ;1 [11] SE0 check for bit 1 187 | andi shift, 0xf9 ;1 [12] 188 | didUnstuff0: 189 | breq unstuff0 ;1 [13] 190 | eor x1, x2 ;1 [14] 191 | bst x1, USBMINUS;1 [15] 192 | bld shift, 1 ;1 [16] 193 | rxbit2: 194 | in x1, USBIN ;1 [17] <-- sample bit 2 (or possibly bit 1 stuffed) 195 | andi shift, 0xf3 ;1 [18] 196 | breq unstuff1 ;1 [19] do remaining work for bit 1 197 | didUnstuff1: 198 | subi cnt, 1 ;1 [20] 199 | brcs overflow ;1 [21] loop control 200 | eor x2, x1 ;1 [22] 201 | bst x2, USBMINUS;1 [23] 202 | bld shift, 2 ;1 [24] 203 | in x2, USBIN ;1 [25] <-- sample bit 3 (or possibly bit 2 stuffed) 204 | andi shift, 0xe7 ;1 [26] 205 | breq unstuff2 ;1 [27] 206 | didUnstuff2: 207 | eor x1, x2 ;1 [28] 208 | bst x1, USBMINUS;1 [29] 209 | bld shift, 3 ;1 [30] 210 | didUnstuff3: 211 | andi shift, 0xcf ;1 [31] 212 | breq unstuff3 ;1 [32] 213 | in x1, USBIN ;1 [33] <-- sample bit 4 214 | eor x2, x1 ;1 [34] 215 | bst x2, USBMINUS;1 [35] 216 | bld shift, 4 ;1 [36] 217 | didUnstuff4: 218 | andi shift, 0x9f ;1 [37] 219 | breq unstuff4 ;1 [38] 220 | nop2 ;2 [40] 221 | in x2, USBIN ;1 [41] <-- sample bit 5 222 | eor x1, x2 ;1 [42] 223 | bst x1, USBMINUS;1 [43] 224 | bld shift, 5 ;1 [44] 225 | didUnstuff5: 226 | andi shift, 0x3f ;1 [45] 227 | breq unstuff5 ;1 [46] 228 | nop2 ;2 [48] 229 | in x1, USBIN ;1 [49] <-- sample bit 6 230 | eor x2, x1 ;1 [50] 231 | bst x2, USBMINUS;1 [51] 232 | bld shift, 6 ;1 [52] 233 | didUnstuff6: 234 | cpi shift, 0x02 ;1 [53] 235 | brlo unstuff6 ;1 [54] 236 | nop2 ;2 [56] 237 | in x2, USBIN ;1 [57] <-- sample bit 7 238 | eor x1, x2 ;1 [58] 239 | bst x1, USBMINUS;1 [59] 240 | bld shift, 7 ;1 [60] 241 | didUnstuff7: 242 | cpi shift, 0x04 ;1 [61] 243 | brsh rxLoop ;2 [63] loop control 244 | unstuff7: 245 | andi x3, ~0x80 ;1 [63] 246 | ori shift, 0x80 ;1 [64] 247 | in x2, USBIN ;1 [65] <-- sample stuffed bit 7 248 | nop ;1 [66] 249 | rjmp didUnstuff7 ;2 [68] 250 | 251 | macro POP_STANDARD ; 12 cycles 252 | pop cnt 253 | pop x3 254 | pop x2 255 | pop x1 256 | pop shift 257 | pop YH 258 | endm 259 | macro POP_RETI ; 5 cycles 260 | pop YL 261 | out SREG, YL 262 | pop YL 263 | endm 264 | 265 | #include "asmcommon.inc" 266 | 267 | ;---------------------------------------------------------------------------- 268 | ; Transmitting data 269 | ;---------------------------------------------------------------------------- 270 | 271 | txByteLoop: 272 | txBitloop: 273 | stuffN1Delay: ; [03] 274 | ror shift ;[-5] [11] [59] 275 | brcc doExorN1 ;[-4] [60] 276 | subi x4, 1 ;[-3] 277 | brne commonN1 ;[-2] 278 | lsl shift ;[-1] compensate ror after rjmp stuffDelay 279 | nop ;[00] stuffing consists of just waiting 8 cycles 280 | rjmp stuffN1Delay ;[01] after ror, C bit is reliably clear 281 | 282 | sendNakAndReti: ;0 [-19] 19 cycles until SOP 283 | ldi x3, USBPID_NAK ;1 [-18] 284 | rjmp usbSendX3 ;2 [-16] 285 | sendAckAndReti: ;0 [-19] 19 cycles until SOP 286 | ldi x3, USBPID_ACK ;1 [-18] 287 | rjmp usbSendX3 ;2 [-16] 288 | sendCntAndReti: ;0 [-17] 17 cycles until SOP 289 | mov x3, cnt ;1 [-16] 290 | usbSendX3: ;0 [-16] 291 | ldi YL, 20 ;1 [-15] 'x3' is R20 292 | ldi YH, 0 ;1 [-14] 293 | ldi cnt, 2 ;1 [-13] 294 | ; rjmp usbSendAndReti fallthrough 295 | 296 | ; USB spec says: 297 | ; idle = J 298 | ; J = (D+ = 0), (D- = 1) or USBOUT = 0x01 299 | ; K = (D+ = 1), (D- = 0) or USBOUT = 0x02 300 | ; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles) 301 | 302 | ;usbSend: 303 | ;pointer to data in 'Y' 304 | ;number of bytes in 'cnt' -- including sync byte 305 | ;uses: x1...x2, x4, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x4 = bitstuff cnt] 306 | ;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction) 307 | usbSendAndReti: 308 | in x2, USBDDR ;[-12] 12 cycles until SOP 309 | ori x2, USBMASK ;[-11] 310 | sbi USBOUT, USBMINUS ;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) 311 | out USBDDR, x2 ;[-8] <--- acquire bus 312 | in x1, USBOUT ;[-7] port mirror for tx loop 313 | ldi shift, 0x40 ;[-6] sync byte is first byte sent (we enter loop after ror) 314 | ldi x2, USBMASK ;[-5] 315 | push x4 ;[-4] 316 | doExorN1: 317 | eor x1, x2 ;[-2] [06] [62] 318 | ldi x4, 6 ;[-1] [07] [63] 319 | commonN1: 320 | stuffN2Delay: 321 | out USBOUT, x1 ;[00] [08] [64] <--- set bit 322 | ror shift ;[01] 323 | brcc doExorN2 ;[02] 324 | subi x4, 1 ;[03] 325 | brne commonN2 ;[04] 326 | lsl shift ;[05] compensate ror after rjmp stuffDelay 327 | rjmp stuffN2Delay ;[06] after ror, C bit is reliably clear 328 | doExorN2: 329 | eor x1, x2 ;[04] [12] 330 | ldi x4, 6 ;[05] [13] 331 | commonN2: 332 | nop ;[06] [14] 333 | subi cnt, 171 ;[07] [15] trick: (3 * 171) & 0xff = 1 334 | out USBOUT, x1 ;[08] [16] <--- set bit 335 | brcs txBitloop ;[09] [25] [41] 336 | 337 | stuff6Delay: 338 | ror shift ;[42] [50] 339 | brcc doExor6 ;[43] 340 | subi x4, 1 ;[44] 341 | brne common6 ;[45] 342 | lsl shift ;[46] compensate ror after rjmp stuffDelay 343 | nop ;[47] stuffing consists of just waiting 8 cycles 344 | rjmp stuff6Delay ;[48] after ror, C bit is reliably clear 345 | doExor6: 346 | eor x1, x2 ;[45] [53] 347 | ldi x4, 6 ;[46] 348 | common6: 349 | stuff7Delay: 350 | ror shift ;[47] [55] 351 | out USBOUT, x1 ;[48] <--- set bit 352 | brcc doExor7 ;[49] 353 | subi x4, 1 ;[50] 354 | brne common7 ;[51] 355 | lsl shift ;[52] compensate ror after rjmp stuffDelay 356 | rjmp stuff7Delay ;[53] after ror, C bit is reliably clear 357 | doExor7: 358 | eor x1, x2 ;[51] [59] 359 | ldi x4, 6 ;[52] 360 | common7: 361 | ld shift, y+ ;[53] 362 | tst cnt ;[55] 363 | out USBOUT, x1 ;[56] <--- set bit 364 | brne txByteLoop ;[57] 365 | 366 | ;make SE0: 367 | cbr x1, USBMASK ;[58] prepare SE0 [spec says EOP may be 15 to 18 cycles] 368 | lds x2, usbNewDeviceAddr;[59] 369 | lsl x2 ;[61] we compare with left shifted address 370 | subi YL, 2 + 20 ;[62] Only assign address on data packets, not ACK/NAK in x3 371 | sbci YH, 0 ;[63] 372 | out USBOUT, x1 ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle 373 | ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: 374 | ;set address only after data packet was sent, not after handshake 375 | breq skipAddrAssign ;[01] 376 | sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer 377 | skipAddrAssign: 378 | ;end of usbDeviceAddress transfer 379 | ldi x2, 1< 10.6666666 cycles per bit, 85.333333333 cycles per byte 29 | ; Numbers in brackets are clocks counted from center of last sync bit 30 | ; when instruction starts 31 | 32 | USB_INTR_VECTOR: 33 | ;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt 34 | push YL ;[-25] push only what is necessary to sync with edge ASAP 35 | in YL, SREG ;[-23] 36 | push YL ;[-22] 37 | push YH ;[-20] 38 | ;---------------------------------------------------------------------------- 39 | ; Synchronize with sync pattern: 40 | ;---------------------------------------------------------------------------- 41 | ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 42 | ;sync up with J to K edge during sync pattern -- use fastest possible loops 43 | ;The first part waits at most 1 bit long since we must be in sync pattern. 44 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 45 | ;waitForJ, ensure that this prerequisite is met. 46 | waitForJ: 47 | inc YL 48 | sbis USBIN, USBMINUS 49 | brne waitForJ ; just make sure we have ANY timeout 50 | waitForK: 51 | ;The following code results in a sampling window of < 1/4 bit which meets the spec. 52 | sbis USBIN, USBMINUS ;[-15] 53 | rjmp foundK ;[-14] 54 | sbis USBIN, USBMINUS 55 | rjmp foundK 56 | sbis USBIN, USBMINUS 57 | rjmp foundK 58 | sbis USBIN, USBMINUS 59 | rjmp foundK 60 | sbis USBIN, USBMINUS 61 | rjmp foundK 62 | sbis USBIN, USBMINUS 63 | rjmp foundK 64 | #if USB_COUNT_SOF 65 | lds YL, usbSofCount 66 | inc YL 67 | sts usbSofCount, YL 68 | #endif /* USB_COUNT_SOF */ 69 | #ifdef USB_SOF_HOOK 70 | USB_SOF_HOOK 71 | #endif 72 | rjmp sofError 73 | foundK: ;[-12] 74 | ;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling] 75 | ;we have 1 bit time for setup purposes, then sample again. Numbers in brackets 76 | ;are cycles from center of first sync (double K) bit after the instruction 77 | push bitcnt ;[-12] 78 | ; [---] ;[-11] 79 | lds YL, usbInputBufOffset;[-10] 80 | ; [---] ;[-9] 81 | clr YH ;[-8] 82 | subi YL, lo8(-(usbRxBuf));[-7] [rx loop init] 83 | sbci YH, hi8(-(usbRxBuf));[-6] [rx loop init] 84 | push shift ;[-5] 85 | ; [---] ;[-4] 86 | ldi bitcnt, 0x55 ;[-3] [rx loop init] 87 | sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early) 88 | rjmp haveTwoBitsK ;[-1] 89 | pop shift ;[0] undo the push from before 90 | pop bitcnt ;[2] undo the push from before 91 | rjmp waitForK ;[4] this was not the end of sync, retry 92 | ; The entire loop from waitForK until rjmp waitForK above must not exceed two 93 | ; bit times (= 21 cycles). 94 | 95 | ;---------------------------------------------------------------------------- 96 | ; push more registers and initialize values while we sample the first bits: 97 | ;---------------------------------------------------------------------------- 98 | haveTwoBitsK: 99 | push x1 ;[1] 100 | push x2 ;[3] 101 | push x3 ;[5] 102 | ldi shift, 0 ;[7] 103 | ldi x3, 1<<4 ;[8] [rx loop init] first sample is inverse bit, compensate that 104 | push x4 ;[9] == leap 105 | 106 | in x1, USBIN ;[11] <-- sample bit 0 107 | andi x1, USBMASK ;[12] 108 | bst x1, USBMINUS ;[13] 109 | bld shift, 7 ;[14] 110 | push cnt ;[15] 111 | ldi leap, 0 ;[17] [rx loop init] 112 | ldi cnt, USB_BUFSIZE;[18] [rx loop init] 113 | rjmp rxbit1 ;[19] arrives at [21] 114 | 115 | ;---------------------------------------------------------------------------- 116 | ; Receiver loop (numbers in brackets are cycles within byte after instr) 117 | ;---------------------------------------------------------------------------- 118 | 119 | ; duration of unstuffing code should be 10.66666667 cycles. We adjust "leap" 120 | ; accordingly to approximate this value in the long run. 121 | 122 | unstuff6: 123 | andi x2, USBMASK ;[03] 124 | ori x3, 1<<6 ;[04] will not be shifted any more 125 | andi shift, ~0x80;[05] 126 | mov x1, x2 ;[06] sampled bit 7 is actually re-sampled bit 6 127 | subi leap, -1 ;[07] total duration = 11 bits -> subtract 1/3 128 | rjmp didUnstuff6 ;[08] 129 | 130 | unstuff7: 131 | ori x3, 1<<7 ;[09] will not be shifted any more 132 | in x2, USBIN ;[00] [10] re-sample bit 7 133 | andi x2, USBMASK ;[01] 134 | andi shift, ~0x80;[02] 135 | subi leap, 2 ;[03] total duration = 10 bits -> add 1/3 136 | rjmp didUnstuff7 ;[04] 137 | 138 | unstuffEven: 139 | ori x3, 1<<6 ;[09] will be shifted right 6 times for bit 0 140 | in x1, USBIN ;[00] [10] 141 | andi shift, ~0x80;[01] 142 | andi x1, USBMASK ;[02] 143 | breq se0 ;[03] 144 | subi leap, -1 ;[04] total duration = 11 bits -> subtract 1/3 145 | nop2 ;[05] 146 | rjmp didUnstuffE ;[06] 147 | 148 | unstuffOdd: 149 | ori x3, 1<<5 ;[09] will be shifted right 4 times for bit 1 150 | in x2, USBIN ;[00] [10] 151 | andi shift, ~0x80;[01] 152 | andi x2, USBMASK ;[02] 153 | breq se0 ;[03] 154 | subi leap, -1 ;[04] total duration = 11 bits -> subtract 1/3 155 | nop2 ;[05] 156 | rjmp didUnstuffO ;[06] 157 | 158 | rxByteLoop: 159 | andi x1, USBMASK ;[03] 160 | eor x2, x1 ;[04] 161 | subi leap, 1 ;[05] 162 | brpl skipLeap ;[06] 163 | subi leap, -3 ;1 one leap cycle every 3rd byte -> 85 + 1/3 cycles per byte 164 | nop ;1 165 | skipLeap: 166 | subi x2, 1 ;[08] 167 | ror shift ;[09] 168 | didUnstuff6: 169 | cpi shift, 0xfc ;[10] 170 | in x2, USBIN ;[00] [11] <-- sample bit 7 171 | brcc unstuff6 ;[01] 172 | andi x2, USBMASK ;[02] 173 | eor x1, x2 ;[03] 174 | subi x1, 1 ;[04] 175 | ror shift ;[05] 176 | didUnstuff7: 177 | cpi shift, 0xfc ;[06] 178 | brcc unstuff7 ;[07] 179 | eor x3, shift ;[08] reconstruct: x3 is 1 at bit locations we changed, 0 at others 180 | st y+, x3 ;[09] store data 181 | rxBitLoop: 182 | in x1, USBIN ;[00] [11] <-- sample bit 0/2/4 183 | andi x1, USBMASK ;[01] 184 | eor x2, x1 ;[02] 185 | andi x3, 0x3f ;[03] topmost two bits reserved for 6 and 7 186 | subi x2, 1 ;[04] 187 | ror shift ;[05] 188 | cpi shift, 0xfc ;[06] 189 | brcc unstuffEven ;[07] 190 | didUnstuffE: 191 | lsr x3 ;[08] 192 | lsr x3 ;[09] 193 | rxbit1: 194 | in x2, USBIN ;[00] [10] <-- sample bit 1/3/5 195 | andi x2, USBMASK ;[01] 196 | breq se0 ;[02] 197 | eor x1, x2 ;[03] 198 | subi x1, 1 ;[04] 199 | ror shift ;[05] 200 | cpi shift, 0xfc ;[06] 201 | brcc unstuffOdd ;[07] 202 | didUnstuffO: 203 | subi bitcnt, 0xab;[08] == addi 0x55, 0x55 = 0x100/3 204 | brcs rxBitLoop ;[09] 205 | 206 | subi cnt, 1 ;[10] 207 | in x1, USBIN ;[00] [11] <-- sample bit 6 208 | brcc rxByteLoop ;[01] 209 | rjmp overflow 210 | 211 | macro POP_STANDARD ; 14 cycles 212 | pop cnt 213 | pop x4 214 | pop x3 215 | pop x2 216 | pop x1 217 | pop shift 218 | pop bitcnt 219 | endm 220 | macro POP_RETI ; 7 cycles 221 | pop YH 222 | pop YL 223 | out SREG, YL 224 | pop YL 225 | endm 226 | 227 | #include "asmcommon.inc" 228 | 229 | ; USB spec says: 230 | ; idle = J 231 | ; J = (D+ = 0), (D- = 1) 232 | ; K = (D+ = 1), (D- = 0) 233 | ; Spec allows 7.5 bit times from EOP to SOP for replies 234 | 235 | bitstuffN: 236 | eor x1, x4 ;[5] 237 | ldi x2, 0 ;[6] 238 | nop2 ;[7] 239 | nop ;[9] 240 | out USBOUT, x1 ;[10] <-- out 241 | rjmp didStuffN ;[0] 242 | 243 | bitstuff6: 244 | eor x1, x4 ;[5] 245 | ldi x2, 0 ;[6] Carry is zero due to brcc 246 | rol shift ;[7] compensate for ror shift at branch destination 247 | rjmp didStuff6 ;[8] 248 | 249 | bitstuff7: 250 | ldi x2, 0 ;[2] Carry is zero due to brcc 251 | rjmp didStuff7 ;[3] 252 | 253 | 254 | sendNakAndReti: 255 | ldi x3, USBPID_NAK ;[-18] 256 | rjmp sendX3AndReti ;[-17] 257 | sendAckAndReti: 258 | ldi cnt, USBPID_ACK ;[-17] 259 | sendCntAndReti: 260 | mov x3, cnt ;[-16] 261 | sendX3AndReti: 262 | ldi YL, 20 ;[-15] x3==r20 address is 20 263 | ldi YH, 0 ;[-14] 264 | ldi cnt, 2 ;[-13] 265 | ; rjmp usbSendAndReti fallthrough 266 | 267 | ;usbSend: 268 | ;pointer to data in 'Y' 269 | ;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] 270 | ;uses: x1...x4, btcnt, shift, cnt, Y 271 | ;Numbers in brackets are time since first bit of sync pattern is sent 272 | ;We don't match the transfer rate exactly (don't insert leap cycles every third 273 | ;byte) because the spec demands only 1.5% precision anyway. 274 | usbSendAndReti: ; 12 cycles until SOP 275 | in x2, USBDDR ;[-12] 276 | ori x2, USBMASK ;[-11] 277 | sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) 278 | in x1, USBOUT ;[-8] port mirror for tx loop 279 | out USBDDR, x2 ;[-7] <- acquire bus 280 | ; need not init x2 (bitstuff history) because sync starts with 0 281 | ldi x4, USBMASK ;[-6] exor mask 282 | ldi shift, 0x80 ;[-5] sync byte is first byte sent 283 | txByteLoop: 284 | ldi bitcnt, 0x35 ;[-4] [6] binary 0011 0101 285 | txBitLoop: 286 | sbrs shift, 0 ;[-3] [7] 287 | eor x1, x4 ;[-2] [8] 288 | out USBOUT, x1 ;[-1] [9] <-- out N 289 | ror shift ;[0] [10] 290 | ror x2 ;[1] 291 | didStuffN: 292 | cpi x2, 0xfc ;[2] 293 | brcc bitstuffN ;[3] 294 | lsr bitcnt ;[4] 295 | brcc txBitLoop ;[5] 296 | brne txBitLoop ;[6] 297 | 298 | sbrs shift, 0 ;[7] 299 | eor x1, x4 ;[8] 300 | didStuff6: 301 | out USBOUT, x1 ;[-1] [9] <-- out 6 302 | ror shift ;[0] [10] 303 | ror x2 ;[1] 304 | cpi x2, 0xfc ;[2] 305 | brcc bitstuff6 ;[3] 306 | ror shift ;[4] 307 | didStuff7: 308 | ror x2 ;[5] 309 | sbrs x2, 7 ;[6] 310 | eor x1, x4 ;[7] 311 | nop ;[8] 312 | cpi x2, 0xfc ;[9] 313 | out USBOUT, x1 ;[-1][10] <-- out 7 314 | brcc bitstuff7 ;[0] [11] 315 | ld shift, y+ ;[1] 316 | dec cnt ;[3] 317 | brne txByteLoop ;[4] 318 | ;make SE0: 319 | cbr x1, USBMASK ;[5] prepare SE0 [spec says EOP may be 21 to 25 cycles] 320 | lds x2, usbNewDeviceAddr;[6] 321 | lsl x2 ;[8] we compare with left shifted address 322 | subi YL, 20 + 2 ;[9] Only assign address on data packets, not ACK/NAK in x3 323 | sbci YH, 0 ;[10] 324 | out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle 325 | ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: 326 | ;set address only after data packet was sent, not after handshake 327 | breq skipAddrAssign ;[0] 328 | sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer 329 | skipAddrAssign: 330 | ;end of usbDeviceAddress transfer 331 | ldi x2, 1< max 52 cycles interrupt disable 31 | ;max stack usage: [ret(2), r0, SREG, YL, YH, shift, x1, x2, x3, x4, cnt] = 12 bytes 32 | ;nominal frequency: 16.5 MHz -> 11 cycles per bit 33 | ; 16.3125 MHz < F_CPU < 16.6875 MHz (+/- 1.1%) 34 | ; Numbers in brackets are clocks counted from center of last sync bit 35 | ; when instruction starts 36 | 37 | 38 | USB_INTR_VECTOR: 39 | ;order of registers pushed: YL, SREG [sofError], r0, YH, shift, x1, x2, x3, x4, cnt 40 | push YL ;[-23] push only what is necessary to sync with edge ASAP 41 | in YL, SREG ;[-21] 42 | push YL ;[-20] 43 | ;---------------------------------------------------------------------------- 44 | ; Synchronize with sync pattern: 45 | ;---------------------------------------------------------------------------- 46 | ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 47 | ;sync up with J to K edge during sync pattern -- use fastest possible loops 48 | ;The first part waits at most 1 bit long since we must be in sync pattern. 49 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 50 | ;waitForJ, ensure that this prerequisite is met. 51 | waitForJ: 52 | inc YL 53 | sbis USBIN, USBMINUS 54 | brne waitForJ ; just make sure we have ANY timeout 55 | waitForK: 56 | ;The following code results in a sampling window of < 1/4 bit which meets the spec. 57 | sbis USBIN, USBMINUS ;[-15] 58 | rjmp foundK ;[-14] 59 | sbis USBIN, USBMINUS 60 | rjmp foundK 61 | sbis USBIN, USBMINUS 62 | rjmp foundK 63 | sbis USBIN, USBMINUS 64 | rjmp foundK 65 | sbis USBIN, USBMINUS 66 | rjmp foundK 67 | sbis USBIN, USBMINUS 68 | rjmp foundK 69 | #if USB_COUNT_SOF 70 | lds YL, usbSofCount 71 | inc YL 72 | sts usbSofCount, YL 73 | #endif /* USB_COUNT_SOF */ 74 | #ifdef USB_SOF_HOOK 75 | USB_SOF_HOOK 76 | #endif 77 | rjmp sofError 78 | foundK: ;[-12] 79 | ;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling] 80 | ;we have 1 bit time for setup purposes, then sample again. Numbers in brackets 81 | ;are cycles from center of first sync (double K) bit after the instruction 82 | push r0 ;[-12] 83 | ; [---] ;[-11] 84 | push YH ;[-10] 85 | ; [---] ;[-9] 86 | lds YL, usbInputBufOffset;[-8] 87 | ; [---] ;[-7] 88 | clr YH ;[-6] 89 | subi YL, lo8(-(usbRxBuf));[-5] [rx loop init] 90 | sbci YH, hi8(-(usbRxBuf));[-4] [rx loop init] 91 | mov r0, x2 ;[-3] [rx loop init] 92 | sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early) 93 | rjmp haveTwoBitsK ;[-1] 94 | pop YH ;[0] undo the pushes from before 95 | pop r0 ;[2] 96 | rjmp waitForK ;[4] this was not the end of sync, retry 97 | ; The entire loop from waitForK until rjmp waitForK above must not exceed two 98 | ; bit times (= 22 cycles). 99 | 100 | ;---------------------------------------------------------------------------- 101 | ; push more registers and initialize values while we sample the first bits: 102 | ;---------------------------------------------------------------------------- 103 | haveTwoBitsK: ;[1] 104 | push shift ;[1] 105 | push x1 ;[3] 106 | push x2 ;[5] 107 | push x3 ;[7] 108 | ldi shift, 0xff ;[9] [rx loop init] 109 | ori x3, 0xff ;[10] [rx loop init] == ser x3, clear zero flag 110 | 111 | in x1, USBIN ;[11] <-- sample bit 0 112 | bst x1, USBMINUS ;[12] 113 | bld shift, 0 ;[13] 114 | push x4 ;[14] == phase 115 | ; [---] ;[15] 116 | push cnt ;[16] 117 | ; [---] ;[17] 118 | ldi phase, 0 ;[18] [rx loop init] 119 | ldi cnt, USB_BUFSIZE;[19] [rx loop init] 120 | rjmp rxbit1 ;[20] 121 | ; [---] ;[21] 122 | 123 | ;---------------------------------------------------------------------------- 124 | ; Receiver loop (numbers in brackets are cycles within byte after instr) 125 | ;---------------------------------------------------------------------------- 126 | /* 127 | byte oriented operations done during loop: 128 | bit 0: store data 129 | bit 1: SE0 check 130 | bit 2: overflow check 131 | bit 3: catch up 132 | bit 4: rjmp to achieve conditional jump range 133 | bit 5: PLL 134 | bit 6: catch up 135 | bit 7: jump, fixup bitstuff 136 | ; 87 [+ 2] cycles 137 | ------------------------------------------------------------------ 138 | */ 139 | continueWithBit5: 140 | in x2, USBIN ;[055] <-- bit 5 141 | eor r0, x2 ;[056] 142 | or phase, r0 ;[057] 143 | sbrc phase, USBMINUS ;[058] 144 | lpm ;[059] optional nop3; modifies r0 145 | in phase, USBIN ;[060] <-- phase 146 | eor x1, x2 ;[061] 147 | bst x1, USBMINUS ;[062] 148 | bld shift, 5 ;[063] 149 | andi shift, 0x3f ;[064] 150 | in x1, USBIN ;[065] <-- bit 6 151 | breq unstuff5 ;[066] *** unstuff escape 152 | eor phase, x1 ;[067] 153 | eor x2, x1 ;[068] 154 | bst x2, USBMINUS ;[069] 155 | bld shift, 6 ;[070] 156 | didUnstuff6: ;[ ] 157 | in r0, USBIN ;[071] <-- phase 158 | cpi shift, 0x02 ;[072] 159 | brlo unstuff6 ;[073] *** unstuff escape 160 | didUnstuff5: ;[ ] 161 | nop2 ;[074] 162 | ; [---] ;[075] 163 | in x2, USBIN ;[076] <-- bit 7 164 | eor x1, x2 ;[077] 165 | bst x1, USBMINUS ;[078] 166 | bld shift, 7 ;[079] 167 | didUnstuff7: ;[ ] 168 | eor r0, x2 ;[080] 169 | or phase, r0 ;[081] 170 | in r0, USBIN ;[082] <-- phase 171 | cpi shift, 0x04 ;[083] 172 | brsh rxLoop ;[084] 173 | ; [---] ;[085] 174 | unstuff7: ;[ ] 175 | andi x3, ~0x80 ;[085] 176 | ori shift, 0x80 ;[086] 177 | in x2, USBIN ;[087] <-- sample stuffed bit 7 178 | nop ;[088] 179 | rjmp didUnstuff7 ;[089] 180 | ; [---] ;[090] 181 | ;[080] 182 | 183 | unstuff5: ;[067] 184 | eor phase, x1 ;[068] 185 | andi x3, ~0x20 ;[069] 186 | ori shift, 0x20 ;[070] 187 | in r0, USBIN ;[071] <-- phase 188 | mov x2, x1 ;[072] 189 | nop ;[073] 190 | nop2 ;[074] 191 | ; [---] ;[075] 192 | in x1, USBIN ;[076] <-- bit 6 193 | eor r0, x1 ;[077] 194 | or phase, r0 ;[078] 195 | eor x2, x1 ;[079] 196 | bst x2, USBMINUS ;[080] 197 | bld shift, 6 ;[081] no need to check bitstuffing, we just had one 198 | in r0, USBIN ;[082] <-- phase 199 | rjmp didUnstuff5 ;[083] 200 | ; [---] ;[084] 201 | ;[074] 202 | 203 | unstuff6: ;[074] 204 | andi x3, ~0x40 ;[075] 205 | in x1, USBIN ;[076] <-- bit 6 again 206 | ori shift, 0x40 ;[077] 207 | nop2 ;[078] 208 | ; [---] ;[079] 209 | rjmp didUnstuff6 ;[080] 210 | ; [---] ;[081] 211 | ;[071] 212 | 213 | unstuff0: ;[013] 214 | eor r0, x2 ;[014] 215 | or phase, r0 ;[015] 216 | andi x2, USBMASK ;[016] check for SE0 217 | in r0, USBIN ;[017] <-- phase 218 | breq didUnstuff0 ;[018] direct jump to se0 would be too long 219 | andi x3, ~0x01 ;[019] 220 | ori shift, 0x01 ;[020] 221 | mov x1, x2 ;[021] mov existing sample 222 | in x2, USBIN ;[022] <-- bit 1 again 223 | rjmp didUnstuff0 ;[023] 224 | ; [---] ;[024] 225 | ;[014] 226 | 227 | unstuff1: ;[024] 228 | eor r0, x1 ;[025] 229 | or phase, r0 ;[026] 230 | andi x3, ~0x02 ;[027] 231 | in r0, USBIN ;[028] <-- phase 232 | ori shift, 0x02 ;[029] 233 | mov x2, x1 ;[030] 234 | rjmp didUnstuff1 ;[031] 235 | ; [---] ;[032] 236 | ;[022] 237 | 238 | unstuff2: ;[035] 239 | eor r0, x2 ;[036] 240 | or phase, r0 ;[037] 241 | andi x3, ~0x04 ;[038] 242 | in r0, USBIN ;[039] <-- phase 243 | ori shift, 0x04 ;[040] 244 | mov x1, x2 ;[041] 245 | rjmp didUnstuff2 ;[042] 246 | ; [---] ;[043] 247 | ;[033] 248 | 249 | unstuff3: ;[043] 250 | in x2, USBIN ;[044] <-- bit 3 again 251 | eor r0, x2 ;[045] 252 | or phase, r0 ;[046] 253 | andi x3, ~0x08 ;[047] 254 | ori shift, 0x08 ;[048] 255 | nop ;[049] 256 | in r0, USBIN ;[050] <-- phase 257 | rjmp didUnstuff3 ;[051] 258 | ; [---] ;[052] 259 | ;[042] 260 | 261 | unstuff4: ;[053] 262 | andi x3, ~0x10 ;[054] 263 | in x1, USBIN ;[055] <-- bit 4 again 264 | ori shift, 0x10 ;[056] 265 | rjmp didUnstuff4 ;[057] 266 | ; [---] ;[058] 267 | ;[048] 268 | 269 | rxLoop: ;[085] 270 | eor x3, shift ;[086] reconstruct: x3 is 0 at bit locations we changed, 1 at others 271 | in x1, USBIN ;[000] <-- bit 0 272 | st y+, x3 ;[001] 273 | ; [---] ;[002] 274 | eor r0, x1 ;[003] 275 | or phase, r0 ;[004] 276 | eor x2, x1 ;[005] 277 | in r0, USBIN ;[006] <-- phase 278 | ser x3 ;[007] 279 | bst x2, USBMINUS ;[008] 280 | bld shift, 0 ;[009] 281 | andi shift, 0xf9 ;[010] 282 | rxbit1: ;[ ] 283 | in x2, USBIN ;[011] <-- bit 1 284 | breq unstuff0 ;[012] *** unstuff escape 285 | andi x2, USBMASK ;[013] SE0 check for bit 1 286 | didUnstuff0: ;[ ] Z only set if we detected SE0 in bitstuff 287 | breq se0 ;[014] 288 | eor r0, x2 ;[015] 289 | or phase, r0 ;[016] 290 | in r0, USBIN ;[017] <-- phase 291 | eor x1, x2 ;[018] 292 | bst x1, USBMINUS ;[019] 293 | bld shift, 1 ;[020] 294 | andi shift, 0xf3 ;[021] 295 | didUnstuff1: ;[ ] 296 | in x1, USBIN ;[022] <-- bit 2 297 | breq unstuff1 ;[023] *** unstuff escape 298 | eor r0, x1 ;[024] 299 | or phase, r0 ;[025] 300 | subi cnt, 1 ;[026] overflow check 301 | brcs overflow ;[027] 302 | in r0, USBIN ;[028] <-- phase 303 | eor x2, x1 ;[029] 304 | bst x2, USBMINUS ;[030] 305 | bld shift, 2 ;[031] 306 | andi shift, 0xe7 ;[032] 307 | didUnstuff2: ;[ ] 308 | in x2, USBIN ;[033] <-- bit 3 309 | breq unstuff2 ;[034] *** unstuff escape 310 | eor r0, x2 ;[035] 311 | or phase, r0 ;[036] 312 | eor x1, x2 ;[037] 313 | bst x1, USBMINUS ;[038] 314 | in r0, USBIN ;[039] <-- phase 315 | bld shift, 3 ;[040] 316 | andi shift, 0xcf ;[041] 317 | didUnstuff3: ;[ ] 318 | breq unstuff3 ;[042] *** unstuff escape 319 | nop ;[043] 320 | in x1, USBIN ;[044] <-- bit 4 321 | eor x2, x1 ;[045] 322 | bst x2, USBMINUS ;[046] 323 | bld shift, 4 ;[047] 324 | didUnstuff4: ;[ ] 325 | eor r0, x1 ;[048] 326 | or phase, r0 ;[049] 327 | in r0, USBIN ;[050] <-- phase 328 | andi shift, 0x9f ;[051] 329 | breq unstuff4 ;[052] *** unstuff escape 330 | rjmp continueWithBit5;[053] 331 | ; [---] ;[054] 332 | 333 | macro POP_STANDARD ; 16 cycles 334 | pop cnt 335 | pop x4 336 | pop x3 337 | pop x2 338 | pop x1 339 | pop shift 340 | pop YH 341 | pop r0 342 | endm 343 | macro POP_RETI ; 5 cycles 344 | pop YL 345 | out SREG, YL 346 | pop YL 347 | endm 348 | 349 | #include "asmcommon.inc" 350 | 351 | 352 | ; USB spec says: 353 | ; idle = J 354 | ; J = (D+ = 0), (D- = 1) 355 | ; K = (D+ = 1), (D- = 0) 356 | ; Spec allows 7.5 bit times from EOP to SOP for replies 357 | 358 | bitstuff7: 359 | eor x1, x4 ;[4] 360 | ldi x2, 0 ;[5] 361 | nop2 ;[6] C is zero (brcc) 362 | rjmp didStuff7 ;[8] 363 | 364 | bitstuffN: 365 | eor x1, x4 ;[5] 366 | ldi x2, 0 ;[6] 367 | lpm ;[7] 3 cycle NOP, modifies r0 368 | out USBOUT, x1 ;[10] <-- out 369 | rjmp didStuffN ;[0] 370 | 371 | #define bitStatus x3 372 | 373 | sendNakAndReti: 374 | ldi cnt, USBPID_NAK ;[-19] 375 | rjmp sendCntAndReti ;[-18] 376 | sendAckAndReti: 377 | ldi cnt, USBPID_ACK ;[-17] 378 | sendCntAndReti: 379 | mov r0, cnt ;[-16] 380 | ldi YL, 0 ;[-15] R0 address is 0 381 | ldi YH, 0 ;[-14] 382 | ldi cnt, 2 ;[-13] 383 | ; rjmp usbSendAndReti fallthrough 384 | 385 | ;usbSend: 386 | ;pointer to data in 'Y' 387 | ;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] 388 | ;uses: x1...x4, shift, cnt, Y 389 | ;Numbers in brackets are time since first bit of sync pattern is sent 390 | usbSendAndReti: ; 12 cycles until SOP 391 | in x2, USBDDR ;[-12] 392 | ori x2, USBMASK ;[-11] 393 | sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) 394 | in x1, USBOUT ;[-8] port mirror for tx loop 395 | out USBDDR, x2 ;[-7] <- acquire bus 396 | ; need not init x2 (bitstuff history) because sync starts with 0 397 | ldi x4, USBMASK ;[-6] exor mask 398 | ldi shift, 0x80 ;[-5] sync byte is first byte sent 399 | ldi bitStatus, 0xff ;[-4] init bit loop counter, works for up to 12 bytes 400 | byteloop: 401 | bitloop: 402 | sbrs shift, 0 ;[8] [-3] 403 | eor x1, x4 ;[9] [-2] 404 | out USBOUT, x1 ;[10] [-1] <-- out 405 | ror shift ;[0] 406 | ror x2 ;[1] 407 | didStuffN: 408 | cpi x2, 0xfc ;[2] 409 | brcc bitstuffN ;[3] 410 | nop ;[4] 411 | subi bitStatus, 37 ;[5] 256 / 7 ~=~ 37 412 | brcc bitloop ;[6] when we leave the loop, bitStatus has almost the initial value 413 | sbrs shift, 0 ;[7] 414 | eor x1, x4 ;[8] 415 | ror shift ;[9] 416 | didStuff7: 417 | out USBOUT, x1 ;[10] <-- out 418 | ror x2 ;[0] 419 | cpi x2, 0xfc ;[1] 420 | brcc bitstuff7 ;[2] 421 | ld shift, y+ ;[3] 422 | dec cnt ;[5] 423 | brne byteloop ;[6] 424 | ;make SE0: 425 | cbr x1, USBMASK ;[7] prepare SE0 [spec says EOP may be 21 to 25 cycles] 426 | lds x2, usbNewDeviceAddr;[8] 427 | lsl x2 ;[10] we compare with left shifted address 428 | out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle 429 | ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: 430 | ;set address only after data packet was sent, not after handshake 431 | subi YL, 2 ;[0] Only assign address on data packets, not ACK/NAK in r0 432 | sbci YH, 0 ;[1] 433 | breq skipAddrAssign ;[2] 434 | sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer 435 | skipAddrAssign: 436 | ;end of usbDeviceAddress transfer 437 | ldi x2, 1< 13.333333 cycles per bit, 106.666667 cycles per byte 37 | ; Numbers in brackets are clocks counted from center of last sync bit 38 | ; when instruction starts 39 | ;register use in receive loop: 40 | ; shift assembles the byte currently being received 41 | ; x1 holds the D+ and D- line state 42 | ; x2 holds the previous line state 43 | ; x4 (leap) is used to add a leap cycle once every three bytes received 44 | ; X3 (leap2) is used to add a leap cycle once every three stuff bits received 45 | ; bitcnt is used to determine when a stuff bit is due 46 | ; cnt holds the number of bytes left in the receive buffer 47 | 48 | USB_INTR_VECTOR: 49 | ;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt 50 | push YL ;[-28] push only what is necessary to sync with edge ASAP 51 | in YL, SREG ;[-26] 52 | push YL ;[-25] 53 | push YH ;[-23] 54 | ;---------------------------------------------------------------------------- 55 | ; Synchronize with sync pattern: 56 | ;---------------------------------------------------------------------------- 57 | ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] 58 | ;sync up with J to K edge during sync pattern -- use fastest possible loops 59 | ;The first part waits at most 1 bit long since we must be in sync pattern. 60 | ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to 61 | ;waitForJ, ensure that this prerequisite is met. 62 | waitForJ: 63 | inc YL 64 | sbis USBIN, USBMINUS 65 | brne waitForJ ; just make sure we have ANY timeout 66 | waitForK: 67 | ;The following code results in a sampling window of < 1/4 bit which meets the spec. 68 | sbis USBIN, USBMINUS ;[-19] 69 | rjmp foundK ;[-18] 70 | sbis USBIN, USBMINUS 71 | rjmp foundK 72 | sbis USBIN, USBMINUS 73 | rjmp foundK 74 | sbis USBIN, USBMINUS 75 | rjmp foundK 76 | sbis USBIN, USBMINUS 77 | rjmp foundK 78 | sbis USBIN, USBMINUS 79 | rjmp foundK 80 | sbis USBIN, USBMINUS 81 | rjmp foundK 82 | sbis USBIN, USBMINUS 83 | rjmp foundK 84 | sbis USBIN, USBMINUS 85 | rjmp foundK 86 | #if USB_COUNT_SOF 87 | lds YL, usbSofCount 88 | inc YL 89 | sts usbSofCount, YL 90 | #endif /* USB_COUNT_SOF */ 91 | #ifdef USB_SOF_HOOK 92 | USB_SOF_HOOK 93 | #endif 94 | rjmp sofError 95 | foundK: ;[-16] 96 | ;{3, 5} after falling D- edge, average delay: 4 cycles 97 | ;bit0 should be at 34 for center sampling. Currently at 4 so 30 cylces till bit 0 sample 98 | ;use 1 bit time for setup purposes, then sample again. Numbers in brackets 99 | ;are cycles from center of first sync (double K) bit after the instruction 100 | push bitcnt ;[-16] 101 | ; [---] ;[-15] 102 | lds YL, usbInputBufOffset;[-14] 103 | ; [---] ;[-13] 104 | clr YH ;[-12] 105 | subi YL, lo8(-(usbRxBuf));[-11] [rx loop init] 106 | sbci YH, hi8(-(usbRxBuf));[-10] [rx loop init] 107 | push shift ;[-9] 108 | ; [---] ;[-8] 109 | ldi shift,0x40 ;[-7] set msb to "1" so processing bit7 can be detected 110 | nop2 ;[-6] 111 | ; [---] ;[-5] 112 | ldi bitcnt, 5 ;[-4] [rx loop init] 113 | sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early) 114 | rjmp haveTwoBitsK ;[-2] 115 | pop shift ;[-1] undo the push from before 116 | pop bitcnt ;[1] 117 | rjmp waitForK ;[3] this was not the end of sync, retry 118 | ; The entire loop from waitForK until rjmp waitForK above must not exceed two 119 | ; bit times (= 27 cycles). 120 | 121 | ;---------------------------------------------------------------------------- 122 | ; push more registers and initialize values while we sample the first bits: 123 | ;---------------------------------------------------------------------------- 124 | haveTwoBitsK: 125 | push x1 ;[0] 126 | push x2 ;[2] 127 | push x3 ;[4] (leap2) 128 | ldi leap2, 0x55 ;[6] add leap cycle on 2nd,5th,8th,... stuff bit 129 | push x4 ;[7] == leap 130 | ldi leap, 0x55 ;[9] skip leap cycle on 2nd,5th,8th,... byte received 131 | push cnt ;[10] 132 | ldi cnt, USB_BUFSIZE ;[12] [rx loop init] 133 | ldi x2, 1< 38 | #ifndef __IAR_SYSTEMS_ASM__ 39 | # include 40 | #endif 41 | 42 | #define __attribute__(arg) /* not supported on IAR */ 43 | 44 | #ifdef __IAR_SYSTEMS_ASM__ 45 | # define __ASSEMBLER__ /* IAR does not define standard macro for asm */ 46 | #endif 47 | 48 | #ifdef __HAS_ELPM__ 49 | # define PROGMEM __farflash 50 | #else 51 | # define PROGMEM __flash 52 | #endif 53 | 54 | #define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr)) 55 | 56 | /* The following definitions are not needed by the driver, but may be of some 57 | * help if you port a gcc based project to IAR. 58 | */ 59 | #define cli() __disable_interrupt() 60 | #define sei() __enable_interrupt() 61 | #define wdt_reset() __watchdog_reset() 62 | #define _BV(x) (1 << (x)) 63 | 64 | /* assembler compatibility macros */ 65 | #define nop2 rjmp $+2 /* jump to next instruction */ 66 | #define XL r26 67 | #define XH r27 68 | #define YL r28 69 | #define YH r29 70 | #define ZL r30 71 | #define ZH r31 72 | #define lo8(x) LOW(x) 73 | #define hi8(x) (((x)>>8) & 0xff) /* not HIGH to allow XLINK to make a proper range check */ 74 | 75 | /* Depending on the device you use, you may get problems with the way usbdrv.h 76 | * handles the differences between devices. Since IAR does not use #defines 77 | * for MCU registers, we can't check for the existence of a particular 78 | * register with an #ifdef. If the autodetection mechanism fails, include 79 | * definitions for the required USB_INTR_* macros in your usbconfig.h. See 80 | * usbconfig-prototype.h and usbdrv.h for details. 81 | */ 82 | 83 | /* ------------------------------------------------------------------------- */ 84 | #elif __CODEVISIONAVR__ /* check for CodeVision AVR */ 85 | /* ------------------------------------------------------------------------- */ 86 | /* This port is not working (yet) */ 87 | 88 | /* #define F_CPU _MCU_CLOCK_FREQUENCY_ seems to be defined automatically */ 89 | 90 | #include 91 | #include 92 | 93 | #define __attribute__(arg) /* not supported on IAR */ 94 | 95 | #define PROGMEM __flash 96 | #define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr)) 97 | 98 | #ifndef __ASSEMBLER__ 99 | static inline void cli(void) 100 | { 101 | #asm("cli"); 102 | } 103 | static inline void sei(void) 104 | { 105 | #asm("sei"); 106 | } 107 | #endif 108 | #define _delay_ms(t) delay_ms(t) 109 | #define _BV(x) (1 << (x)) 110 | #define USB_CFG_USE_SWITCH_STATEMENT 1 /* macro for if() cascase fails for unknown reason */ 111 | 112 | #define macro .macro 113 | #define endm .endmacro 114 | #define nop2 rjmp .+0 /* jump to next instruction */ 115 | 116 | /* ------------------------------------------------------------------------- */ 117 | #else /* default development environment is avr-gcc/avr-libc */ 118 | /* ------------------------------------------------------------------------- */ 119 | 120 | #include 121 | #ifdef __ASSEMBLER__ 122 | # define _VECTOR(N) __vector_ ## N /* io.h does not define this for asm */ 123 | #else 124 | # include 125 | #endif 126 | 127 | #if USB_CFG_DRIVER_FLASH_PAGE 128 | # define USB_READ_FLASH(addr) pgm_read_byte_far(((long)USB_CFG_DRIVER_FLASH_PAGE << 16) | (long)(addr)) 129 | #else 130 | # define USB_READ_FLASH(addr) pgm_read_byte(addr) 131 | #endif 132 | 133 | #define macro .macro 134 | #define endm .endm 135 | #define nop2 rjmp .+0 /* jump to next instruction */ 136 | 137 | #endif /* development environment */ 138 | 139 | /* for conveniecne, ensure that PRG_RDB exists */ 140 | #ifndef PRG_RDB 141 | # define PRG_RDB(addr) USB_READ_FLASH(addr) 142 | #endif 143 | #endif /* __usbportability_h_INCLUDED__ */ 144 | --------------------------------------------------------------------------------