USBasp 2007.07.23.
[pub/USBasp.git] / firmware / 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) or proprietary (CommercialLicense.txt)
8 * Revision: $Id$
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 #include "iarcompat.h"
19 #ifndef __IAR_SYSTEMS_ASM__
20 /* configs for io.h */
21 # define __SFR_OFFSET 0
22 # define _VECTOR(N) __vector_ ## N /* io.h does not define this for asm */
23 # include <avr/io.h> /* for CPU I/O register definitions and vectors */
24 #endif /* __IAR_SYSTEMS_ASM__ */
25 #include "usbdrv.h" /* for common defs */
26
27
28 /* register names */
29 #define x1 r16
30 #define x2 r17
31 #define shift r18
32 #define cnt r19
33 #define x3 r20
34 #define x4 r21
35 #define bitcnt r22
36 #define phase x4
37 #define leap x4
38
39 /* Some assembler dependent definitions and declarations: */
40
41 #ifdef __IAR_SYSTEMS_ASM__
42
43 # define nop2 rjmp $+2 /* jump to next instruction */
44 # define XL r26
45 # define XH r27
46 # define YL r28
47 # define YH r29
48 # define ZL r30
49 # define ZH r31
50 # define lo8(x) LOW(x)
51 # define hi8(x) ((x)>>8) /* not HIGH to allow XLINK to make a proper range check */
52
53 extern usbRxBuf, usbDeviceAddr, usbNewDeviceAddr, usbInputBufOffset
54 extern usbCurrentTok, usbRxLen, usbRxToken, usbTxLen
55 extern usbTxBuf, usbMsgLen, usbTxLen1, usbTxBuf1, usbTxLen3, usbTxBuf3
56 public usbCrc16
57 public usbCrc16Append
58
59 COMMON INTVEC
60 ORG INT0_vect
61 rjmp SIG_INTERRUPT0
62 RSEG CODE
63
64 #else /* __IAR_SYSTEMS_ASM__ */
65
66 # define nop2 rjmp .+0 /* jump to next instruction */
67
68 .text
69 .global SIG_INTERRUPT0
70 .type SIG_INTERRUPT0, @function
71 .global usbCrc16
72 .global usbCrc16Append
73
74 #endif /* __IAR_SYSTEMS_ASM__ */
75
76 ;----------------------------------------------------------------------------
77 ; Utility functions
78 ;----------------------------------------------------------------------------
79
80 #ifdef __IAR_SYSTEMS_ASM__
81 /* Register assignments for usbCrc16 on IAR cc */
82 /* Calling conventions on IAR:
83 * First parameter passed in r16/r17, second in r18/r19 and so on.
84 * Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer)
85 * Result is passed in r16/r17
86 * In case of the "tiny" memory model, pointers are only 8 bit with no
87 * padding. We therefore pass argument 1 as "16 bit unsigned".
88 */
89 RTMODEL "__rt_version", "3"
90 /* The line above will generate an error if cc calling conventions change.
91 * The value "3" above is valid for IAR 4.10B/W32
92 */
93 # define argLen r18 /* argument 2 */
94 # define argPtrL r16 /* argument 1 */
95 # define argPtrH r17 /* argument 1 */
96
97 # define resCrcL r16 /* result */
98 # define resCrcH r17 /* result */
99
100 # define ptrL ZL
101 # define ptrH ZH
102 # define ptr Z
103 # define byte r22
104 # define bitCnt r19
105 # define polyL r20
106 # define polyH r21
107 # define scratch r23
108
109 #else /* __IAR_SYSTEMS_ASM__ */
110 /* Register assignments for usbCrc16 on gcc */
111 /* Calling conventions on gcc:
112 * First parameter passed in r24/r25, second in r22/23 and so on.
113 * Callee must preserve r1-r17, r28/r29
114 * Result is passed in r24/r25
115 */
116 # define argLen r22 /* argument 2 */
117 # define argPtrL r24 /* argument 1 */
118 # define argPtrH r25 /* argument 1 */
119
120 # define resCrcL r24 /* result */
121 # define resCrcH r25 /* result */
122
123 # define ptrL XL
124 # define ptrH XH
125 # define ptr x
126 # define byte r18
127 # define bitCnt r19
128 # define polyL r20
129 # define polyH r21
130 # define scratch r23
131
132 #endif
133
134 ; extern unsigned usbCrc16(unsigned char *data, unsigned char len);
135 ; data: r24/25
136 ; len: r22
137 ; temp variables:
138 ; r18: data byte
139 ; r19: bit counter
140 ; r20/21: polynomial
141 ; r23: scratch
142 ; r24/25: crc-sum
143 ; r26/27=X: ptr
144 usbCrc16:
145 mov ptrL, argPtrL
146 mov ptrH, argPtrH
147 ldi resCrcL, 0xff
148 ldi resCrcH, 0xff
149 ldi polyL, lo8(0xa001)
150 ldi polyH, hi8(0xa001)
151 crcByteLoop:
152 subi argLen, 1
153 brcs crcReady
154 ld byte, ptr+
155 ldi bitCnt, 8
156 crcBitLoop:
157 mov scratch, byte
158 eor scratch, resCrcL
159 lsr resCrcH
160 ror resCrcL
161 lsr byte
162 sbrs scratch, 0
163 rjmp crcNoXor
164 eor resCrcL, polyL
165 eor resCrcH, polyH
166 crcNoXor:
167 dec bitCnt
168 brne crcBitLoop
169 rjmp crcByteLoop
170 crcReady:
171 com resCrcL
172 com resCrcH
173 ret
174
175 ; extern unsigned usbCrc16Append(unsigned char *data, unsigned char len);
176 usbCrc16Append:
177 rcall usbCrc16
178 st ptr+, resCrcL
179 st ptr+, resCrcH
180 ret
181
182
183 ;----------------------------------------------------------------------------
184 ; Now include the clock rate specific code
185 ;----------------------------------------------------------------------------
186
187 #ifndef USB_CFG_CLOCK_KHZ
188 # define USB_CFG_CLOCK_KHZ 12000
189 #endif
190
191 #if USB_CFG_CLOCK_KHZ == 12000
192 # include "usbdrvasm12.S"
193 #elif USB_CFG_CLOCK_KHZ == 16000
194 # include "usbdrvasm16.S"
195 #elif USB_CFG_CLOCK_KHZ == 16500
196 # include "usbdrvasm165.S"
197 #else
198 # error "USB_CFG_CLOCK_KHZ is not one of the supported rates!"
199 #endif