added protocol stack: pjrc, vusb
This commit is contained in:
		
							parent
							
								
									5552b5afea
								
							
						
					
					
						commit
						acc974c64b
					
				
					 55 changed files with 836 additions and 1832 deletions
				
			
		
							
								
								
									
										393
									
								
								vusb/usbdrv/usbdrvasm.S
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										393
									
								
								vusb/usbdrv/usbdrvasm.S
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,393 @@ | |||
| /* Name: usbdrvasm.S | ||||
|  * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers | ||||
|  * Author: Christian Starkjohann | ||||
|  * Creation Date: 2007-06-13 | ||||
|  * Tabsize: 4 | ||||
|  * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH | ||||
|  * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) | ||||
|  * Revision: $Id: usbdrvasm.S 785 2010-05-30 17:57:07Z cs $ | ||||
|  */ | ||||
| 
 | ||||
| /* | ||||
| General Description: | ||||
| This module is the assembler part of the USB driver. This file contains | ||||
| general code (preprocessor acrobatics and CRC computation) and then includes | ||||
| the file appropriate for the given clock rate. | ||||
| */ | ||||
| 
 | ||||
| #define __SFR_OFFSET 0      /* used by avr-libc's register definitions */ | ||||
| #include "usbportability.h" | ||||
| #include "usbdrv.h"         /* for common defs */ | ||||
| 
 | ||||
| /* register names */ | ||||
| #define x1      r16 | ||||
| #define x2      r17 | ||||
| #define shift   r18 | ||||
| #define cnt     r19 | ||||
| #define x3      r20 | ||||
| #define x4      r21 | ||||
| #define x5		r22 | ||||
| #define bitcnt  x5 | ||||
| #define phase   x4 | ||||
| #define leap    x4 | ||||
| 
 | ||||
| /* Some assembler dependent definitions and declarations: */ | ||||
| 
 | ||||
| #ifdef __IAR_SYSTEMS_ASM__ | ||||
|     extern  usbRxBuf, usbDeviceAddr, usbNewDeviceAddr, usbInputBufOffset | ||||
|     extern  usbCurrentTok, usbRxLen, usbRxToken, usbTxLen | ||||
|     extern  usbTxBuf, usbTxStatus1, usbTxStatus3 | ||||
| #   if USB_COUNT_SOF | ||||
|         extern usbSofCount | ||||
| #   endif | ||||
|     public  usbCrc16 | ||||
|     public  usbCrc16Append | ||||
| 
 | ||||
|     COMMON  INTVEC | ||||
| #   ifndef USB_INTR_VECTOR | ||||
|         ORG     INT0_vect | ||||
| #   else /* USB_INTR_VECTOR */ | ||||
|         ORG     USB_INTR_VECTOR | ||||
| #       undef   USB_INTR_VECTOR | ||||
| #   endif /* USB_INTR_VECTOR */ | ||||
| #   define  USB_INTR_VECTOR usbInterruptHandler | ||||
|     rjmp    USB_INTR_VECTOR | ||||
|     RSEG    CODE | ||||
| 
 | ||||
| #else /* __IAR_SYSTEMS_ASM__ */ | ||||
| 
 | ||||
| #   ifndef USB_INTR_VECTOR /* default to hardware interrupt INT0 */ | ||||
| #       ifdef INT0_vect | ||||
| #           define USB_INTR_VECTOR  INT0_vect       // this is the "new" define for the vector | ||||
| #       else | ||||
| #           define USB_INTR_VECTOR  SIG_INTERRUPT0  // this is the "old" vector | ||||
| #       endif | ||||
| #   endif | ||||
|     .text | ||||
|     .global USB_INTR_VECTOR
 | ||||
|     .type   USB_INTR_VECTOR, @function
 | ||||
|     .global usbCrc16
 | ||||
|     .global usbCrc16Append
 | ||||
| #endif /* __IAR_SYSTEMS_ASM__ */ | ||||
| 
 | ||||
| 
 | ||||
