⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbdrvasm.s

📁 USBasp
💻 S
字号:
/* Name: usbdrvasm.S * Project: AVR USB driver * 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 692 2008-11-07 15:07:40Z cs $ *//*General Description:This module is the assembler part of the USB driver. This file containsgeneral code (preprocessor acrobatics and CRC computation) and then includesthe 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 bitcnt  r22#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 */#       define USB_INTR_VECTOR  SIG_INTERRUPT0#   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; extern unsigned usbCrc16(unsigned char *data, unsigned char len);; data: r24/25; len: r22; temp variables:;   r18: data byte;   r19: bit counter;   r20/21: polynomial;   r23: scratch;   r24/25: crc-sum;   r26/27=X: ptrusbCrc16:    mov     ptrL, argPtrL    mov     ptrH, argPtrH    ldi     resCrcL, 0    ldi     resCrcH, 0    ldi     polyL, lo8(0xa001)    ldi     polyH, hi8(0xa001)    com     argLen      ; argLen = -argLen - 1crcByteLoop:    subi    argLen, -1    brcc    crcReady    ; modified loop to ensure that carry is set below    ld      byte, ptr+    ldi     bitCnt, -8  ; strange loop counter to ensure that carry is set where we need it    eor     resCrcL, bytecrcBitLoop:    ror     resCrcH     ; carry is always set here    ror     resCrcL    brcs    crcNoXor    eor     resCrcL, polyL    eor     resCrcH, polyHcrcNoXor:    subi    bitCnt, -1    brcs    crcBitLoop    rjmp    crcByteLoopcrcReady:    ret; Thanks to Reimar Doeffinger for optimizing this CRC routine!; 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 usbMeasureFrameLengthusbMeasureFrameLength:    ldi     cntH, 6         ; wait ~ 10 ms for D- == 0    clr     cnt16L    clr     cnt16HusbMFTime16:    dec     cntH    breq    usbMFTimeoutusbMFWaitStrobe:            ; 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          ;1usbMFWaitLoop:    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#   define USB_CFG_CLOCK_KHZ 12000#endif#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 rates!"#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -