manueller import aus nem CVS checkout (ist eh nur zum testen)
[ds1820tousb.git] / usbdrv / usbdrvasm.S
1 /* Name: usbdrvasm.S
2  * Project: AVR USB driver
3  * Author: Christian Starkjohann
4  * Creation Date: 2007-06-13
5  * Tabsize: 4
6  * Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
7  * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
8  * Revision: $Id: usbdrvasm.S 692 2008-11-07 15:07:40Z cs $
9  */
10
11 /*
12 General Description:
13 This module is the assembler part of the USB driver. This file contains
14 general code (preprocessor acrobatics and CRC computation) and then includes
15 the file appropriate for the given clock rate.
16 */
17
18 #define __SFR_OFFSET 0      /* used by avr-libc's register definitions */
19 #include "usbportability.h"
20 #include "usbdrv.h"         /* for common defs */
21
22 /* register names */
23 #define x1      r16
24 #define x2      r17
25 #define shift   r18
26 #define cnt     r19
27 #define x3      r20
28 #define x4      r21
29 #define bitcnt  r22
30 #define phase   x4
31 #define leap    x4
32
33 /* Some assembler dependent definitions and declarations: */
34
35 #ifdef __IAR_SYSTEMS_ASM__
36     extern  usbRxBuf, usbDeviceAddr, usbNewDeviceAddr, usbInputBufOffset
37     extern  usbCurrentTok, usbRxLen, usbRxToken, usbTxLen
38     extern  usbTxBuf, usbTxStatus1, usbTxStatus3
39 #   if USB_COUNT_SOF
40         extern usbSofCount
41 #   endif
42     public  usbCrc16
43     public  usbCrc16Append
44
45     COMMON  INTVEC
46 #   ifndef USB_INTR_VECTOR
47         ORG     INT0_vect
48 #   else /* USB_INTR_VECTOR */
49         ORG     USB_INTR_VECTOR
50 #       undef   USB_INTR_VECTOR
51 #   endif /* USB_INTR_VECTOR */
52 #   define  USB_INTR_VECTOR usbInterruptHandler
53     rjmp    USB_INTR_VECTOR
54     RSEG    CODE
55
56 #else /* __IAR_SYSTEMS_ASM__ */
57
58 #   ifndef USB_INTR_VECTOR /* default to hardware interrupt INT0 */
59 #       define USB_INTR_VECTOR  SIG_INTERRUPT0
60 #   endif
61     .text
62     .global USB_INTR_VECTOR
63     .type   USB_INTR_VECTOR, @function
64     .global usbCrc16
65     .global usbCrc16Append
66 #endif /* __IAR_SYSTEMS_ASM__ */
67
68
69 #if USB_INTR_PENDING < 0x40 /* This is an I/O address, use in and out */
70 #   define  USB_LOAD_PENDING(reg)   in reg, USB_INTR_PENDING
71 #   define  USB_STORE_PENDING(reg)  out USB_INTR_PENDING, reg
72 #else   /* It's a memory address, use lds and sts */
73 #   define  USB_LOAD_PENDING(reg)   lds reg, USB_INTR_PENDING
74 #   define  USB_STORE_PENDING(reg)  sts USB_INTR_PENDING, reg
75 #endif
76
77 #define usbTxLen1   usbTxStatus1
78 #define usbTxBuf1   (usbTxStatus1 + 1)
79 #define usbTxLen3   usbTxStatus3
80 #define usbTxBuf3   (usbTxStatus3 + 1)
81
82
83 ;----------------------------------------------------------------------------
84 ; Utility functions
85 ;----------------------------------------------------------------------------
86
87 #ifdef __IAR_SYSTEMS_ASM__
88 /* Register assignments for usbCrc16 on IAR cc */
89 /* Calling conventions on IAR:
90  * First parameter passed in r16/r17, second in r18/r19 and so on.
91  * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer)
92  * Result is passed in r16/r17
93  * In case of the "tiny" memory model, pointers are only 8 bit with no
94  * padding. We therefore pass argument 1 as "16 bit unsigned".
95  */
96 RTMODEL "__rt_version", "3"
97 /* The line above will generate an error if cc calling conventions change.
98  * The value "3" above is valid for IAR 4.10B/W32
99  */
100 #   define argLen   r18 /* argument 2 */
101 #   define argPtrL  r16 /* argument 1 */
102 #   define argPtrH  r17 /* argument 1 */
103
104 #   define resCrcL  r16 /* result */
105 #   define resCrcH  r17 /* result */
106
107 #   define ptrL     ZL
108 #   define ptrH     ZH
109 #   define ptr      Z
110 #   define byte     r22
111 #   define bitCnt   r19
112 #   define polyL    r20
113 #   define polyH    r21
114 #   define scratch  r23
115
116 #else  /* __IAR_SYSTEMS_ASM__ */ 
117 /* Register assignments for usbCrc16 on gcc */
118 /* Calling conventions on gcc:
119  * First parameter passed in r24/r25, second in r22/23 and so on.
120  * Callee must preserve r1-r17, r28/r29
121  * Result is passed in r24/r25
122  */
123 #   define argLen   r22 /* argument 2 */
124 #   define argPtrL  r24 /* argument 1 */
125 #   define argPtrH  r25 /* argument 1 */
126
127 #   define resCrcL  r24 /* result */
128 #   define resCrcH  r25 /* result */
129
130 #   define ptrL     XL
131 #   define ptrH     XH
132 #   define ptr      x
133 #   define byte     r18
134 #   define bitCnt   r19
135 #   define polyL    r20
136 #   define polyH    r21
137 #   define scratch  r23
138
139 #endif
140
141 ; extern unsigned usbCrc16(unsigned char *data, unsigned char len);
142 ; data: r24/25
143 ; len: r22
144 ; temp variables:
145 ;   r18: data byte
146 ;   r19: bit counter
147 ;   r20/21: polynomial
148 ;   r23: scratch
149 ;   r24/25: crc-sum
150 ;   r26/27=X: ptr
151 usbCrc16:
152     mov     ptrL, argPtrL
153     mov     ptrH, argPtrH
154     ldi     resCrcL, 0
155     ldi     resCrcH, 0
156     ldi     polyL, lo8(0xa001)
157     ldi     polyH, hi8(0xa001)
158     com     argLen      ; argLen = -argLen - 1
159 crcByteLoop:
160     subi    argLen, -1
161     brcc    crcReady    ; modified loop to ensure that carry is set below
162     ld      byte, ptr+
163     ldi     bitCnt, -8  ; strange loop counter to ensure that carry is set where we need it
164     eor     resCrcL, byte
165 crcBitLoop:
166     ror     resCrcH     ; carry is always set here
167     ror     resCrcL
168     brcs    crcNoXor
169     eor     resCrcL, polyL
170     eor     resCrcH, polyH
171 crcNoXor:
172     subi    bitCnt, -1
173     brcs    crcBitLoop
174     rjmp    crcByteLoop
175 crcReady:
176     ret
177 ; Thanks to Reimar Doeffinger for optimizing this CRC routine!
178
179 ; extern unsigned usbCrc16Append(unsigned char *data, unsigned char len);
180 usbCrc16Append:
181     rcall   usbCrc16
182     st      ptr+, resCrcL
183     st      ptr+, resCrcH
184     ret
185
186 #undef argLen
187 #undef argPtrL
188 #undef argPtrH
189 #undef resCrcL
190 #undef resCrcH
191 #undef ptrL
192 #undef ptrH
193 #undef ptr
194 #undef byte
195 #undef bitCnt
196 #undef polyL
197 #undef polyH
198 #undef scratch
199
200
201 #if USB_CFG_HAVE_MEASURE_FRAME_LENGTH
202 #ifdef __IAR_SYSTEMS_ASM__
203 /* Register assignments for usbMeasureFrameLength on IAR cc */
204 /* Calling conventions on IAR:
205  * First parameter passed in r16/r17, second in r18/r19 and so on.
206  * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer)
207  * Result is passed in r16/r17
208  * In case of the "tiny" memory model, pointers are only 8 bit with no
209  * padding. We therefore pass argument 1 as "16 bit unsigned".
210  */
211 #   define resL     r16
212 #   define resH     r17
213 #   define cnt16L   r30
214 #   define cnt16H   r31
215 #   define cntH     r18
216
217 #else  /* __IAR_SYSTEMS_ASM__ */ 
218 /* Register assignments for usbMeasureFrameLength on gcc */
219 /* Calling conventions on gcc:
220  * First parameter passed in r24/r25, second in r22/23 and so on.
221  * Callee must preserve r1-r17, r28/r29
222  * Result is passed in r24/r25
223  */
224 #   define resL     r24
225 #   define resH     r25
226 #   define cnt16L   r24
227 #   define cnt16H   r25
228 #   define cntH     r26
229 #endif
230 #   define cnt16    cnt16L
231
232 ; extern unsigned usbMeasurePacketLength(void);
233 ; returns time between two idle strobes in multiples of 7 CPU clocks
234 .global usbMeasureFrameLength
235 usbMeasureFrameLength:
236     ldi     cntH, 6         ; wait ~ 10 ms for D- == 0
237     clr     cnt16L
238     clr     cnt16H
239 usbMFTime16:
240     dec     cntH
241     breq    usbMFTimeout
242 usbMFWaitStrobe:            ; first wait for D- == 0 (idle strobe)
243     sbiw    cnt16, 1        ;[0] [6]
244     breq    usbMFTime16     ;[2]
245     sbic    USBIN, USBMINUS ;[3]
246     rjmp    usbMFWaitStrobe ;[4]
247 usbMFWaitIdle:              ; then wait until idle again
248     sbis    USBIN, USBMINUS ;1 wait for D- == 1
249     rjmp    usbMFWaitIdle   ;2
250     ldi     cnt16L, 1       ;1 represents cycles so far
251     clr     cnt16H          ;1
252 usbMFWaitLoop:
253     in      cntH, USBIN     ;[0] [7]
254     adiw    cnt16, 1        ;[1]
255     breq    usbMFTimeout    ;[3]
256     andi    cntH, USBMASK   ;[4]
257     brne    usbMFWaitLoop   ;[5]
258 usbMFTimeout:
259 #if resL != cnt16L
260     mov     resL, cnt16L
261     mov     resH, cnt16H
262 #endif
263     ret
264
265 #undef resL
266 #undef resH
267 #undef cnt16
268 #undef cnt16L
269 #undef cnt16H
270 #undef cntH
271
272 #endif  /* USB_CFG_HAVE_MEASURE_FRAME_LENGTH */
273
274 ;----------------------------------------------------------------------------
275 ; Now include the clock rate specific code
276 ;----------------------------------------------------------------------------
277
278 #ifndef USB_CFG_CLOCK_KHZ
279 #   define USB_CFG_CLOCK_KHZ 12000
280 #endif
281
282 #if USB_CFG_CLOCK_KHZ == 12000
283 #   include "usbdrvasm12.inc"
284 #elif USB_CFG_CLOCK_KHZ == 12800
285 #   include "usbdrvasm128.inc"
286 #elif USB_CFG_CLOCK_KHZ == 15000
287 #   include "usbdrvasm15.inc"
288 #elif USB_CFG_CLOCK_KHZ == 16000
289 #   include "usbdrvasm16.inc"
290 #elif USB_CFG_CLOCK_KHZ == 16500
291 #   include "usbdrvasm165.inc"
292 #elif USB_CFG_CLOCK_KHZ == 20000
293 #   include "usbdrvasm20.inc"
294 #else
295 #   error "USB_CFG_CLOCK_KHZ is not one of the supported rates!"
296 #endif
This page took 0.065432 seconds and 3 git commands to generate.