| #if USB_INTR_PENDING < 0x40 /* This is an I/O address, use in and out */ | ||||
| #   define  USB_LOAD_PENDING(reg)   in reg, USB_INTR_PENDING | ||||
| #   define  USB_STORE_PENDING(reg)  out USB_INTR_PENDING, reg | ||||
| #else   /* It's a memory address, use lds and sts */ | ||||
| #   define  USB_LOAD_PENDING(reg)   lds reg, USB_INTR_PENDING | ||||
| #   define  USB_STORE_PENDING(reg)  sts USB_INTR_PENDING, reg | ||||
| #endif | ||||
| 
 | ||||
| #define usbTxLen1   usbTxStatus1 | ||||
| #define usbTxBuf1   (usbTxStatus1 + 1) | ||||
| #define usbTxLen3   usbTxStatus3 | ||||
| #define usbTxBuf3   (usbTxStatus3 + 1) | ||||
| 
 | ||||
| 
 | ||||
| ;----------------------------------------------------------------------------
 | ||||
| ; Utility functions
 | ||||
| ;----------------------------------------------------------------------------
 | ||||
| 
 | ||||
| #ifdef __IAR_SYSTEMS_ASM__ | ||||
| /* Register assignments for usbCrc16 on IAR cc */ | ||||
| /* Calling conventions on IAR: | ||||
|  * First parameter passed in r16/r17, second in r18/r19 and so on. | ||||
|  * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer) | ||||
|  * Result is passed in r16/r17 | ||||
|  * In case of the "tiny" memory model, pointers are only 8 bit with no | ||||
|  * padding. We therefore pass argument 1 as "16 bit unsigned". | ||||
|  */ | ||||
| RTMODEL "__rt_version", "3" | ||||
| /* The line above will generate an error if cc calling conventions change. | ||||
|  * The value "3" above is valid for IAR 4.10B/W32 | ||||
|  */ | ||||
| #   define argLen   r18 /* argument 2 */ | ||||
| #   define argPtrL  r16 /* argument 1 */ | ||||
| #   define argPtrH  r17 /* argument 1 */ | ||||
| 
 | ||||
| #   define resCrcL  r16 /* result */ | ||||
| #   define resCrcH  r17 /* result */ | ||||
| 
 | ||||
| #   define ptrL     ZL | ||||
| #   define ptrH     ZH | ||||
| #   define ptr      Z | ||||
| #   define byte     r22 | ||||
| #   define bitCnt   r19 | ||||
| #   define polyL    r20 | ||||
| #   define polyH    r21 | ||||
| #   define scratch  r23 | ||||
| 
 | ||||
| #else  /* __IAR_SYSTEMS_ASM__ */  | ||||
| /* Register assignments for usbCrc16 on gcc */ | ||||
| /* Calling conventions on gcc: | ||||
|  * First parameter passed in r24/r25, second in r22/23 and so on. | ||||
|  * Callee must preserve r1-r17, r28/r29 | ||||
|  * Result is passed in r24/r25 | ||||
|  */ | ||||
| #   define argLen   r22 /* argument 2 */ | ||||
| #   define argPtrL  r24 /* argument 1 */ | ||||
| #   define argPtrH  r25 /* argument 1 */ | ||||
| 
 | ||||
| #   define resCrcL  r24 /* result */ | ||||
| #   define resCrcH  r25 /* result */ | ||||
| 
 | ||||
| #   define ptrL     XL | ||||
| #   define ptrH     XH | ||||
| #   define ptr      x | ||||
| #   define byte     r18 | ||||
| #   define bitCnt   r19 | ||||
| #   define polyL    r20 | ||||
| #   define polyH    r21 | ||||
| #   define scratch  r23 | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| #if USB_USE_FAST_CRC | ||||
| 
 | ||||
| ; This implementation is faster, but has bigger code size
 | ||||
| ; Thanks to Slawomir Fras (BoskiDialer) for this code!
 | ||||
| ; It implements the following C pseudo-code:
 | ||||
| ; unsigned table(unsigned char x)
 | ||||
