/* Name: usbdrvasm20.inc * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers * Author: Jeroen Benschop * Based on usbdrvasm16.inc from Christian Starkjohann * Creation Date: 2008-03-05 * Tabsize: 4 * Copyright: (c) 2008 by Jeroen Benschop and OBJECTIVE DEVELOPMENT Software GmbH * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) * TinyAvr1 TinyAvr0 code port by: 12oClocker */ /* Do not link this file! Link usbdrvasm.S instead, which includes the * appropriate implementation! */ /* General Description: This file is the 20 MHz version of the asssembler part of the USB driver. It requires a 20 MHz crystal (not a ceramic resonator and not a calibrated RC oscillator). See usbdrv.h for a description of the entire driver. Since almost all of this code is timing critical, don't change unless you really know what you are doing! Many parts require not only a maximum number of CPU cycles, but even an exact number of cycles! ,----Likely to cause the most issues with TinyAvr0 TinyAvr1 series... | --AVR---|--TinyAvr-- CPU cycle differences for opcodes X push 2 push 1 X cbi 2 cbi 1 X sbi 2 sbi 1 X st 2 st 1,2 1 cycles for SRAM, 2 cycles for FLASH or EEPROM X std 2 std 1,2 1 cycles for SRAM, 2 cycles for FLASH or EEPROM sts 2 sts 2,3 only different if NOT reading from SRAM X lds 2 lds 3,4 3 cycles for SRAM, 4 cycles for FLASH or EEPROM ld 2 ld 2,3 only different if NOT reading from SRAM ldd 2 ldd 2,3 only different if NOT reading from SRAM ret 4 ret 4,5 only different if NOT reading from SRAM reti 4 reti 4,5 only different if NOT reading from SRAM icall 3 icall 2,3 rcall 3 rcall 2,3 */ #define leap2 x3 #ifdef __IAR_SYSTEMS_ASM__ #define nextInst $+2 #else #define nextInst .+0 #endif ;max stack usage: [ret(2), YL, SREG, YH, bitcnt, shift, x1, x2, x3, x4, cnt] = 12 bytes ;nominal frequency: 20 MHz -> 13.333333 cycles per bit, 106.666667 cycles per byte ; Numbers in brackets are clocks counted from center of last sync bit ; when instruction starts ;register use in receive loop: ; shift assembles the byte currently being received ; x1 holds the D+ and D- line state ; x2 holds the previous line state ; x4 (leap) is used to add a leap cycle once every three bytes received ; X3 (leap2) is used to add a leap cycle once every three stuff bits received ; bitcnt is used to determine when a stuff bit is due ; cnt holds the number of bytes left in the receive buffer USB_INTR_VECTOR: ;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt #if USB_CFG_TINYAVR_SERIES == 1 push YL ;[-28] push only what is necessary to sync with edge ASAP ldi YL, (1<