diff options
Diffstat (limited to 'usbdrv')
-rw-r--r-- | usbdrv/usbdrvasm128.inc | 64 |
1 files changed, 49 insertions, 15 deletions
diff --git a/usbdrv/usbdrvasm128.inc b/usbdrv/usbdrvasm128.inc index 9424f07..6144cbf 100644 --- a/usbdrv/usbdrvasm128.inc +++ b/usbdrv/usbdrvasm128.inc @@ -1,8 +1,36 @@ +/* Name: usbdrvasm128.inc + * Project: AVR USB driver + * Author: Christian Starkjohann + * Creation Date: 2008-10-11 + * Tabsize: 4 + * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH + * License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt) + * This Revision: $Id$ + */ -/***************************************************************************** +/* Do not link this file! Link usbdrvasm.S instead, which includes the + * appropriate implementation! + */ + +/* +General Description: +This file is the 12.8 MHz version of the USB driver. It is intended for use +with the internal RC oscillator. Although 12.8 MHz is outside the guaranteed +calibration range of the oscillator, almost all AVRs can reach this frequency. +This version contains a phase locked loop in the receiver routine to cope with +slight clock rate deviations of up to +/- 1%. + +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! + +Implementation notes: +====================== min frequency: 67 cycles for 8 bit -> 12.5625 MHz -max frequency: 69.666 cycles for 8 bit -> 13.0625 MHz -nominal frequency: 12.81 MHz ( = sqrt(min * max)) +max frequency: 69.286 cycles for 8 bit -> 12.99 MHz +nominal frequency: 12.77 MHz ( = sqrt(min * max)) sampling positions: (next even number in range [+/- 0.5]) cycle index range: 0 ... 66 @@ -10,19 +38,18 @@ bits: .5, 8.875, 17.25, 25.625, 34, 42.375, 50.75, 59.125 [0/1], [9], [17], [25/+26], [34], [+42/43], [51], [59] - bit number: 0 1 2 3 4 5 6 7 spare cycles 1 2 1 2 1 1 1 0 operations to perform: duration cycle ---------------- - eor x3, shift 1 -> 00 + eor fix, shift 1 -> 00 andi phase, USBMASK 1 -> 08 breq se0 1 -> 16 (moved to 11) - st y+, x3 2 -> 24, 25 - mov x3, x4 1 -> 33 - ser x4 1 -> 41 - dec cnt 1 -> 49 + st y+, data 2 -> 24, 25 + mov data, fix 1 -> 33 + ser data 1 -> 41 + subi cnt, 1 1 -> 49 brcs overflow 1 -> 50 layout of samples and operations: @@ -41,13 +68,21 @@ layout of samples and operations: *****************************************************************************/ /* we prefer positive expressions (do if condition) instead of negative - * (skip if condition), therefore use defines for skip instructions + * (skip if condition), therefore use defines for skip instructions: */ #define ifioclr sbis #define ifioset sbic #define ifrclr sbrs #define ifrset sbrc +/* The registers "fix" and "data" swap their meaning during the loop. Use + * defines to keep their name constant. + */ +#define fix x2 +#define data x1 +#undef phase /* phase has a default definition to x4 */ +#define phase x3 + USB_INTR_VECTOR: ;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt, r0 @@ -82,9 +117,6 @@ waitForK: #endif /* USB_COUNT_SOF */ rjmp sofError -#undef phase -#define phase x3 - foundK: ;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling] ;we have 1 bit time for setup purposes, then sample again. Numbers in brackets @@ -125,7 +157,7 @@ haveTwoBitsK: ifioset USBIN, USBMINUS ;[17] <--- bit 2 ori data, 3<<2 ;[18] store in bit 2 AND bit 3 eor shift, data ;[19] do nrzi decoding - andi data, 1<<USBMINUS ;[20] + andi data, 1<<3 ;[20] in phase, USBIN ;[21] <- phase brne jumpToEntryAfterSet ;[22] if USBMINS at bit 3 was 1 nop ;[23] @@ -492,7 +524,7 @@ txBitloop: stuffN1Delay: ; [03] ror shift ;[-5] [11] [63] brcc doExorN1 ;[-4] [64] - subi x4, 1 ;[-3] + subi x3, 1 ;[-3] brne commonN1 ;[-2] lsl shift ;[-1] compensate ror after rjmp stuffDelay nop ;[00] stuffing consists of just waiting 8 cycles @@ -608,6 +640,8 @@ skipAddrAssign: out USBOUT, x3 ;[18] <-- ensure no pull-up resistors are active rjmp doReturn + + /***************************************************************************** The following PHP script generates a code skeleton for the receiver routine: |