| ; {
 | ||||
| ; unsigned    value;
 | ||||
| ; 
 | ||||
| ;     value = (unsigned)x << 6;
 | ||||
| ;     value ^= (unsigned)x << 7;
 | ||||
| ;     if(parity(x))
 | ||||
| ;         value ^= 0xc001;
 | ||||
| ;     return value;
 | ||||
| ; }
 | ||||
| ; unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen)
 | ||||
| ; {
 | ||||
| ; unsigned crc = 0xffff;
 | ||||
| ; 
 | ||||
| ;     while(argLen--)
 | ||||
| ;         crc = table(lo8(crc) ^ *argPtr++) ^ hi8(crc);
 | ||||
| ;     return ~crc;
 | ||||
| ; }
 | ||||
| 
 | ||||
| ; extern unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen);
 | ||||
| ;   argPtr  r24+25 / r16+r17
 | ||||
| ;   argLen  r22 / r18
 | ||||
| ; temp variables:
 | ||||
| ;   byte    r18 / r22
 | ||||
| ;   scratch r23
 | ||||
| ;   resCrc  r24+r25 / r16+r17
 | ||||
| ;   ptr     X / Z
 | ||||
| usbCrc16: | ||||
|     mov     ptrL, argPtrL | ||||
|     mov     ptrH, argPtrH | ||||
|     ldi     resCrcL, 0xFF | ||||
|     ldi     resCrcH, 0xFF | ||||
|     rjmp    usbCrc16LoopTest | ||||
| usbCrc16ByteLoop: | ||||
|     ld      byte, ptr+ | ||||
|     eor     resCrcL, byte   ; resCrcL is now 'x' in table()
 | ||||
|     mov     byte, resCrcL   ; compute parity of 'x'
 | ||||
|     swap    byte | ||||
|     eor     byte, resCrcL | ||||
|     mov     scratch, byte | ||||
|     lsr     byte | ||||
|     lsr     byte | ||||
|     eor     byte, scratch | ||||
|     inc     byte | ||||
|     lsr     byte | ||||
|     andi    byte, 1         ; byte is now parity(x)
 | ||||
|     mov     scratch, resCrcL | ||||
|     mov     resCrcL, resCrcH | ||||
|     eor     resCrcL, byte   ; low byte of if(parity(x)) value ^= 0xc001;
 | ||||
|     neg     byte | ||||
|     andi    byte, 0xc0 | ||||
|     mov     resCrcH, byte   ; high byte of if(parity(x)) value ^= 0xc001;
 | ||||
|     clr     byte | ||||
|     lsr     scratch | ||||
|     ror     byte | ||||
|     eor     resCrcH, scratch | ||||
|     eor     resCrcL, byte | ||||
|     lsr     scratch | ||||
|     ror     byte | ||||
|     eor     resCrcH, scratch | ||||
|     eor     resCrcL, byte | ||||
| usbCrc16LoopTest: | ||||
|     subi    argLen, 1 | ||||
|     brsh    usbCrc16ByteLoop | ||||
|     com     resCrcL | ||||
|     com     resCrcH | ||||
|     ret | ||||
| 
 | ||||
| #else   /* USB_USE_FAST_CRC */ | ||||
| 
 | ||||
| ; This implementation is slower, but has less code size
 | ||||
| ;
 | ||||
| ; extern unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen);
 | ||||
| ;   argPtr  r24+25 / r16+r17
 | ||||
| ;   argLen  r22 / r18
 | ||||
| ; temp variables:
 | ||||
| ;   byte    r18 / r22
 | ||||
| ;   bitCnt  r19
 | ||||
| ;   poly    r20+r21
 | ||||
| ;   scratch r23
 | ||||
| ;   resCrc  r24+r25 / r16+r17
 | ||||
| ;   ptr     X / Z
 | ||||
| usbCrc16: | ||||
|     mov     ptrL, argPtrL | ||||
|     mov     ptrH, argPtrH | ||||
|     ldi     resCrcL, 0 | ||||
|     ldi     resCrcH, 0 | ||||
|     ldi     polyL, lo8(0xa001) | ||||
|     ldi     polyH, hi8(0xa001) | ||||
|     com     argLen      ; argLen = -argLen - 1: modified loop to ensure that carry is set
 | ||||
