Blame | Last modification | View Log | RSS feed
1 # 1 "vusb-20120109/usbdrv/usbdrvasm.S"1 /* Name: usbdrvasm.S002 * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers3 * Author: Christian Starkjohann4 * Creation Date: 2007-06-135 * Tabsize: 46 * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH7 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)8 * Revision: $Id$9 */1011 /*12 General Description:13 This module is the assembler part of the USB driver. This file contains14 general code (preprocessor acrobatics and CRC computation) and then includes15 the file appropriate for the given clock rate.16 */1718 #define __SFR_OFFSET 0 /* used by avr-libc's register definitions */19 #include "usbportability.h"1 /* Name: usbportability.h2 * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers3 * Author: Christian Starkjohann4 * Creation Date: 2008-06-175 * Tabsize: 46 * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH7 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)8 * This Revision: $Id$9 */1011 /*12 General Description:13 This header is intended to contain all (or at least most of) the compiler14 and library dependent stuff. The C code is written for avr-gcc and avr-libc.15 The API of other development environments is converted to gcc's and avr-libc's16 API by means of defines.1718 This header also contains all system includes since they depend on the19 development environment.2021 Thanks to Oleg Semyonov for his help with the IAR tools port!22 */2324 #ifndef __usbportability_h_INCLUDED__25 #define __usbportability_h_INCLUDED__2627 /* We check explicitly for IAR and CodeVision. Default is avr-gcc/avr-libc. */2829 /* ------------------------------------------------------------------------- */30 #if defined __IAR_SYSTEMS_ICC__ || defined __IAR_SYSTEMS_ASM__ /* check for IAR */31 /* ------------------------------------------------------------------------- */3233 #ifndef ENABLE_BIT_DEFINITIONS34 # define ENABLE_BIT_DEFINITIONS 1 /* Enable bit definitions */35 #endif3637 /* Include IAR headers */38 #include <ioavr.h>39 #ifndef __IAR_SYSTEMS_ASM__40 # include <inavr.h>41 #endif4243 #define __attribute__(arg) /* not supported on IAR */4445 #ifdef __IAR_SYSTEMS_ASM__46 # define __ASSEMBLER__ /* IAR does not define standard macro for asm */47 #endif4849 #ifdef __HAS_ELPM__50 # define PROGMEM __farflash51 #else52 # define PROGMEM __flash53 #endif5455 #define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr))5657 /* The following definitions are not needed by the driver, but may be of some58 * help if you port a gcc based project to IAR.59 */60 #define cli() __disable_interrupt()61 #define sei() __enable_interrupt()62 #define wdt_reset() __watchdog_reset()63 #define _BV(x) (1 << (x))6465 /* assembler compatibility macros */66 #define nop2 rjmp $+2 /* jump to next instruction */67 #define XL r2668 #define XH r2769 #define YL r2870 #define YH r2971 #define ZL r3072 #define ZH r3173 #define lo8(x) LOW(x)74 #define hi8(x) (((x)>>8) & 0xff) /* not HIGH to allow XLINK to make a proper range check */7576 /* Depending on the device you use, you may get problems with the way usbdrv.h77 * handles the differences between devices. Since IAR does not use #defines78 * for MCU registers, we can't check for the existence of a particular79 * register with an #ifdef. If the autodetection mechanism fails, include80 * definitions for the required USB_INTR_* macros in your usbconfig.h. See81 * usbconfig-prototype.h and usbdrv.h for details.82 */8384 /* ------------------------------------------------------------------------- */85 #elif __CODEVISIONAVR__ /* check for CodeVision AVR */86 /* ------------------------------------------------------------------------- */87 /* This port is not working (yet) */8889 /* #define F_CPU _MCU_CLOCK_FREQUENCY_ seems to be defined automatically */9091 #include <io.h>92 #include <delay.h>9394 #define __attribute__(arg) /* not supported on IAR */9596 #define PROGMEM __flash97 #define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr))9899 #ifndef __ASSEMBLER__100 static inline void cli(void)101 {102 #asm("cli");103 }104 static inline void sei(void)105 {106 #asm("sei");107 }108 #endif109 #define _delay_ms(t) delay_ms(t)110 #define _BV(x) (1 << (x))111 #define USB_CFG_USE_SWITCH_STATEMENT 1 /* macro for if() cascase fails for unknown reason */112113 #define macro .macro114 #define endm .endmacro115 #define nop2 rjmp .+0 /* jump to next instruction */116117 /* ------------------------------------------------------------------------- */118 #else /* default development environment is avr-gcc/avr-libc */119 /* ------------------------------------------------------------------------- */120121 #include <avr/io.h>1 /* Copyright (c) 2002,2003,2005,2006,2007 Marek Michalkiewicz, Joerg Wunsch2 Copyright (c) 2007 Eric B. Weddington3 All rights reserved.45 Redistribution and use in source and binary forms, with or without6 modification, are permitted provided that the following conditions are met:78 * Redistributions of source code must retain the above copyright9 notice, this list of conditions and the following disclaimer.1011 * Redistributions in binary form must reproduce the above copyright12 notice, this list of conditions and the following disclaimer in13 the documentation and/or other materials provided with the14 distribution.1516 * Neither the name of the copyright holders nor the names of17 contributors may be used to endorse or promote products derived18 from this software without specific prior written permission.1920 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE30 POSSIBILITY OF SUCH DAMAGE. */3132 /* $Id: io.h,v 1.52.2.28 2009/12/20 17:02:53 arcanum Exp $ */3334 /** \file */35 /** \defgroup avr_io <avr/io.h>: AVR device-specific IO definitions36 \code #include <avr/io.h> \endcode3738 This header file includes the apropriate IO definitions for the39 device that has been specified by the <tt>-mmcu=</tt> compiler40 command-line switch. This is done by diverting to the appropriate41 file <tt><avr/io</tt><em>XXXX</em><tt>.h></tt> which should42 never be included directly. Some register names common to all43 AVR devices are defined directly within <tt><avr/common.h></tt>,44 which is included in <tt><avr/io.h></tt>,45 but most of the details come from the respective include file.4647 Note that this file always includes the following files:48 \code49 #include <avr/sfr_defs.h>50 #include <avr/portpins.h>51 #include <avr/common.h>52 #include <avr/version.h>53 \endcode54 See \ref avr_sfr for more details about that header file.5556 Included are definitions of the IO register set and their57 respective bit values as specified in the Atmel documentation.58 Note that inconsistencies in naming conventions,59 so even identical functions sometimes get different names on60 different devices.6162 Also included are the specific names useable for interrupt63 function definitions as documented64 \ref avr_signames "here".6566 Finally, the following macros are defined:6768 - \b RAMEND69 <br>70 The last on-chip RAM address.71 <br>72 - \b XRAMEND73 <br>74 The last possible RAM location that is addressable. This is equal to75 RAMEND for devices that do not allow for external RAM. For devices76 that allow external RAM, this will be larger than RAMEND.77 <br>78 - \b E2END79 <br>80 The last EEPROM address.81 <br>82 - \b FLASHEND83 <br>84 The last byte address in the Flash program space.85 <br>86 - \b SPM_PAGESIZE87 <br>88 For devices with bootloader support, the flash pagesize89 (in bytes) to be used for the \c SPM instruction.90 - \b E2PAGESIZE91 <br>92 The size of the EEPROM page.9394 */9596 #ifndef _AVR_IO_H_97 #define _AVR_IO_H_9899 #include <avr/sfr_defs.h>1 /* Copyright (c) 2002, Marek Michalkiewicz <marekm@amelek.gda.pl>100101 #if defined (__AVR_AT94K__)102 # include <avr/ioat94k.h>103 #elif defined (__AVR_AT43USB320__)104 # include <avr/io43u32x.h>105 #elif defined (__AVR_AT43USB355__)106 # include <avr/io43u35x.h>107 #elif defined (__AVR_AT76C711__)108 # include <avr/io76c711.h>109 #elif defined (__AVR_AT86RF401__)110 # include <avr/io86r401.h>111 #elif defined (__AVR_AT90PWM1__)112 # include <avr/io90pwm1.h>113 #elif defined (__AVR_AT90PWM2__)114 # include <avr/io90pwmx.h>115 #elif defined (__AVR_AT90PWM2B__)116 # include <avr/io90pwm2b.h>117 #elif defined (__AVR_AT90PWM3__)118 # include <avr/io90pwmx.h>119 #elif defined (__AVR_AT90PWM3B__)120 # include <avr/io90pwm3b.h>121 #elif defined (__AVR_AT90PWM216__)122 # include <avr/io90pwm216.h>123 #elif defined (__AVR_AT90PWM316__)124 # include <avr/io90pwm316.h>125 #elif defined (__AVR_AT90PWM81__)126 # include <avr/io90pwm81.h>127 #elif defined (__AVR_ATmega8U2__)128 # include <avr/iom8u2.h>129 #elif defined (__AVR_ATmega16M1__)130 # include <avr/iom16m1.h>131 #elif defined (__AVR_ATmega16U2__)132 # include <avr/iom16u2.h>133 #elif defined (__AVR_ATmega16U4__)134 # include <avr/iom16u4.h>135 #elif defined (__AVR_ATmega32C1__)136 # include <avr/iom32c1.h>137 #elif defined (__AVR_ATmega32M1__)138 # include <avr/iom32m1.h>139 #elif defined (__AVR_ATmega32U2__)140 # include <avr/iom32u2.h>141 #elif defined (__AVR_ATmega32U4__)142 # include <avr/iom32u4.h>143 #elif defined (__AVR_ATmega32U6__)144 # include <avr/iom32u6.h>145 #elif defined (__AVR_ATmega64C1__)146 # include <avr/iom64c1.h>147 #elif defined (__AVR_ATmega64M1__)148 # include <avr/iom64m1.h>149 #elif defined (__AVR_ATmega128__)150 # include <avr/iom128.h>151 #elif defined (__AVR_ATmega1280__)152 # include <avr/iom1280.h>153 #elif defined (__AVR_ATmega1281__)154 # include <avr/iom1281.h>155 #elif defined (__AVR_ATmega1284P__)156 # include <avr/iom1284p.h>157 #elif defined (__AVR_ATmega128RFA1__)158 # include <avr/iom128rfa1.h>159 #elif defined (__AVR_ATmega2560__)160 # include <avr/iom2560.h>161 #elif defined (__AVR_ATmega2561__)162 # include <avr/iom2561.h>163 #elif defined (__AVR_AT90CAN32__)164 # include <avr/iocan32.h>165 #elif defined (__AVR_AT90CAN64__)166 # include <avr/iocan64.h>167 #elif defined (__AVR_AT90CAN128__)168 # include <avr/iocan128.h>169 #elif defined (__AVR_AT90USB82__)170 # include <avr/iousb82.h>171 #elif defined (__AVR_AT90USB162__)172 # include <avr/iousb162.h>173 #elif defined (__AVR_AT90USB646__)174 # include <avr/iousb646.h>175 #elif defined (__AVR_AT90USB647__)176 # include <avr/iousb647.h>177 #elif defined (__AVR_AT90USB1286__)178 # include <avr/iousb1286.h>179 #elif defined (__AVR_AT90USB1287__)180 # include <avr/iousb1287.h>181 #elif defined (__AVR_ATmega64__)182 # include <avr/iom64.h>183 #elif defined (__AVR_ATmega640__)184 # include <avr/iom640.h>185 #elif defined (__AVR_ATmega644__) || defined (__AVR_ATmega644A__)186 # include <avr/iom644.h>187 #elif defined (__AVR_ATmega644P__)188 # include <avr/iom644p.h>189 #elif defined (__AVR_ATmega644PA__)190 # include <avr/iom644pa.h>191 #elif defined (__AVR_ATmega645__) || defined (__AVR_ATmega645A__) || defined (__AVR_ATmega645P__)192 # include <avr/iom645.h>193 #elif defined (__AVR_ATmega6450__) || defined (__AVR_ATmega6450A__) || defined (__AVR_ATmega6450P__194 # include <avr/iom6450.h>195 #elif defined (__AVR_ATmega649__) || defined (__AVR_ATmega649A__)196 # include <avr/iom649.h>197 #elif defined (__AVR_ATmega6490__) || defined (__AVR_ATmega6490A__) || defined (__AVR_ATmega6490P__198 # include <avr/iom6490.h>199 #elif defined (__AVR_ATmega649P__)200 # include <avr/iom649p.h>201 #elif defined (__AVR_ATmega64HVE__)202 # include <avr/iom64hve.h>203 #elif defined (__AVR_ATmega103__)204 # include <avr/iom103.h>205 #elif defined (__AVR_ATmega32__)206 # include <avr/iom32.h>207 #elif defined (__AVR_ATmega323__)208 # include <avr/iom323.h>209 #elif defined (__AVR_ATmega324P__) || defined (__AVR_ATmega324A__)210 # include <avr/iom324.h>211 #elif defined (__AVR_ATmega324PA__)212 # include <avr/iom324pa.h>213 #elif defined (__AVR_ATmega325__)214 # include <avr/iom325.h>215 #elif defined (__AVR_ATmega325P__)216 # include <avr/iom325.h>217 #elif defined (__AVR_ATmega3250__)218 # include <avr/iom3250.h>219 #elif defined (__AVR_ATmega3250P__)220 # include <avr/iom3250.h>221 #elif defined (__AVR_ATmega328P__) || defined (__AVR_ATmega328__)222 # include <avr/iom328p.h>223 #elif defined (__AVR_ATmega329__)224 # include <avr/iom329.h>225 #elif defined (__AVR_ATmega329P__) || defined (__AVR_ATmega329PA__)226 # include <avr/iom329.h>227 #elif defined (__AVR_ATmega3290__)228 # include <avr/iom3290.h>229 #elif defined (__AVR_ATmega3290P__)230 # include <avr/iom3290.h>231 #elif defined (__AVR_ATmega32HVB__)232 # include <avr/iom32hvb.h>233 #elif defined (__AVR_ATmega406__)234 # include <avr/iom406.h>235 #elif defined (__AVR_ATmega16__)236 # include <avr/iom16.h>237 #elif defined (__AVR_ATmega16A__)238 # include <avr/iom16a.h>239 #elif defined (__AVR_ATmega161__)240 # include <avr/iom161.h>241 #elif defined (__AVR_ATmega162__)242 # include <avr/iom162.h>243 #elif defined (__AVR_ATmega163__)244 # include <avr/iom163.h>245 #elif defined (__AVR_ATmega164P__) || defined (__AVR_ATmega164A__)246 # include <avr/iom164.h>247 #elif defined (__AVR_ATmega165__) || defined (__AVR_ATmega165A__)248 # include <avr/iom165.h>249 #elif defined (__AVR_ATmega165P__)250 # include <avr/iom165p.h>251 #elif defined (__AVR_ATmega168__) || defined (__AVR_ATmega168A__)252 # include <avr/iom168.h>253 #elif defined (__AVR_ATmega168P__)254 # include <avr/iom168p.h>255 #elif defined (__AVR_ATmega169__) || defined (__AVR_ATmega169A__)256 # include <avr/iom169.h>257 #elif defined (__AVR_ATmega169P__)258 # include <avr/iom169p.h>259 #elif defined (__AVR_ATmega169PA__)260 # include <avr/iom169pa.h>261 #elif defined (__AVR_ATmega8HVA__)262 # include <avr/iom8hva.h>263 #elif defined (__AVR_ATmega16HVA__)264 # include <avr/iom16hva.h>265 #elif defined (__AVR_ATmega16HVA2__)266 # include <avr/iom16hva2.h>267 #elif defined (__AVR_ATmega16HVB__)268 # include <avr/iom16hvb.h>269 #elif defined (__AVR_ATmega8__)270 # include <avr/iom8.h>271 #elif defined (__AVR_ATmega48__) || defined (__AVR_ATmega48A__)272 # include <avr/iom48.h>273 #elif defined (__AVR_ATmega48P__)274 # include <avr/iom48p.h>275 #elif defined (__AVR_ATmega88__) || defined (__AVR_ATmega88A__)276 # include <avr/iom88.h>277 #elif defined (__AVR_ATmega88P__)278 # include <avr/iom88p.h>279 #elif defined (__AVR_ATmega88PA__)280 # include <avr/iom88pa.h>281 #elif defined (__AVR_ATmega8515__)282 # include <avr/iom8515.h>283 #elif defined (__AVR_ATmega8535__)284 # include <avr/iom8535.h>285 #elif defined (__AVR_AT90S8535__)286 # include <avr/io8535.h>287 #elif defined (__AVR_AT90C8534__)288 # include <avr/io8534.h>289 #elif defined (__AVR_AT90S8515__)290 # include <avr/io8515.h>291 #elif defined (__AVR_AT90S4434__)292 # include <avr/io4434.h>293 #elif defined (__AVR_AT90S4433__)294 # include <avr/io4433.h>295 #elif defined (__AVR_AT90S4414__)296 # include <avr/io4414.h>297 #elif defined (__AVR_ATtiny22__)298 # include <avr/iotn22.h>299 #elif defined (__AVR_ATtiny26__)300 # include <avr/iotn26.h>301 #elif defined (__AVR_AT90S2343__)302 # include <avr/io2343.h>303 #elif defined (__AVR_AT90S2333__)304 # include <avr/io2333.h>305 #elif defined (__AVR_AT90S2323__)306 # include <avr/io2323.h>307 #elif defined (__AVR_AT90S2313__)308 # include <avr/io2313.h>309 #elif defined (__AVR_ATtiny2313__)310 # include <avr/iotn2313.h>311 #elif defined (__AVR_ATtiny2313A__)312 # include <avr/iotn2313a.h>313 #elif defined (__AVR_ATtiny13__)314 # include <avr/iotn13.h>315 #elif defined (__AVR_ATtiny13A__)316 # include <avr/iotn13a.h>317 #elif defined (__AVR_ATtiny25__)318 # include <avr/iotn25.h>319 #elif defined (__AVR_ATtiny4313__)320 # include <avr/iotn4313.h>321 #elif defined (__AVR_ATtiny45__)322 # include <avr/iotn45.h>323 #elif defined (__AVR_ATtiny85__)324 # include <avr/iotn85.h>1 /* Copyright (c) 2005, Joerg Wunsch2 All rights reserved.34 Redistribution and use in source and binary forms, with or without5 modification, are permitted provided that the following conditions are met:67 * Redistributions of source code must retain the above copyright8 notice, this list of conditions and the following disclaimer.910 * Redistributions in binary form must reproduce the above copyright11 notice, this list of conditions and the following disclaimer in12 the documentation and/or other materials provided with the13 distribution.1415 * Neither the name of the copyright holders nor the names of16 contributors may be used to endorse or promote products derived17 from this software without specific prior written permission.1819 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE29 POSSIBILITY OF SUCH DAMAGE. */3031 /* $Id: iotn85.h,v 1.3.2.6 2009/02/11 18:05:33 arcanum Exp $ */3233 /* avr/iotn85.h - definitions for ATtiny85 */3435 #ifndef _AVR_IOTN85_H_36 #define _AVR_IOTN85_H_ 13738 #include <avr/iotnx5.h>1 /* Copyright (c) 2005, 2007, 2009 Anatoly Sokolov39325 #elif defined (__AVR_ATtiny24__)326 # include <avr/iotn24.h>327 #elif defined (__AVR_ATtiny24A__)328 # include <avr/iotn24a.h>329 #elif defined (__AVR_ATtiny44__)330 # include <avr/iotn44.h>331 #elif defined (__AVR_ATtiny44A__)332 # include <avr/iotn44a.h>333 #elif defined (__AVR_ATtiny84__)334 # include <avr/iotn84.h>335 #elif defined (__AVR_ATtiny261__)336 # include <avr/iotn261.h>337 #elif defined (__AVR_ATtiny261A__)338 # include <avr/iotn261a.h>339 #elif defined (__AVR_ATtiny461__)340 # include <avr/iotn461.h>341 #elif defined (__AVR_ATtiny461A__)342 # include <avr/iotn461a.h>343 #elif defined (__AVR_ATtiny861__)344 # include <avr/iotn861.h>345 #elif defined (__AVR_ATtiny861A__)346 # include <avr/iotn861a.h>347 #elif defined (__AVR_ATtiny43U__)348 # include <avr/iotn43u.h>349 #elif defined (__AVR_ATtiny48__)350 # include <avr/iotn48.h>351 #elif defined (__AVR_ATtiny88__)352 # include <avr/iotn88.h>353 #elif defined (__AVR_ATtiny87__)354 # include <avr/iotn87.h>355 #elif defined (__AVR_ATtiny167__)356 # include <avr/iotn167.h>357 #elif defined (__AVR_AT90SCR100__)358 # include <avr/io90scr100.h>359 #elif defined (__AVR_ATxmega16A4__)360 # include <avr/iox16a4.h>361 #elif defined (__AVR_ATxmega16D4__)362 # include <avr/iox16d4.h>363 #elif defined (__AVR_ATxmega32A4__)364 # include <avr/iox32a4.h>365 #elif defined (__AVR_ATxmega32D4__)366 # include <avr/iox32d4.h>367 #elif defined (__AVR_ATxmega64A1__)368 # include <avr/iox64a1.h>369 #elif defined (__AVR_ATxmega64A3__)370 # include <avr/iox64a3.h>371 #elif defined (__AVR_ATxmega64D3__)372 # include <avr/iox64d3.h>373 #elif defined (__AVR_ATxmega128A1__)374 # include <avr/iox128a1.h>375 #elif defined (__AVR_ATxmega128A3__)376 # include <avr/iox128a3.h>377 #elif defined (__AVR_ATxmega128D3__)378 # include <avr/iox128d3.h>379 #elif defined (__AVR_ATxmega192A3__)380 # include <avr/iox192a3.h>381 #elif defined (__AVR_ATxmega192D3__)382 # include <avr/iox192d3.h>383 #elif defined (__AVR_ATxmega256A3__)384 # include <avr/iox256a3.h>385 #elif defined (__AVR_ATxmega256A3B__)386 # include <avr/iox256a3b.h>387 #elif defined (__AVR_ATxmega256D3__)388 # include <avr/iox256d3.h>389 #elif defined (__AVR_ATA6289__)390 # include <avr/ioa6289.h>391 /* avr1: the following only supported for assembler programs */392 #elif defined (__AVR_ATtiny28__)393 # include <avr/iotn28.h>394 #elif defined (__AVR_AT90S1200__)395 # include <avr/io1200.h>396 #elif defined (__AVR_ATtiny15__)397 # include <avr/iotn15.h>398 #elif defined (__AVR_ATtiny12__)399 # include <avr/iotn12.h>400 #elif defined (__AVR_ATtiny11__)401 # include <avr/iotn11.h>402 #else403 # if !defined(__COMPILING_AVR_LIBC__)404 # warning "device type not defined"405 # endif406 #endif407408 #include <avr/portpins.h>1 /* Copyright (c) 2003 Theodore A. Roth409410 #include <avr/common.h>1 /* Copyright (c) 2007 Eric B. Weddington411412 #include <avr/version.h>1 /* Copyright (c) 2005, Joerg Wunsch -*- c -*-413414 /* Include fuse.h after individual IO header files. */415 #include <avr/fuse.h>1 /* Copyright (c) 2007, Atmel Corporation416417 /* Include lock.h after individual IO header files. */418 #include <avr/lock.h>1 /* Copyright (c) 2007, Atmel Corporation419122 avr/pgmspace.h>20 " /* for common defs */1 /* Name: usbdrv.h2 * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers3 * Author: Christian Starkjohann4 * Creation Date: 2004-12-295 * Tabsize: 46 * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH7 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)8 * This Revision: $Id$9 */1011 #ifndef __usbdrv_h_included__12 #define __usbdrv_h_included__13 #include "usbconfig.h"1 /* Name: usbconfig.h14 portability.h"21 /* register names */22 #define x1 r1623 #define x2 r1724 #define shift r1825 #define cnt r1926 #define x3 r2027 #define x4 r2128 #define x5 r2229 #define bitcnt x530 #define phase x431 #define leap x43233 /* Some assembler dependent definitions and declarations: */3435 #ifdef __IAR_SYSTEMS_ASM__36 extern usbRxBuf, usbDeviceAddr, usbNewDeviceAddr, usbInputBufOffset37 extern usbCurrentTok, usbRxLen, usbRxToken, usbTxLen38 extern usbTxBuf, usbTxStatus1, usbTxStatus339 # if USB_COUNT_SOF40 extern usbSofCount41 # endif42 public usbCrc1643 public usbCrc16Append4445 COMMON INTVEC46 # ifndef USB_INTR_VECTOR47 ORG INT0_vect48 # else /* USB_INTR_VECTOR */49 ORG USB_INTR_VECTOR50 # undef USB_INTR_VECTOR51 # endif /* USB_INTR_VECTOR */52 # define USB_INTR_VECTOR usbInterruptHandler53 rjmp USB_INTR_VECTOR54 RSEG CODE5556 #else /* __IAR_SYSTEMS_ASM__ */5758 # ifndef USB_INTR_VECTOR /* default to hardware interrupt INT0 */59 # ifdef INT0_vect60 # define USB_INTR_VECTOR INT0_vect // this is the "new" define for the vector61 # else62 # define USB_INTR_VECTOR SIG_INTERRUPT0 // this is the "old" vector63 # endif64 # endif65 .text66 .global USB_INTR_VECTOR68 .global usbCrc1669 .global usbCrc16Append70 #endif /* __IAR_SYSTEMS_ASM__ */717273 #if USB_INTR_PENDING < 0x40 /* This is an I/O address, use in and out */74 # define USB_LOAD_PENDING(reg) in reg, USB_INTR_PENDING75 # define USB_STORE_PENDING(reg) out USB_INTR_PENDING, reg76 #else /* It's a memory address, use lds and sts */77 # define USB_LOAD_PENDING(reg) lds reg, USB_INTR_PENDING78 # define USB_STORE_PENDING(reg) sts USB_INTR_PENDING, reg79 #endif8081 #define usbTxLen1 usbTxStatus182 #define usbTxBuf1 (usbTxStatus1 + 1)83 #define usbTxLen3 usbTxStatus384 #define usbTxBuf3 (usbTxStatus3 + 1)858687 ;----------------------------------------------------------------------------88 ; Utility functions89 ;----------------------------------------------------------------------------9091 #ifdef __IAR_SYSTEMS_ASM__92 /* Register assignments for usbCrc16 on IAR cc */93 /* Calling conventions on IAR:94 * First parameter passed in r16/r17, second in r18/r19 and so on.95 * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer)96 * Result is passed in r16/r1797 * In case of the "tiny" memory model, pointers are only 8 bit with no98 * padding. We therefore pass argument 1 as "16 bit unsigned".99 */100 RTMODEL "__rt_version", "3"101 /* The line above will generate an error if cc calling conventions change.102 * The value "3" above is valid for IAR 4.10B/W32103 */104 # define argLen r18 /* argument 2 */105 # define argPtrL r16 /* argument 1 */106 # define argPtrH r17 /* argument 1 */107108 # define resCrcL r16 /* result */109 # define resCrcH r17 /* result */110111 # define ptrL ZL112 # define ptrH ZH113 # define ptr Z114 # define byte r22115 # define bitCnt r19116 # define polyL r20117 # define polyH r21118 # define scratch r23119120 #else /* __IAR_SYSTEMS_ASM__ */121 /* Register assignments for usbCrc16 on gcc */122 /* Calling conventions on gcc:123 * First parameter passed in r24/r25, second in r22/23 and so on.124 * Callee must preserve r1-r17, r28/r29125 * Result is passed in r24/r25126 */127 # define argLen r22 /* argument 2 */128 # define argPtrL r24 /* argument 1 */129 # define argPtrH r25 /* argument 1 */130131 # define resCrcL r24 /* result */132 # define resCrcH r25 /* result */133134 # define ptrL XL135 # define ptrH XH136 # define ptr x137 # define byte r18138 # define bitCnt r19139 # define polyL r20140 # define polyH r21141 # define scratch r23142143 #endif144145 #if USB_USE_FAST_CRC146147 ; This implementation is faster, but has bigger code size148 ; Thanks to Slawomir Fras (BoskiDialer) for this code!149 ; It implements the following C pseudo-code:150 ; unsigned table(unsigned char x)151 ; {152 ; unsigned value;153 ;154 ; value = (unsigned)x << 6;155 ; value ^= (unsigned)x << 7;156 ; if(parity(x))157 ; value ^= 0xc001;158 ; return value;159 ; }160 ; unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen)161 ; {162 ; unsigned crc = 0xffff;163 ;164 ; while(argLen--)165 ; crc = table(lo8(crc) ^ *argPtr++) ^ hi8(crc);166 ; return ~crc;167 ; }168169 ; extern unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen);170 ; argPtr r24+25 / r16+r17171 ; argLen r22 / r18172 ; temp variables:173 ; byte r18 / r22174 ; scratch r23175 ; resCrc r24+r25 / r16+r17176 ; ptr X / Z177 usbCrc16:178 mov ptrL, argPtrL179 mov ptrH, argPtrH180 ldi resCrcL, 0xFF181 ldi resCrcH, 0xFF182 rjmp usbCrc16LoopTest183 usbCrc16ByteLoop:184 ld byte, ptr+185 eor resCrcL, byte ; resCrcL is now 'x' in table()186 mov byte, resCrcL ; compute parity of 'x'187 swap byte188 eor byte, resCrcL189 mov scratch, byte190 lsr byte191 lsr byte192 eor byte, scratch193 inc byte194 lsr byte195 andi byte, 1 ; byte is now parity(x)196 mov scratch, resCrcL197 mov resCrcL, resCrcH198 eor resCrcL, byte ; low byte of if(parity(x)) value ^= 0xc001;199 neg byte200 andi byte, 0xc0201 mov resCrcH, byte ; high byte of if(parity(x)) value ^= 0xc001;202 clr byte203 lsr scratch204 ror byte205 eor resCrcH, scratch206 eor resCrcL, byte207 lsr scratch208 ror byte209 eor resCrcH, scratch210 eor resCrcL, byte211 usbCrc16LoopTest:212 subi argLen, 1213 brsh usbCrc16ByteLoop214 com resCrcL215 com resCrcH216 ret217218 #else /* USB_USE_FAST_CRC */219220 ; This implementation is slower, but has less code size221 ;222 ; extern unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen);223 ; argPtr r24+25 / r16+r17224 ; argLen r22 / r18225 ; temp variables:226 ; byte r18 / r22227 ; bitCnt r19228 ; poly r20+r21229 ; scratch r23230 ; resCrc r24+r25 / r16+r17231 ; ptr X / Z232 usbCrc16:233 mov ptrL, argPtrL234:vusb-20120109/usbdrv/usbdrvasm.S **** mov ptrH, argPtrH235:vusb-20120109/usbdrv/usbdrvasm.S **** ldi resCrcL, 0236:vusb-20120109/usbdrv/usbdrvasm.S **** ldi resCrcH, 0237:vusb-20120109/usbdrv/usbdrvasm.S **** ldi polyL, lo8(0xa001)238:vusb-20120109/usbdrv/usbdrvasm.S **** ldi polyH, hi8(0xa001)239:vusb-20120109/usbdrv/usbdrvasm.S **** com argLen ; argLen = -argLen - 1: modified loop to ensure that carry is set240:vusb-20120109/usbdrv/usbdrvasm.S **** ldi bitCnt, 0 ; loop counter with starnd condition = end condition241:vusb-20120109/usbdrv/usbdrvasm.S **** rjmp usbCrcLoopEntry242:vusb-20120109/usbdrv/usbdrvasm.S **** usbCrcByteLoop:243 ld byte, ptr+244:vusb-20120109/usbdrv/usbdrvasm.S **** eor resCrcL, byte245:vusb-20120109/usbdrv/usbdrvasm.S **** usbCrcBitLoop:246 ror resCrcH ; carry is always set here (see brcs jumps to here)247:vusb-20120109/usbdrv/usbdrvasm.S **** ror resCrcL248:vusb-20120109/usbdrv/usbdrvasm.S **** brcs usbCrcNoXor249:vusb-20120109/usbdrv/usbdrvasm.S **** eor resCrcL, polyL250:vusb-20120109/usbdrv/usbdrvasm.S **** eor resCrcH, polyH251:vusb-20120109/usbdrv/usbdrvasm.S **** usbCrcNoXor:252 subi bitCnt, 224 ; (8 * 224) % 256 = 0; this loop iterates 8 times253:vusb-20120109/usbdrv/usbdrvasm.S **** brcs usbCrcBitLoop254:vusb-20120109/usbdrv/usbdrvasm.S **** usbCrcLoopEntry:255 subi argLen, -1256:vusb-20120109/usbdrv/usbdrvasm.S **** brcs usbCrcByteLoop257:vusb-20120109/usbdrv/usbdrvasm.S **** usbCrcReady:258 ret259:vusb-20120109/usbdrv/usbdrvasm.S **** ; Thanks to Reimar Doeffinger for optimizing this CRC routine!260261 #endif /* USB_USE_FAST_CRC */262263 ; extern unsigned usbCrc16Append(unsigned char *data, unsigned char len);264 usbCrc16Append:265 rcall usbCrc16266:vusb-20120109/usbdrv/usbdrvasm.S **** st ptr+, resCrcL267:vusb-20120109/usbdrv/usbdrvasm.S **** st ptr+, resCrcH268:vusb-20120109/usbdrv/usbdrvasm.S **** ret269:vusb-20120109/usbdrv/usbdrvasm.S ****270 #undef argLen271 #undef argPtrL272 #undef argPtrH273 #undef resCrcL274 #undef resCrcH275 #undef ptrL276 #undef ptrH277 #undef ptr278 #undef byte279 #undef bitCnt280 #undef polyL281 #undef polyH282 #undef scratch283284285 #if USB_CFG_HAVE_MEASURE_FRAME_LENGTH286 #ifdef __IAR_SYSTEMS_ASM__287 /* Register assignments for usbMeasureFrameLength on IAR cc */288 /* Calling conventions on IAR:289 * First parameter passed in r16/r17, second in r18/r19 and so on.290 * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer)291 * Result is passed in r16/r17292 * In case of the "tiny" memory model, pointers are only 8 bit with no293 * padding. We therefore pass argument 1 as "16 bit unsigned".294 */295 # define resL r16296 # define resH r17297 # define cnt16L r30298 # define cnt16H r31299 # define cntH r18300301 #else /* __IAR_SYSTEMS_ASM__ */302 /* Register assignments for usbMeasureFrameLength on gcc */303 /* Calling conventions on gcc:304 * First parameter passed in r24/r25, second in r22/23 and so on.305 * Callee must preserve r1-r17, r28/r29306 * Result is passed in r24/r25307 */308 # define resL r24309 # define resH r25310 # define cnt16L r24311 # define cnt16H r25312 # define cntH r26313 #endif314 # define cnt16 cnt16L315316 ; extern unsigned usbMeasurePacketLength(void);317 ; returns time between two idle strobes in multiples of 7 CPU clocks318 .global usbMeasureFrameLength319 usbMeasureFrameLength:320 ldi cntH, 6 ; wait ~ 10 ms for D- == 0321:vusb-20120109/usbdrv/usbdrvasm.S **** clr cnt16L322:vusb-20120109/usbdrv/usbdrvasm.S **** clr cnt16H323:vusb-20120109/usbdrv/usbdrvasm.S **** usbMFTime16:324 dec cntH325:vusb-20120109/usbdrv/usbdrvasm.S **** breq usbMFTimeout326:vusb-20120109/usbdrv/usbdrvasm.S **** usbMFWaitStrobe: ; first wait for D- == 0 (idle strobe)327 sbiw cnt16, 1 ;[0] [6]328:vusb-20120109/usbdrv/usbdrvasm.S **** breq usbMFTime16 ;[2]329:vusb-20120109/usbdrv/usbdrvasm.S **** sbic USBIN, USBMINUS ;[3]330:vusb-20120109/usbdrv/usbdrvasm.S **** rjmp usbMFWaitStrobe ;[4]331:vusb-20120109/usbdrv/usbdrvasm.S **** usbMFWaitIdle: ; then wait until idle again332 sbis USBIN, USBMINUS ;1 wait for D- == 1333:vusb-20120109/usbdrv/usbdrvasm.S **** rjmp usbMFWaitIdle ;2334:vusb-20120109/usbdrv/usbdrvasm.S **** ldi cnt16L, 1 ;1 represents cycles so far335:vusb-20120109/usbdrv/usbdrvasm.S **** clr cnt16H ;1336:vusb-20120109/usbdrv/usbdrvasm.S **** usbMFWaitLoop:337 in cntH, USBIN ;[0] [7]338:vusb-20120109/usbdrv/usbdrvasm.S **** adiw cnt16, 1 ;[1]339:vusb-20120109/usbdrv/usbdrvasm.S **** breq usbMFTimeout ;[3]340:vusb-20120109/usbdrv/usbdrvasm.S **** andi cntH, USBMASK ;[4]341:vusb-20120109/usbdrv/usbdrvasm.S **** brne usbMFWaitLoop ;[5]342:vusb-20120109/usbdrv/usbdrvasm.S **** usbMFTimeout:343 #if resL != cnt16L344 mov resL, cnt16L345 mov resH, cnt16H346 #endif347 ret348:vusb-20120109/usbdrv/usbdrvasm.S ****349 #undef resL350 #undef resH351 #undef cnt16352 #undef cnt16L353 #undef cnt16H354 #undef cntH355356 #endif /* USB_CFG_HAVE_MEASURE_FRAME_LENGTH */357358 ;----------------------------------------------------------------------------359 ; Now include the clock rate specific code360 ;----------------------------------------------------------------------------361362 #ifndef USB_CFG_CLOCK_KHZ363 # ifdef F_CPU364 # define USB_CFG_CLOCK_KHZ (F_CPU/1000)365 # else366 # error "USB_CFG_CLOCK_KHZ not defined in usbconfig.h and no F_CPU set!"367 # endif368 #endif369370 #if USB_CFG_CHECK_CRC /* separate dispatcher for CRC type modules */371 # if USB_CFG_CLOCK_KHZ == 18000372 # include "usbdrvasm18-crc.inc"373 # else374 # error "USB_CFG_CLOCK_KHZ is not one of the supported crc-rates!"375 # endif376 #else /* USB_CFG_CHECK_CRC */377 # if USB_CFG_CLOCK_KHZ == 12000378 # include "usbdrvasm12.inc"379 # elif USB_CFG_CLOCK_KHZ == 12800380 # include "usbdrvasm128.inc"381 # elif USB_CFG_CLOCK_KHZ == 15000382 # include "usbdrvasm15.inc"383 # elif USB_CFG_CLOCK_KHZ == 16000384 # include "usbdrvasm16.inc"385 # elif USB_CFG_CLOCK_KHZ == 16500386 # include "usbdrvasm165.inc"387 # elif USB_CFG_CLOCK_KHZ == 200001 /* Name: usbdrvasm165.inc2 * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers3 * Author: Christian Starkjohann4 * Creation Date: 2007-04-225 * Tabsize: 46 * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH7 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)8 * Revision: $Id$9 */1011 /* Do not link this file! Link usbdrvasm.S instead, which includes the12 * appropriate implementation!13 */1415 /*16 General Description:17 This file is the 16.5 MHz version of the USB driver. It is intended for the18 ATTiny45 and similar controllers running on 16.5 MHz internal RC oscillator.19 This version contains a phase locked loop in the receiver routine to cope with20 slight clock rate deviations of up to +/- 1%.2122 See usbdrv.h for a description of the entire driver.2324 Since almost all of this code is timing critical, don't change unless you25 really know what you are doing! Many parts require not only a maximum number26 of CPU cycles, but even an exact number of cycles!27 */2829 ;Software-receiver engine. Strict timing! Don't change unless you can preserve timing!30 ;interrupt response time: 4 cycles + insn running = 7 max if interrupts always enabled31 ;max allowable interrupt latency: 59 cycles -> max 52 cycles interrupt disable32 ;max stack usage: [ret(2), r0, SREG, YL, YH, shift, x1, x2, x3, x4, cnt] = 12 bytes33 ;nominal frequency: 16.5 MHz -> 11 cycles per bit34 ; 16.3125 MHz < F_CPU < 16.6875 MHz (+/- 1.1%)35 ; Numbers in brackets are clocks counted from center of last sync bit36 ; when instruction starts373839 USB_INTR_VECTOR:40 ;order of registers pushed: YL, SREG [sofError], r0, YH, shift, x1, x2, x3, x4, cnt41:vusb-20120109/usbdrv/usbdrvasm165.inc **** push YL ;[-23] push only what is necessary to sync with edge ASAP42:vusb-20120109/usbdrv/usbdrvasm165.inc **** in YL, SREG ;[-21]43:vusb-20120109/usbdrv/usbdrvasm165.inc **** push YL ;[-20]44 ;----------------------------------------------------------------------------45 ; Synchronize with sync pattern:46 ;----------------------------------------------------------------------------47 ;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]48 ;sync up with J to K edge during sync pattern -- use fastest possible loops49 ;The first part waits at most 1 bit long since we must be in sync pattern.50 ;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to51 ;waitForJ, ensure that this prerequisite is met.52 waitForJ:53:vusb-20120109/usbdrv/usbdrvasm165.inc **** inc YL54:vusb-20120109/usbdrv/usbdrvasm165.inc **** sbis USBIN, USBMINUS55:vusb-20120109/usbdrv/usbdrvasm165.inc **** brne waitForJ ; just make sure we have ANY timeout56 waitForK:57 ;The following code results in a sampling window of < 1/4 bit which meets the spec.58:vusb-20120109/usbdrv/usbdrvasm165.inc **** sbis USBIN, USBMINUS ;[-15]59:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp foundK ;[-14]60:vusb-20120109/usbdrv/usbdrvasm165.inc **** sbis USBIN, USBMINUS61:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp foundK62:vusb-20120109/usbdrv/usbdrvasm165.inc **** sbis USBIN, USBMINUS63:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp foundK64:vusb-20120109/usbdrv/usbdrvasm165.inc **** sbis USBIN, USBMINUS65:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp foundK66:vusb-20120109/usbdrv/usbdrvasm165.inc **** sbis USBIN, USBMINUS67:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp foundK68:vusb-20120109/usbdrv/usbdrvasm165.inc **** sbis USBIN, USBMINUS69:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp foundK70 #if USB_COUNT_SOF71:vusb-20120109/usbdrv/usbdrvasm165.inc **** lds YL, usbSofCount72:vusb-20120109/usbdrv/usbdrvasm165.inc **** inc YL73:vusb-20120109/usbdrv/usbdrvasm165.inc **** sts usbSofCount, YL74:vusb-20120109/usbdrv/usbdrvasm165.inc **** #endif /* USB_COUNT_SOF */75:vusb-20120109/usbdrv/usbdrvasm165.inc **** #ifdef USB_SOF_HOOK76:vusb-20120109/usbdrv/usbdrvasm165.inc **** USB_SOF_HOOK77:vusb-20120109/usbdrv/usbdrvasm165.inc **** #endif78:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp sofError79 foundK: ;[-12]80 ;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling]81 ;we have 1 bit time for setup purposes, then sample again. Numbers in brackets82 ;are cycles from center of first sync (double K) bit after the instruction83:vusb-20120109/usbdrv/usbdrvasm165.inc **** push r0 ;[-12]84 ; [---] ;[-11]85:vusb-20120109/usbdrv/usbdrvasm165.inc **** push YH ;[-10]86 ; [---] ;[-9]87:vusb-20120109/usbdrv/usbdrvasm165.inc **** lds YL, usbInputBufOffset;[-8]88 ; [---] ;[-7]89:vusb-20120109/usbdrv/usbdrvasm165.inc **** clr YH ;[-6]90:vusb-20120109/usbdrv/usbdrvasm165.inc **** subi YL, lo8(-(usbRxBuf));[-5] [rx loop init]91:vusb-20120109/usbdrv/usbdrvasm165.inc **** sbci YH, hi8(-(usbRxBuf));[-4] [rx loop init]92:vusb-20120109/usbdrv/usbdrvasm165.inc **** mov r0, x2 ;[-3] [rx loop init]93:vusb-20120109/usbdrv/usbdrvasm165.inc **** sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early)94:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp haveTwoBitsK ;[-1]95:vusb-20120109/usbdrv/usbdrvasm165.inc **** pop YH ;[0] undo the pushes from before96:vusb-20120109/usbdrv/usbdrvasm165.inc **** pop r0 ;[2]97:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp waitForK ;[4] this was not the end of sync, retry98 ; The entire loop from waitForK until rjmp waitForK above must not exceed two99 ; bit times (= 22 cycles).100101 ;----------------------------------------------------------------------------102 ; push more registers and initialize values while we sample the first bits:103 ;----------------------------------------------------------------------------104 haveTwoBitsK: ;[1]105:vusb-20120109/usbdrv/usbdrvasm165.inc **** push shift ;[1]106:vusb-20120109/usbdrv/usbdrvasm165.inc **** push x1 ;[3]107:vusb-20120109/usbdrv/usbdrvasm165.inc **** push x2 ;[5]108:vusb-20120109/usbdrv/usbdrvasm165.inc **** push x3 ;[7]109:vusb-20120109/usbdrv/usbdrvasm165.inc **** ldi shift, 0xff ;[9] [rx loop init]110:vusb-20120109/usbdrv/usbdrvasm165.inc **** ori x3, 0xff ;[10] [rx loop init] == ser x3, clear zero flag111112:vusb-20120109/usbdrv/usbdrvasm165.inc **** in x1, USBIN ;[11] <-- sample bit 0113:vusb-20120109/usbdrv/usbdrvasm165.inc **** bst x1, USBMINUS ;[12]114:vusb-20120109/usbdrv/usbdrvasm165.inc **** bld shift, 0 ;[13]115:vusb-20120109/usbdrv/usbdrvasm165.inc **** push x4 ;[14] == phase116 ; [---] ;[15]117:vusb-20120109/usbdrv/usbdrvasm165.inc **** push cnt ;[16]118 ; [---] ;[17]119:vusb-20120109/usbdrv/usbdrvasm165.inc **** ldi phase, 0 ;[18] [rx loop init]120:vusb-20120109/usbdrv/usbdrvasm165.inc **** ldi cnt, USB_BUFSIZE;[19] [rx loop init]121:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp rxbit1 ;[20]122 ; [---] ;[21]123124 ;----------------------------------------------------------------------------125 ; Receiver loop (numbers in brackets are cycles within byte after instr)126 ;----------------------------------------------------------------------------127 /*128 byte oriented operations done during loop:129 bit 0: store data130 bit 1: SE0 check131 bit 2: overflow check132 bit 3: catch up133 bit 4: rjmp to achieve conditional jump range134 bit 5: PLL135 bit 6: catch up136 bit 7: jump, fixup bitstuff137 ; 87 [+ 2] cycles138 ------------------------------------------------------------------139 */140 continueWithBit5:141:vusb-20120109/usbdrv/usbdrvasm165.inc **** in x2, USBIN ;[055] <-- bit 5142:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor r0, x2 ;[056]143:vusb-20120109/usbdrv/usbdrvasm165.inc **** or phase, r0 ;[057]144:vusb-20120109/usbdrv/usbdrvasm165.inc **** sbrc phase, USBMINUS ;[058]145:vusb-20120109/usbdrv/usbdrvasm165.inc **** lpm ;[059] optional nop3; modifies r0146:vusb-20120109/usbdrv/usbdrvasm165.inc **** in phase, USBIN ;[060] <-- phase147:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor x1, x2 ;[061]148:vusb-20120109/usbdrv/usbdrvasm165.inc **** bst x1, USBMINUS ;[062]149:vusb-20120109/usbdrv/usbdrvasm165.inc **** bld shift, 5 ;[063]150:vusb-20120109/usbdrv/usbdrvasm165.inc **** andi shift, 0x3f ;[064]151:vusb-20120109/usbdrv/usbdrvasm165.inc **** in x1, USBIN ;[065] <-- bit 6152:vusb-20120109/usbdrv/usbdrvasm165.inc **** breq unstuff5 ;[066] *** unstuff escape153:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor phase, x1 ;[067]154:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor x2, x1 ;[068]155:vusb-20120109/usbdrv/usbdrvasm165.inc **** bst x2, USBMINUS ;[069]156:vusb-20120109/usbdrv/usbdrvasm165.inc **** bld shift, 6 ;[070]157 didUnstuff6: ;[ ]158:vusb-20120109/usbdrv/usbdrvasm165.inc **** in r0, USBIN ;[071] <-- phase159:vusb-20120109/usbdrv/usbdrvasm165.inc **** cpi shift, 0x02 ;[072]160:vusb-20120109/usbdrv/usbdrvasm165.inc **** brlo unstuff6 ;[073] *** unstuff escape161 didUnstuff5: ;[ ]162:vusb-20120109/usbdrv/usbdrvasm165.inc **** nop2 ;[074]163 ; [---] ;[075]164:vusb-20120109/usbdrv/usbdrvasm165.inc **** in x2, USBIN ;[076] <-- bit 7165:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor x1, x2 ;[077]166:vusb-20120109/usbdrv/usbdrvasm165.inc **** bst x1, USBMINUS ;[078]167:vusb-20120109/usbdrv/usbdrvasm165.inc **** bld shift, 7 ;[079]168 didUnstuff7: ;[ ]169:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor r0, x2 ;[080]170:vusb-20120109/usbdrv/usbdrvasm165.inc **** or phase, r0 ;[081]171:vusb-20120109/usbdrv/usbdrvasm165.inc **** in r0, USBIN ;[082] <-- phase172:vusb-20120109/usbdrv/usbdrvasm165.inc **** cpi shift, 0x04 ;[083]173:vusb-20120109/usbdrv/usbdrvasm165.inc **** brsh rxLoop ;[084]174 ; [---] ;[085]175 unstuff7: ;[ ]176:vusb-20120109/usbdrv/usbdrvasm165.inc **** andi x3, ~0x80 ;[085]177:vusb-20120109/usbdrv/usbdrvasm165.inc **** ori shift, 0x80 ;[086]178:vusb-20120109/usbdrv/usbdrvasm165.inc **** in x2, USBIN ;[087] <-- sample stuffed bit 7179:vusb-20120109/usbdrv/usbdrvasm165.inc **** nop ;[088]180:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp didUnstuff7 ;[089]181 ; [---] ;[090]182 ;[080]183184 unstuff5: ;[067]185:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor phase, x1 ;[068]186:vusb-20120109/usbdrv/usbdrvasm165.inc **** andi x3, ~0x20 ;[069]187:vusb-20120109/usbdrv/usbdrvasm165.inc **** ori shift, 0x20 ;[070]188:vusb-20120109/usbdrv/usbdrvasm165.inc **** in r0, USBIN ;[071] <-- phase189:vusb-20120109/usbdrv/usbdrvasm165.inc **** mov x2, x1 ;[072]190:vusb-20120109/usbdrv/usbdrvasm165.inc **** nop ;[073]191:vusb-20120109/usbdrv/usbdrvasm165.inc **** nop2 ;[074]192 ; [---] ;[075]193:vusb-20120109/usbdrv/usbdrvasm165.inc **** in x1, USBIN ;[076] <-- bit 6194:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor r0, x1 ;[077]195:vusb-20120109/usbdrv/usbdrvasm165.inc **** or phase, r0 ;[078]196:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor x2, x1 ;[079]197:vusb-20120109/usbdrv/usbdrvasm165.inc **** bst x2, USBMINUS ;[080]198:vusb-20120109/usbdrv/usbdrvasm165.inc **** bld shift, 6 ;[081] no need to check bitstuffing, we just had one199:vusb-20120109/usbdrv/usbdrvasm165.inc **** in r0, USBIN ;[082] <-- phase200:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp didUnstuff5 ;[083]201 ; [---] ;[084]202 ;[074]203204 unstuff6: ;[074]205:vusb-20120109/usbdrv/usbdrvasm165.inc **** andi x3, ~0x40 ;[075]206:vusb-20120109/usbdrv/usbdrvasm165.inc **** in x1, USBIN ;[076] <-- bit 6 again207:vusb-20120109/usbdrv/usbdrvasm165.inc **** ori shift, 0x40 ;[077]208:vusb-20120109/usbdrv/usbdrvasm165.inc **** nop2 ;[078]209 ; [---] ;[079]210:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp didUnstuff6 ;[080]211 ; [---] ;[081]212 ;[071]213214 unstuff0: ;[013]215:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor r0, x2 ;[014]216:vusb-20120109/usbdrv/usbdrvasm165.inc **** or phase, r0 ;[015]217:vusb-20120109/usbdrv/usbdrvasm165.inc **** andi x2, USBMASK ;[016] check for SE0218:vusb-20120109/usbdrv/usbdrvasm165.inc **** in r0, USBIN ;[017] <-- phase219:vusb-20120109/usbdrv/usbdrvasm165.inc **** breq didUnstuff0 ;[018] direct jump to se0 would be too long220:vusb-20120109/usbdrv/usbdrvasm165.inc **** andi x3, ~0x01 ;[019]221:vusb-20120109/usbdrv/usbdrvasm165.inc **** ori shift, 0x01 ;[020]222:vusb-20120109/usbdrv/usbdrvasm165.inc **** mov x1, x2 ;[021] mov existing sample223:vusb-20120109/usbdrv/usbdrvasm165.inc **** in x2, USBIN ;[022] <-- bit 1 again224:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp didUnstuff0 ;[023]225 ; [---] ;[024]226 ;[014]227228 unstuff1: ;[024]229:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor r0, x1 ;[025]230:vusb-20120109/usbdrv/usbdrvasm165.inc **** or phase, r0 ;[026]231:vusb-20120109/usbdrv/usbdrvasm165.inc **** andi x3, ~0x02 ;[027]232:vusb-20120109/usbdrv/usbdrvasm165.inc **** in r0, USBIN ;[028] <-- phase233:vusb-20120109/usbdrv/usbdrvasm165.inc **** ori shift, 0x02 ;[029]234:vusb-20120109/usbdrv/usbdrvasm165.inc **** mov x2, x1 ;[030]235:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp didUnstuff1 ;[031]236 ; [---] ;[032]237 ;[022]238239 unstuff2: ;[035]240:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor r0, x2 ;[036]241:vusb-20120109/usbdrv/usbdrvasm165.inc **** or phase, r0 ;[037]242:vusb-20120109/usbdrv/usbdrvasm165.inc **** andi x3, ~0x04 ;[038]243:vusb-20120109/usbdrv/usbdrvasm165.inc **** in r0, USBIN ;[039] <-- phase244:vusb-20120109/usbdrv/usbdrvasm165.inc **** ori shift, 0x04 ;[040]245:vusb-20120109/usbdrv/usbdrvasm165.inc **** mov x1, x2 ;[041]246:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp didUnstuff2 ;[042]247 ; [---] ;[043]248 ;[033]249250 unstuff3: ;[043]251:vusb-20120109/usbdrv/usbdrvasm165.inc **** in x2, USBIN ;[044] <-- bit 3 again252:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor r0, x2 ;[045]253:vusb-20120109/usbdrv/usbdrvasm165.inc **** or phase, r0 ;[046]254:vusb-20120109/usbdrv/usbdrvasm165.inc **** andi x3, ~0x08 ;[047]255:vusb-20120109/usbdrv/usbdrvasm165.inc **** ori shift, 0x08 ;[048]256:vusb-20120109/usbdrv/usbdrvasm165.inc **** nop ;[049]257:vusb-20120109/usbdrv/usbdrvasm165.inc **** in r0, USBIN ;[050] <-- phase258:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp didUnstuff3 ;[051]259 ; [---] ;[052]260 ;[042]261262 unstuff4: ;[053]263:vusb-20120109/usbdrv/usbdrvasm165.inc **** andi x3, ~0x10 ;[054]264:vusb-20120109/usbdrv/usbdrvasm165.inc **** in x1, USBIN ;[055] <-- bit 4 again265:vusb-20120109/usbdrv/usbdrvasm165.inc **** ori shift, 0x10 ;[056]266:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp didUnstuff4 ;[057]267 ; [---] ;[058]268 ;[048]269270 rxLoop: ;[085]271:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor x3, shift ;[086] reconstruct: x3 is 0 at bit locations we changed, 1 at others272:vusb-20120109/usbdrv/usbdrvasm165.inc **** in x1, USBIN ;[000] <-- bit 0273:vusb-20120109/usbdrv/usbdrvasm165.inc **** st y+, x3 ;[001]274 ; [---] ;[002]275:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor r0, x1 ;[003]276:vusb-20120109/usbdrv/usbdrvasm165.inc **** or phase, r0 ;[004]277:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor x2, x1 ;[005]278:vusb-20120109/usbdrv/usbdrvasm165.inc **** in r0, USBIN ;[006] <-- phase279:vusb-20120109/usbdrv/usbdrvasm165.inc **** ser x3 ;[007]280:vusb-20120109/usbdrv/usbdrvasm165.inc **** bst x2, USBMINUS ;[008]281:vusb-20120109/usbdrv/usbdrvasm165.inc **** bld shift, 0 ;[009]282:vusb-20120109/usbdrv/usbdrvasm165.inc **** andi shift, 0xf9 ;[010]283 rxbit1: ;[ ]284:vusb-20120109/usbdrv/usbdrvasm165.inc **** in x2, USBIN ;[011] <-- bit 1285:vusb-20120109/usbdrv/usbdrvasm165.inc **** breq unstuff0 ;[012] *** unstuff escape286:vusb-20120109/usbdrv/usbdrvasm165.inc **** andi x2, USBMASK ;[013] SE0 check for bit 1287 didUnstuff0: ;[ ] Z only set if we detected SE0 in bitstuff288:vusb-20120109/usbdrv/usbdrvasm165.inc **** breq se0 ;[014]289:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor r0, x2 ;[015]290:vusb-20120109/usbdrv/usbdrvasm165.inc **** or phase, r0 ;[016]291:vusb-20120109/usbdrv/usbdrvasm165.inc **** in r0, USBIN ;[017] <-- phase292:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor x1, x2 ;[018]293:vusb-20120109/usbdrv/usbdrvasm165.inc **** bst x1, USBMINUS ;[019]294:vusb-20120109/usbdrv/usbdrvasm165.inc **** bld shift, 1 ;[020]295:vusb-20120109/usbdrv/usbdrvasm165.inc **** andi shift, 0xf3 ;[021]296 didUnstuff1: ;[ ]297:vusb-20120109/usbdrv/usbdrvasm165.inc **** in x1, USBIN ;[022] <-- bit 2298:vusb-20120109/usbdrv/usbdrvasm165.inc **** breq unstuff1 ;[023] *** unstuff escape299:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor r0, x1 ;[024]300:vusb-20120109/usbdrv/usbdrvasm165.inc **** or phase, r0 ;[025]301:vusb-20120109/usbdrv/usbdrvasm165.inc **** subi cnt, 1 ;[026] overflow check302:vusb-20120109/usbdrv/usbdrvasm165.inc **** brcs overflow ;[027]303:vusb-20120109/usbdrv/usbdrvasm165.inc **** in r0, USBIN ;[028] <-- phase304:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor x2, x1 ;[029]305:vusb-20120109/usbdrv/usbdrvasm165.inc **** bst x2, USBMINUS ;[030]306:vusb-20120109/usbdrv/usbdrvasm165.inc **** bld shift, 2 ;[031]307:vusb-20120109/usbdrv/usbdrvasm165.inc **** andi shift, 0xe7 ;[032]308 didUnstuff2: ;[ ]309:vusb-20120109/usbdrv/usbdrvasm165.inc **** in x2, USBIN ;[033] <-- bit 3310:vusb-20120109/usbdrv/usbdrvasm165.inc **** breq unstuff2 ;[034] *** unstuff escape311:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor r0, x2 ;[035]312:vusb-20120109/usbdrv/usbdrvasm165.inc **** or phase, r0 ;[036]313:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor x1, x2 ;[037]314:vusb-20120109/usbdrv/usbdrvasm165.inc **** bst x1, USBMINUS ;[038]315:vusb-20120109/usbdrv/usbdrvasm165.inc **** in r0, USBIN ;[039] <-- phase316:vusb-20120109/usbdrv/usbdrvasm165.inc **** bld shift, 3 ;[040]317:vusb-20120109/usbdrv/usbdrvasm165.inc **** andi shift, 0xcf ;[041]318 didUnstuff3: ;[ ]319:vusb-20120109/usbdrv/usbdrvasm165.inc **** breq unstuff3 ;[042] *** unstuff escape320:vusb-20120109/usbdrv/usbdrvasm165.inc **** nop ;[043]321:vusb-20120109/usbdrv/usbdrvasm165.inc **** in x1, USBIN ;[044] <-- bit 4322:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor x2, x1 ;[045]323:vusb-20120109/usbdrv/usbdrvasm165.inc **** bst x2, USBMINUS ;[046]324:vusb-20120109/usbdrv/usbdrvasm165.inc **** bld shift, 4 ;[047]325 didUnstuff4: ;[ ]326:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor r0, x1 ;[048]327:vusb-20120109/usbdrv/usbdrvasm165.inc **** or phase, r0 ;[049]328:vusb-20120109/usbdrv/usbdrvasm165.inc **** in r0, USBIN ;[050] <-- phase329:vusb-20120109/usbdrv/usbdrvasm165.inc **** andi shift, 0x9f ;[051]330:vusb-20120109/usbdrv/usbdrvasm165.inc **** breq unstuff4 ;[052] *** unstuff escape331:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp continueWithBit5;[053]332 ; [---] ;[054]333334 macro POP_STANDARD ; 16 cycles335 pop cnt336 pop x4337 pop x3338 pop x2339 pop x1340 pop shift341 pop YH342 pop r0343 endm344 macro POP_RETI ; 5 cycles345 pop YL346 out SREG, YL347 pop YL348 endm349350 #include "asmcommon.inc"1 /* Name: asmcommon.inc2 * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers3 * Author: Christian Starkjohann4 * Creation Date: 2007-11-055 * Tabsize: 46 * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH7 * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)8 * Revision: $Id$9 */1011 /* Do not link this file! Link usbdrvasm.S instead, which includes the12 * appropriate implementation!13 */1415 /*16 General Description:17 This file contains assembler code which is shared among the USB driver18 implementations for different CPU cocks. Since the code must be inserted19 in the middle of the module, it's split out into this file and #included.2021 Jump destinations called from outside:22 sofError: Called when no start sequence was found.23 se0: Called when a package has been successfully received.24 overflow: Called when receive buffer overflows.25 doReturn: Called after sending data.2627 Outside jump destinations used by this module:28 waitForJ: Called to receive an already arriving packet.29 sendAckAndReti:30 sendNakAndReti:31 sendCntAndReti:32 usbSendAndReti:3334 The following macros must be defined before this file is included:35 .macro POP_STANDARD36 .endm37 .macro POP_RETI38 .endm39 */4041 #define token x14243 overflow:44:vusb-20120109/usbdrv/asmcommon.inc **** ldi x2, 1<<USB_INTR_PENDING_BIT45:vusb-20120109/usbdrv/asmcommon.inc **** USB_STORE_PENDING(x2) ; clear any pending interrupts46 ignorePacket:47:vusb-20120109/usbdrv/asmcommon.inc **** clr token48:vusb-20120109/usbdrv/asmcommon.inc **** rjmp storeTokenAndReturn4950 ;----------------------------------------------------------------------------51 ; Processing of received packet (numbers in brackets are cycles after center of SE0)52 ;----------------------------------------------------------------------------53 ;This is the only non-error exit point for the software receiver loop54 ;we don't check any CRCs here because there is no time left.55 se0:56:vusb-20120109/usbdrv/asmcommon.inc **** subi cnt, USB_BUFSIZE ;[5]57:vusb-20120109/usbdrv/asmcommon.inc **** neg cnt ;[6]58:vusb-20120109/usbdrv/asmcommon.inc **** sub YL, cnt ;[7]59:vusb-20120109/usbdrv/asmcommon.inc **** sbci YH, 0 ;[8]60:vusb-20120109/usbdrv/asmcommon.inc **** ldi x2, 1<<USB_INTR_PENDING_BIT ;[9]61:vusb-20120109/usbdrv/asmcommon.inc **** USB_STORE_PENDING(x2) ;[10] clear pending intr and check flag later. SE0 should be over.62:vusb-20120109/usbdrv/asmcommon.inc **** ld token, y ;[11]63:vusb-20120109/usbdrv/asmcommon.inc **** cpi token, USBPID_DATA0 ;[13]64:vusb-20120109/usbdrv/asmcommon.inc **** breq handleData ;[14]65:vusb-20120109/usbdrv/asmcommon.inc **** cpi token, USBPID_DATA1 ;[15]66:vusb-20120109/usbdrv/asmcommon.inc **** breq handleData ;[16]67:vusb-20120109/usbdrv/asmcommon.inc **** lds shift, usbDeviceAddr;[17]68:vusb-20120109/usbdrv/asmcommon.inc **** ldd x2, y+1 ;[19] ADDR and 1 bit endpoint number69:vusb-20120109/usbdrv/asmcommon.inc **** lsl x2 ;[21] shift out 1 bit endpoint number70:vusb-20120109/usbdrv/asmcommon.inc **** cpse x2, shift ;[22]71:vusb-20120109/usbdrv/asmcommon.inc **** rjmp ignorePacket ;[23]72 /* only compute endpoint number in x3 if required later */73 #if USB_CFG_HAVE_INTRIN_ENDPOINT || USB_CFG_IMPLEMENT_FN_WRITEOUT74:vusb-20120109/usbdrv/asmcommon.inc **** ldd x3, y+2 ;[24] endpoint number + crc75:vusb-20120109/usbdrv/asmcommon.inc **** rol x3 ;[26] shift in LSB of endpoint76 #endif77:vusb-20120109/usbdrv/asmcommon.inc **** cpi token, USBPID_IN ;[27]78:vusb-20120109/usbdrv/asmcommon.inc **** breq handleIn ;[28]79:vusb-20120109/usbdrv/asmcommon.inc **** cpi token, USBPID_SETUP ;[29]80:vusb-20120109/usbdrv/asmcommon.inc **** breq handleSetupOrOut ;[30]81:vusb-20120109/usbdrv/asmcommon.inc **** cpi token, USBPID_OUT ;[31]82:vusb-20120109/usbdrv/asmcommon.inc **** brne ignorePacket ;[32] must be ack, nak or whatever83 ; rjmp handleSetupOrOut ; fallthrough8485 ;Setup and Out are followed by a data packet two bit times (16 cycles) after86 ;the end of SE0. The sync code allows up to 40 cycles delay from the start of87 ;the sync pattern until the first bit is sampled. That's a total of 56 cycles.88 handleSetupOrOut: ;[32]89 #if USB_CFG_IMPLEMENT_FN_WRITEOUT /* if we have data for endpoint != 0, set usbCurrentTok to addr90 andi x3, 0xf ;[32]91 breq storeTokenAndReturn ;[33]92 mov token, x3 ;[34] indicate that this is endpoint x OUT93 #endif94 storeTokenAndReturn:95:vusb-20120109/usbdrv/asmcommon.inc **** sts usbCurrentTok, token;[35]96 doReturn:97:vusb-20120109/usbdrv/asmcommon.inc **** POP_STANDARD ;[37] 12...16 cycles98:vusb-20120109/usbdrv/asmcommon.inc **** USB_LOAD_PENDING(YL) ;[49]99:vusb-20120109/usbdrv/asmcommon.inc **** sbrc YL, USB_INTR_PENDING_BIT;[50] check whether data is already arriving100:vusb-20120109/usbdrv/asmcommon.inc **** rjmp waitForJ ;[51] save the pops and pushes -- a new interrupt is already pendin101 sofError:102:vusb-20120109/usbdrv/asmcommon.inc **** POP_RETI ;macro call103:vusb-20120109/usbdrv/asmcommon.inc **** reti104105 handleData:106 #if USB_CFG_CHECK_CRC107 CRC_CLEANUP_AND_CHECK ; jumps to ignorePacket if CRC error108 #endif109:vusb-20120109/usbdrv/asmcommon.inc **** lds shift, usbCurrentTok;[18]110:vusb-20120109/usbdrv/asmcommon.inc **** tst shift ;[20]111:vusb-20120109/usbdrv/asmcommon.inc **** breq doReturn ;[21]112:vusb-20120109/usbdrv/asmcommon.inc **** lds x2, usbRxLen ;[22]113:vusb-20120109/usbdrv/asmcommon.inc **** tst x2 ;[24]114:vusb-20120109/usbdrv/asmcommon.inc **** brne sendNakAndReti ;[25]115 ; 2006-03-11: The following two lines fix a problem where the device was not116 ; recognized if usbPoll() was called less frequently than once every 4 ms.117:vusb-20120109/usbdrv/asmcommon.inc **** cpi cnt, 4 ;[26] zero sized data packets are status phase only -- ignore and a118:vusb-20120109/usbdrv/asmcommon.inc **** brmi sendAckAndReti ;[27] keep rx buffer clean -- we must not NAK next SETUP119 #if USB_CFG_CHECK_DATA_TOGGLING120 sts usbCurrentDataToken, token ; store for checking by C code121 #endif122:vusb-20120109/usbdrv/asmcommon.inc **** sts usbRxLen, cnt ;[28] store received data, swap buffers123:vusb-20120109/usbdrv/asmcommon.inc **** sts usbRxToken, shift ;[30]124:vusb-20120109/usbdrv/asmcommon.inc **** lds x2, usbInputBufOffset;[32] swap buffers125:vusb-20120109/usbdrv/asmcommon.inc **** ldi cnt, USB_BUFSIZE ;[34]126:vusb-20120109/usbdrv/asmcommon.inc **** sub cnt, x2 ;[35]127:vusb-20120109/usbdrv/asmcommon.inc **** sts usbInputBufOffset, cnt;[36] buffers now swapped128:vusb-20120109/usbdrv/asmcommon.inc **** rjmp sendAckAndReti ;[38] 40 + 17 = 57 until SOP129130 handleIn:131 ;We don't send any data as long as the C code has not processed the current132 ;input data and potentially updated the output data. That's more efficient133 ;in terms of code size than clearing the tx buffers when a packet is received.134:vusb-20120109/usbdrv/asmcommon.inc **** lds x1, usbRxLen ;[30]135:vusb-20120109/usbdrv/asmcommon.inc **** cpi x1, 1 ;[32] negative values are flow control, 0 means "buffer free"136:vusb-20120109/usbdrv/asmcommon.inc **** brge sendNakAndReti ;[33] unprocessed input packet?137:vusb-20120109/usbdrv/asmcommon.inc **** ldi x1, USBPID_NAK ;[34] prepare value for usbTxLen138 #if USB_CFG_HAVE_INTRIN_ENDPOINT139:vusb-20120109/usbdrv/asmcommon.inc **** andi x3, 0xf ;[35] x3 contains endpoint140 #if USB_CFG_SUPPRESS_INTR_CODE141 brne sendNakAndReti ;[36]142 #else143:vusb-20120109/usbdrv/asmcommon.inc **** brne handleIn1 ;[36]144 #endif145 #endif146:vusb-20120109/usbdrv/asmcommon.inc **** lds cnt, usbTxLen ;[37]147:vusb-20120109/usbdrv/asmcommon.inc **** sbrc cnt, 4 ;[39] all handshake tokens have bit 4 set148:vusb-20120109/usbdrv/asmcommon.inc **** rjmp sendCntAndReti ;[40] 42 + 16 = 58 until SOP149:vusb-20120109/usbdrv/asmcommon.inc **** sts usbTxLen, x1 ;[41] x1 == USBPID_NAK from above150:vusb-20120109/usbdrv/asmcommon.inc **** ldi YL, lo8(usbTxBuf) ;[43]151:vusb-20120109/usbdrv/asmcommon.inc **** ldi YH, hi8(usbTxBuf) ;[44]152:vusb-20120109/usbdrv/asmcommon.inc **** rjmp usbSendAndReti ;[45] 57 + 12 = 59 until SOP153154 ; Comment about when to set usbTxLen to USBPID_NAK:155 ; We should set it back when we receive the ACK from the host. This would156 ; be simple to implement: One static variable which stores whether the last157 ; tx was for endpoint 0 or 1 and a compare in the receiver to distinguish the158 ; ACK. However, we set it back immediately when we send the package,159 ; assuming that no error occurs and the host sends an ACK. We save one byte160 ; RAM this way and avoid potential problems with endless retries. The rest of161 ; the driver assumes error-free transfers anyway.162163 #if !USB_CFG_SUPPRESS_INTR_CODE && USB_CFG_HAVE_INTRIN_ENDPOINT /* placed here due to relative jump164 handleIn1: ;[38]165 #if USB_CFG_HAVE_INTRIN_ENDPOINT3166 ; 2006-06-10 as suggested by O.Tamura: support second INTR IN / BULK IN endpoint167 cpi x3, USB_CFG_EP3_NUMBER;[38]168 breq handleIn3 ;[39]169 #endif170:vusb-20120109/usbdrv/asmcommon.inc **** lds cnt, usbTxLen1 ;[40]171:vusb-20120109/usbdrv/asmcommon.inc **** sbrc cnt, 4 ;[42] all handshake tokens have bit 4 set172:vusb-20120109/usbdrv/asmcommon.inc **** rjmp sendCntAndReti ;[43] 47 + 16 = 63 until SOP173:vusb-20120109/usbdrv/asmcommon.inc **** sts usbTxLen1, x1 ;[44] x1 == USBPID_NAK from above174:vusb-20120109/usbdrv/asmcommon.inc **** ldi YL, lo8(usbTxBuf1) ;[46]175:vusb-20120109/usbdrv/asmcommon.inc **** ldi YH, hi8(usbTxBuf1) ;[47]176:vusb-20120109/usbdrv/asmcommon.inc **** rjmp usbSendAndReti ;[48] 50 + 12 = 62 until SOP177351 = (D+ = 0), (D- = 1)352 ; K = (D+ = 1), (D- = 0)353 ; Spec allows 7.5 bit times from EOP to SOP for replies354355 bitstuff7:356 eor x1, x4 ;[4]357 ldi x2, 0 ;[5]358 nop2 ;[6] C is zero (brcc)359 rjmp didStuff7 ;[8]360:vusb-20120109/usbdrv/usbdrvasm165.inc ****361:vusb-20120109/usbdrv/usbdrvasm165.inc **** bitstuffN:362:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor x1, x4 ;[5]363:vusb-20120109/usbdrv/usbdrvasm165.inc **** ldi x2, 0 ;[6]364 lpm ;[7] 3 cycle NOP, modifies r0365 out USBOUT, x1 ;[10] <-- out366:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp didStuffN ;[0]367:vusb-20120109/usbdrv/usbdrvasm165.inc ****368:vusb-20120109/usbdrv/usbdrvasm165.inc **** #define bitStatus x3369:vusb-20120109/usbdrv/usbdrvasm165.inc ****370:vusb-20120109/usbdrv/usbdrvasm165.inc **** sendNakAndReti:371 ldi cnt, USBPID_NAK ;[-19]372 rjmp sendCntAndReti ;[-18]373 sendAckAndReti:374 ldi cnt, USBPID_ACK ;[-17]375:vusb-20120109/usbdrv/usbdrvasm165.inc **** sendCntAndReti:376:vusb-20120109/usbdrv/usbdrvasm165.inc **** mov r0, cnt ;[-16]377 ldi YL, 0 ;[-15] R0 address is 0378:vusb-20120109/usbdrv/usbdrvasm165.inc **** ldi YH, 0 ;[-14]379 ldi cnt, 2 ;[-13]380:vusb-20120109/usbdrv/usbdrvasm165.inc **** ; rjmp usbSendAndReti fallthrough381:vusb-20120109/usbdrv/usbdrvasm165.inc ****382:vusb-20120109/usbdrv/usbdrvasm165.inc **** ;usbSend:383:vusb-20120109/usbdrv/usbdrvasm165.inc **** ;pointer to data in 'Y'384 ;number of bytes in 'cnt' -- including sync byte [range 2 ... 12]385 ;uses: x1...x4, shift, cnt, Y386 ;Numbers in brackets are time since first bit of sync pattern is sent387 usbSendAndReti: ; 12 cycles until SOP388 in x2, USBDDR ;[-12]389 ori x2, USBMASK ;[-11]390 sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups)391 in x1, USBOUT ;[-8] port mirror for tx loop392:vusb-20120109/usbdrv/usbdrvasm165.inc **** out USBDDR, x2 ;[-7] <- acquire bus393:vusb-20120109/usbdrv/usbdrvasm165.inc **** ; need not init x2 (bitstuff history) because sync starts with 0394:vusb-20120109/usbdrv/usbdrvasm165.inc **** ldi x4, USBMASK ;[-6] exor mask395:vusb-20120109/usbdrv/usbdrvasm165.inc **** ldi shift, 0x80 ;[-5] sync byte is first byte sent396:vusb-20120109/usbdrv/usbdrvasm165.inc **** ldi bitStatus, 0xff ;[-4] init bit loop counter, works for up to 12 bytes397 byteloop:398:vusb-20120109/usbdrv/usbdrvasm165.inc **** bitloop:399:vusb-20120109/usbdrv/usbdrvasm165.inc **** sbrs shift, 0 ;[8] [-3]400:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor x1, x4 ;[9] [-2]401 out USBOUT, x1 ;[10] [-1] <-- out402 ror shift ;[0]403:vusb-20120109/usbdrv/usbdrvasm165.inc **** ror x2 ;[1]404:vusb-20120109/usbdrv/usbdrvasm165.inc **** didStuffN:405:vusb-20120109/usbdrv/usbdrvasm165.inc **** cpi x2, 0xfc ;[2]406:vusb-20120109/usbdrv/usbdrvasm165.inc **** brcc bitstuffN ;[3]407:vusb-20120109/usbdrv/usbdrvasm165.inc **** nop ;[4]408 subi bitStatus, 37 ;[5] 256 / 7 ~=~ 37409:vusb-20120109/usbdrv/usbdrvasm165.inc **** brcc bitloop ;[6] when we leave the loop, bitStatus has almost the initial value410:vusb-20120109/usbdrv/usbdrvasm165.inc **** sbrs shift, 0 ;[7]411:vusb-20120109/usbdrv/usbdrvasm165.inc **** eor x1, x4 ;[8]412:vusb-20120109/usbdrv/usbdrvasm165.inc **** ror shift ;[9]413:vusb-20120109/usbdrv/usbdrvasm165.inc **** didStuff7:414:vusb-20120109/usbdrv/usbdrvasm165.inc **** out USBOUT, x1 ;[10] <-- out415:vusb-20120109/usbdrv/usbdrvasm165.inc **** ror x2 ;[0]416:vusb-20120109/usbdrv/usbdrvasm165.inc **** cpi x2, 0xfc ;[1]417 brcc bitstuff7 ;[2]418:vusb-20120109/usbdrv/usbdrvasm165.inc **** ld shift, y+ ;[3]419:vusb-20120109/usbdrv/usbdrvasm165.inc **** dec cnt ;[5]420:vusb-20120109/usbdrv/usbdrvasm165.inc **** brne byteloop ;[6]421:vusb-20120109/usbdrv/usbdrvasm165.inc **** ;make SE0:422:vusb-20120109/usbdrv/usbdrvasm165.inc **** cbr x1, USBMASK ;[7] prepare SE0 [spec says EOP may be 21 to 25 cycles]423:vusb-20120109/usbdrv/usbdrvasm165.inc **** lds x2, usbNewDeviceAddr;[8]424:vusb-20120109/usbdrv/usbdrvasm165.inc **** lsl x2 ;[10] we compare with left shifted address425 out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle426:vusb-20120109/usbdrv/usbdrvasm165.inc **** ;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:427:vusb-20120109/usbdrv/usbdrvasm165.inc **** ;set address only after data packet was sent, not after handshake428:vusb-20120109/usbdrv/usbdrvasm165.inc **** subi YL, 2 ;[0] Only assign address on data packets, not ACK/NAK in r0429:vusb-20120109/usbdrv/usbdrvasm165.inc **** sbci YH, 0 ;[1]430 breq skipAddrAssign ;[2]431 sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer432:vusb-20120109/usbdrv/usbdrvasm165.inc **** skipAddrAssign:433:vusb-20120109/usbdrv/usbdrvasm165.inc **** ;end of usbDeviceAddress transfer434:vusb-20120109/usbdrv/usbdrvasm165.inc **** ldi x2, 1<<USB_INTR_PENDING_BIT;[4] int0 occurred during TX -- clear pending flag435:vusb-20120109/usbdrv/usbdrvasm165.inc **** USB_STORE_PENDING(x2) ;[5]436 ori x1, USBIDLE ;[6]437 in x2, USBDDR ;[7]438:vusb-20120109/usbdrv/usbdrvasm165.inc **** cbr x2, USBMASK ;[8] set both pins to input439:vusb-20120109/usbdrv/usbdrvasm165.inc **** mov x3, x1 ;[9]440:vusb-20120109/usbdrv/usbdrvasm165.inc **** cbr x3, USBMASK ;[10] configure no pullup on both pins441:vusb-20120109/usbdrv/usbdrvasm165.inc **** ldi x4, 4 ;[11]442:vusb-20120109/usbdrv/usbdrvasm165.inc **** se0Delay:443:vusb-20120109/usbdrv/usbdrvasm165.inc **** dec x4 ;[12] [15] [18] [21]444:vusb-20120109/usbdrv/usbdrvasm165.inc **** brne se0Delay ;[13] [16] [19] [22]445:vusb-20120109/usbdrv/usbdrvasm165.inc **** out USBOUT, x1 ;[23] <-- out J (idle) -- end of SE0 (EOP signal)446 out USBDDR, x2 ;[24] <-- release bus now447:vusb-20120109/usbdrv/usbdrvasm165.inc **** out USBOUT, x3 ;[25] <-- ensure no pull-up resistors are active448:vusb-20120109/usbdrv/usbdrvasm165.inc **** rjmp doReturn449:vusb-20120109/usbdrv/usbdrvasm165.inc ****450:vusb-20120109/usbdrv/usbdrvasm165.inc **** ...DEFINED SYMBOLSvusb-20120109/usbdrv/usbdrvasm165.inc:39 .text:00000058 __vector_1vusb-20120109/usbdrv/usbdrvasm.S:233 .text:00000000 usbCrc16vusb-20120109/usbdrv/usbdrvasm.S:265 .text:0000002a usbCrc16Appendvusb-20120109/usbdrv/usbdrvasm.S:255 .text:00000024 usbCrcLoopEntryvusb-20120109/usbdrv/usbdrvasm.S:243 .text:00000012 usbCrcByteLoopvusb-20120109/usbdrv/usbdrvasm.S:246 .text:00000016 usbCrcBitLoopvusb-20120109/usbdrv/usbdrvasm.S:252 .text:00000020 usbCrcNoXorvusb-20120109/usbdrv/usbdrvasm.S:258 .text:00000028 usbCrcReadyvusb-20120109/usbdrv/usbdrvasm.S:320 .text:00000032 usbMeasureFrameLengthvusb-20120109/usbdrv/usbdrvasm.S:324 .text:00000038 usbMFTime16vusb-20120109/usbdrv/usbdrvasm.S:343 .text:00000056 usbMFTimeoutvusb-20120109/usbdrv/usbdrvasm.S:327 .text:0000003c usbMFWaitStrobevusb-20120109/usbdrv/usbdrvasm.S:332 .text:00000044 usbMFWaitIdlevusb-20120109/usbdrv/usbdrvasm.S:337 .text:0000004c usbMFWaitLoopvusb-20120109/usbdrv/usbdrvasm165.inc:52 .text:0000005e waitForJvusb-20120109/usbdrv/usbdrvasm165.inc:56 .text:00000064 waitForKvusb-20120109/usbdrv/usbdrvasm165.inc:79 .text:0000007e foundKvusb-20120109/usbdrv/asmcommon.inc:101 .text:00000228 sofErrorvusb-20120109/usbdrv/usbdrvasm165.inc:104 .text:00000098 haveTwoBitsKvusb-20120109/usbdrv/usbdrvasm165.inc:283 .text:0000017e rxbit1vusb-20120109/usbdrv/usbdrvasm165.inc:140 .text:000000b4 continueWithBit5vusb-20120109/usbdrv/usbdrvasm165.inc:184 .text:000000f8 unstuff5vusb-20120109/usbdrv/usbdrvasm165.inc:157 .text:000000d4 didUnstuff6vusb-20120109/usbdrv/usbdrvasm165.inc:204 .text:00000116 unstuff6vusb-20120109/usbdrv/usbdrvasm165.inc:161 .text:000000da didUnstuff5vusb-20120109/usbdrv/usbdrvasm165.inc:168 .text:000000e4 didUnstuff7vusb-20120109/usbdrv/usbdrvasm165.inc:270 .text:00000168 rxLoopvusb-20120109/usbdrv/usbdrvasm165.inc:175 .text:000000ee unstuff7vusb-20120109/usbdrv/usbdrvasm165.inc:214 .text:00000120 unstuff0vusb-20120109/usbdrv/usbdrvasm165.inc:287 .text:00000184 didUnstuff0vusb-20120109/usbdrv/usbdrvasm165.inc:228 .text:00000134 unstuff1vusb-20120109/usbdrv/usbdrvasm165.inc:296 .text:00000194 didUnstuff1vusb-20120109/usbdrv/usbdrvasm165.inc:239 .text:00000142 unstuff2vusb-20120109/usbdrv/usbdrvasm165.inc:308 .text:000001aa didUnstuff2vusb-20120109/usbdrv/usbdrvasm165.inc:250 .text:00000150 unstuff3vusb-20120109/usbdrv/usbdrvasm165.inc:318 .text:000001bc didUnstuff3vusb-20120109/usbdrv/usbdrvasm165.inc:262 .text:00000160 unstuff4vusb-20120109/usbdrv/usbdrvasm165.inc:325 .text:000001c8 didUnstuff4vusb-20120109/usbdrv/asmcommon.inc:55 .text:000001dc se0vusb-20120109/usbdrv/asmcommon.inc:43 .text:000001d4 overflowvusb-20120109/usbdrv/asmcommon.inc:46 .text:000001d8 ignorePacketvusb-20120109/usbdrv/asmcommon.inc:94 .text:0000020e storeTokenAndReturnvusb-20120109/usbdrv/asmcommon.inc:105 .text:00000230 handleDatavusb-20120109/usbdrv/asmcommon.inc:130 .text:0000025a handleInvusb-20120109/usbdrv/asmcommon.inc:88 .text:0000020e handleSetupOrOutvusb-20120109/usbdrv/asmcommon.inc:96 .text:00000212 doReturnvusb-20120109/usbdrv/usbdrvasm165.inc:374 .text:0000029e sendNakAndRetivusb-20120109/usbdrv/usbdrvasm165.inc:377 .text:000002a2 sendAckAndRetivusb-20120109/usbdrv/asmcommon.inc:164 .text:0000027a handleIn1vusb-20120109/usbdrv/usbdrvasm165.inc:379 .text:000002a4 sendCntAndRetivusb-20120109/usbdrv/usbdrvasm165.inc:391 .text:000002ac usbSendAndRetivusb-20120109/usbdrv/usbdrvasm165.inc:359 .text:0000028c bitstuff7vusb-20120109/usbdrv/usbdrvasm165.inc:417 .text:000002d6 didStuff7vusb-20120109/usbdrv/usbdrvasm165.inc:365 .text:00000294 bitstuffNvusb-20120109/usbdrv/usbdrvasm165.inc:408 .text:000002c6 didStuffNvusb-20120109/usbdrv/usbdrvasm165.inc:401 .text:000002bc byteloopvusb-20120109/usbdrv/usbdrvasm165.inc:402 .text:000002bc bitloopvusb-20120109/usbdrv/usbdrvasm165.inc:436 .text:000002f8 skipAddrAssignvusb-20120109/usbdrv/usbdrvasm165.inc:446 .text:00000308 se0DelayUNDEFINED SYMBOLSusbInputBufOffsetusbRxBufusbDeviceAddrusbCurrentTokusbRxLenusbRxTokenusbTxLenusbTxBufusbTxStatus1usbNewDeviceAddr