|     ldi     bitCnt, 0   ; loop counter with starnd condition = end condition
 | ||||
|     rjmp    usbCrcLoopEntry | ||||
| usbCrcByteLoop: | ||||
|     ld      byte, ptr+ | ||||
|     eor     resCrcL, byte | ||||
| usbCrcBitLoop: | ||||
|     ror     resCrcH     ; carry is always set here (see brcs jumps to here)
 | ||||
|     ror     resCrcL | ||||
|     brcs    usbCrcNoXor | ||||
|     eor     resCrcL, polyL | ||||
|     eor     resCrcH, polyH | ||||
| usbCrcNoXor: | ||||
|     subi    bitCnt, 224 ; (8 * 224) % 256 = 0; this loop iterates 8 times
 | ||||
|     brcs    usbCrcBitLoop | ||||
| usbCrcLoopEntry: | ||||
|     subi    argLen, -1 | ||||
|     brcs    usbCrcByteLoop | ||||
| usbCrcReady: | ||||
|     ret | ||||
| ; Thanks to Reimar Doeffinger for optimizing this CRC routine!
 | ||||
| 
 | ||||
| #endif /* USB_USE_FAST_CRC */ | ||||
| 
 | ||||
| ; extern unsigned usbCrc16Append(unsigned char *data, unsigned char len);
 | ||||
| usbCrc16Append: | ||||
|     rcall   usbCrc16 | ||||
|     st      ptr+, resCrcL | ||||
|     st      ptr+, resCrcH | ||||
|     ret | ||||
| 
 | ||||
| #undef argLen | ||||
| #undef argPtrL | ||||
| #undef argPtrH | ||||
| #undef resCrcL | ||||
| #undef resCrcH | ||||
| #undef ptrL | ||||
| #undef ptrH | ||||
| #undef ptr | ||||
| #undef byte | ||||
| #undef bitCnt | ||||
| #undef polyL | ||||
| #undef polyH | ||||
| #undef scratch | ||||
| 
 | ||||
| 
 | ||||
| #if USB_CFG_HAVE_MEASURE_FRAME_LENGTH | ||||
| #ifdef __IAR_SYSTEMS_ASM__ | ||||
| /* Register assignments for usbMeasureFrameLength on IAR cc */ | ||||
| /* Calling conventions on IAR: | ||||
|  * First parameter passed in r16/r17, second in r18/r19 and so on. | ||||
|  * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer) | ||||
|  * Result is passed in r16/r17 | ||||
|  * In case of the "tiny" memory model, pointers are only 8 bit with no | ||||
|  * padding. We therefore pass argument 1 as "16 bit unsigned". | ||||
|  */ | ||||
| #   define resL     r16 | ||||
| #   define resH     r17 | ||||
| #   define cnt16L   r30 | ||||
| #   define cnt16H   r31 | ||||
| #   define cntH     r18 | ||||
| 
 | ||||
| #else  /* __IAR_SYSTEMS_ASM__ */  | ||||
| /* Register assignments for usbMeasureFrameLength on gcc */ | ||||
| /* Calling conventions on gcc: | ||||
|  * First parameter passed in r24/r25, second in r22/23 and so on. | ||||
|  * Callee must preserve r1-r17, r28/r29 | ||||
|  * Result is passed in r24/r25 | ||||
|  */ | ||||
| #   define resL     r24 | ||||
| #   define resH     r25 | ||||
| #   define cnt16L   r24 | ||||
| #   define cnt16H   r25 | ||||
| #   define cntH     r26 | ||||
| #endif | ||||
| #   define cnt16    cnt16L | ||||
| 
 | ||||
| ; extern unsigned usbMeasurePacketLength(void);
 | ||||
| ; returns time between two idle strobes in multiples of 7 CPU clocks
 | ||||
| .global usbMeasureFrameLength
 | ||||
| usbMeasureFrameLength: | ||||
|     ldi     cntH, 6         ; wait ~ 10 ms for D- == 0
 | ||||
|     clr     cnt16L | ||||
|     clr     cnt16H | ||||
| usbMFTime16: | ||||
|     dec     cntH | ||||
|     breq    usbMFTimeout | ||||
| usbMFWaitStrobe:            ; first wait for D- == 0 (idle strobe)
 | ||||
|     sbiw    cnt16, 1        ;[0] [6]
 | ||||
|     breq    usbMFTime16     ;[2]
 | ||||
|     sbic    USBIN, USBMINUS ;[3]
 | ||||
|     rjmp    usbMFWaitStrobe ;[4]
 | ||||
| usbMFWaitIdle:              ; then wait until idle again
 | ||||
|     sbis    USBIN, USBMINUS ;1 wait for D- == 1
 | ||||
|     rjmp    usbMFWaitIdle   ;2
 | ||||
|     ldi     cnt16L, 1       ;1 represents cycles so far
 | ||||
|     clr     cnt16H          ;1
 | ||||
| usbMFWaitLoop: | ||||
|     in      cntH, USBIN     ;[0] [7]
 | ||||
|     adiw    cnt16, 1        ;[1]
 | ||||
|     breq    usbMFTimeout    ;[3]
 | ||||
|     andi    cntH, USBMASK   ;[4]
 | ||||
|     brne    usbMFWaitLoop   ;[5]
 | ||||
| usbMFTimeout: | ||||
| #if resL != cnt16L | ||||
|     mov     resL, cnt16L | ||||
|     mov     resH, cnt16H | ||||
| #endif | ||||
|     ret | ||||
| 
 | ||||
| #undef resL | ||||
| #undef resH | ||||
| #undef cnt16 | ||||
| #undef cnt16L | ||||
| #undef cnt16H | ||||
| #undef cntH | ||||
| 
 | ||||
| #endif  /* USB_CFG_HAVE_MEASURE_FRAME_LENGTH */ | ||||
| 
 | ||||
| ;----------------------------------------------------------------------------
 | ||||
| ; Now include the clock rate specific code
 | ||||
| ;----------------------------------------------------------------------------
 | ||||
| 
 | ||||
| #ifndef USB_CFG_CLOCK_KHZ | ||||
| #   ifdef F_CPU | ||||
| #       define USB_CFG_CLOCK_KHZ (F_CPU/1000) | ||||
| #   else | ||||
| #       error "USB_CFG_CLOCK_KHZ not defined in usbconfig.h and no F_CPU set!" | ||||
| #   endif | ||||
| #endif | ||||
| 
 | ||||
| #if USB_CFG_CHECK_CRC   /* separate dispatcher for CRC type modules */ | ||||
| #   if USB_CFG_CLOCK_KHZ == 18000 | ||||
| #       include "usbdrvasm18-crc.inc" | ||||
| #   else | ||||
| #       error "USB_CFG_CLOCK_KHZ is not one of the supported crc-rates!" | ||||
| #   endif | ||||
| #else   /* USB_CFG_CHECK_CRC */ | ||||
| #   if USB_CFG_CLOCK_KHZ == 12000 | ||||
| #       include "usbdrvasm12.inc" | ||||
| #   elif USB_CFG_CLOCK_KHZ == 12800 | ||||
| #       include "usbdrvasm128.inc" | ||||
| #   elif USB_CFG_CLOCK_KHZ == 15000 | ||||
| #       include "usbdrvasm15.inc" | ||||
| #   elif USB_CFG_CLOCK_KHZ == 16000 | ||||
| #       include "usbdrvasm16.inc" | ||||
| #   elif USB_CFG_CLOCK_KHZ == 16500 | ||||
| #       include "usbdrvasm165.inc" | ||||
| #   elif USB_CFG_CLOCK_KHZ == 20000 | ||||
| #       include "usbdrvasm20.inc" | ||||
| #   else | ||||
| #       error "USB_CFG_CLOCK_KHZ is not one of the supported non-crc-rates!" | ||||
| #   endif | ||||
| #endif /* USB_CFG_CHECK_CRC */ | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 tmk
						tmk