| 3514 | miho | 1 | ; ====================================================================== | 
      
        |  |  | 2 | ; USB interrupt handler | 
      
        |  |  | 3 | ; | 
      
        |  |  | 4 | ; This is the handler for the interrupt caused by the initial rising edge | 
      
        |  |  | 5 | ; on the D+ USB signal. The NRZI encoding and bit stuffing are removed, | 
      
        |  |  | 6 | ; and the packet is saved in one of the two input buffers. In some cases, | 
      
        |  |  | 7 | ; a reply packet is sent right away. | 
      
        |  |  | 8 | ; | 
      
        |  |  | 9 | ; When a DATA0/DATA1 packet directly follows a SETUP or OUT packet, while | 
      
        |  |  | 10 | ; this interrupt handler is not yet finished, there would be no time to | 
      
        |  |  | 11 | ; return and take another interrupt. In that case, the second packet is | 
      
        |  |  | 12 | ; decoded directly in the same invocation. | 
      
        |  |  | 13 | ; | 
      
        |  |  | 14 | ; This code is *extremely* time critical. For instance, there is not a | 
      
        |  |  | 15 | ; single spare cycle in the receiver loop, and only two in the transmitter | 
      
        |  |  | 16 | ; loop. In addition, the various code paths are laid out in such a way that | 
      
        |  |  | 17 | ; the various USB timeouts are not violated, in particular the maximum time | 
      
        |  |  | 18 | ; between the reception of a packet and the reply, which is 6.5 bit times | 
      
        |  |  | 19 | ; for a detachable cable (TRSPIPD1), and 7.5 bit times for a captive cable | 
      
        |  |  | 20 | ; (TRSPIPD2). The worst-case delay here is 51 cycles, which is just below | 
      
        |  |  | 21 | ; the 52 cycles for a detachable cable. | 
      
        |  |  | 22 | ; | 
      
        |  |  | 23 | ; The interrupt handler must be reached within 34 cycles after D+ goes high | 
      
        |  |  | 24 | ; for the first time, so the interrupts should not be disabled for longer | 
      
        |  |  | 25 | ; than 34-4-2=28 cycles. | 
      
        |  |  | 26 | ; | 
      
        |  |  | 27 | ; The end-of-packet (EOP) is sampled in the second bit, because the USB | 
      
        |  |  | 28 | ; standard allows the EOP to be delayed by up to one bit. As the EOP | 
      
        |  |  | 29 | ; duration is two bits, this is not a problem. | 
      
        |  |  | 30 | ; | 
      
        |  |  | 31 | ; Stack usage including the return address: 11 bytes. | 
      
        |  |  | 32 | ; | 
      
        |  |  | 33 | ; Copyright (C) 2006 Dick Streefland | 
      
        |  |  | 34 | ; | 
      
        |  |  | 35 | ; This is free software, licensed under the terms of the GNU General | 
      
        |  |  | 36 | ; Public License as published by the Free Software Foundation. | 
      
        |  |  | 37 | ; ====================================================================== | 
      
        |  |  | 38 |  | 
      
        |  |  | 39 | #include "def.h" | 
      
        |  |  | 40 |  | 
      
        |  |  | 41 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 42 | ; local data | 
      
        |  |  | 43 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 44 | 	.data | 
      
        |  |  | 45 | tx_ack:	.byte	USB_PID_ACK		; ACK packet | 
      
        |  |  | 46 | tx_nak:	.byte	USB_PID_NAK		; NAK packet | 
      
        |  |  | 47 | 	.lcomm	token_pid, 1		; PID of most recent token packet | 
      
        |  |  | 48 |  | 
      
        |  |  | 49 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 50 | ; register definitions | 
      
        |  |  | 51 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 52 | // receiver: | 
      
        |  |  | 53 | #define	count		r16 | 
      
        |  |  | 54 | #define	usbmask		r17 | 
      
        |  |  | 55 | #define	odd		r18 | 
      
        |  |  | 56 | #define	byte		r19 | 
      
        |  |  | 57 | #define	fixup		r20 | 
      
        |  |  | 58 | #define	even		r22 | 
      
        |  |  | 59 |  | 
      
        |  |  | 60 | // transmitter: | 
      
        |  |  | 61 | #define	output		odd | 
      
        |  |  | 62 | #define	done		fixup | 
      
        |  |  | 63 | #define	next		even | 
      
        |  |  | 64 |  | 
      
        |  |  | 65 | // control: | 
      
        |  |  | 66 | #define	pid		odd | 
      
        |  |  | 67 | #define	addr		usbmask | 
      
        |  |  | 68 | #define	tmp		fixup | 
      
        |  |  | 69 |  | 
      
        |  |  | 70 | #define	nop2		rjmp	.+0	// not .+2 for some strange reason | 
      
        |  |  | 71 |  | 
      
        |  |  | 72 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 73 | ; interrupt handler | 
      
        |  |  | 74 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 75 | 	.text | 
      
        |  |  | 76 | 	.global	USB_INT_VECTOR | 
      
        |  |  | 77 | 	.type	USB_INT_VECTOR, @function | 
      
        |  |  | 78 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 79 | ; This handler must be reached no later than 34 cycles after D+ goes high | 
      
        |  |  | 80 | ; for the first time. | 
      
        |  |  | 81 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 82 | USB_INT_VECTOR: | 
      
        |  |  | 83 | 	; save registers | 
      
        |  |  | 84 | 	push	count | 
      
        |  |  | 85 | 	push	usbmask | 
      
        |  |  | 86 | 	push	odd | 
      
        |  |  | 87 | 	push	YH | 
      
        |  |  | 88 | 	push	YL | 
      
        |  |  | 89 | 	in	count, SREG | 
      
        |  |  | 90 | 	push	count | 
      
        |  |  | 91 |  | 
      
        |  |  | 92 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 93 | ; Synchronize to the pattern 10101011 on D+. This code must be reached | 
      
        |  |  | 94 | ; no later than 47 cycles after D+ goes high for the first time. | 
      
        |  |  | 95 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 96 | sync: | 
      
        |  |  | 97 | 	; wait until D+ == 0 | 
      
        |  |  | 98 | 	sbic	USB_IN, USBTINY_DPLUS | 
      
        |  |  | 99 | 	rjmp	sync			; jump if D+ == 1 | 
      
        |  |  | 100 | resync: | 
      
        |  |  | 101 | 	; sync on 0-->1 transition on D+ with a 2 cycle resolution | 
      
        |  |  | 102 | 	sbic	USB_IN, USBTINY_DPLUS | 
      
        |  |  | 103 | 	rjmp	sync6			; jump if D+ == 1 | 
      
        |  |  | 104 | 	sbic	USB_IN, USBTINY_DPLUS | 
      
        |  |  | 105 | 	rjmp	sync6			; jump if D+ == 1 | 
      
        |  |  | 106 | 	sbic	USB_IN, USBTINY_DPLUS | 
      
        |  |  | 107 | 	rjmp	sync6			; jump if D+ == 1 | 
      
        |  |  | 108 | 	sbic	USB_IN, USBTINY_DPLUS | 
      
        |  |  | 109 | 	rjmp	sync6			; jump if D+ == 1 | 
      
        |  |  | 110 | 	sbic	USB_IN, USBTINY_DPLUS | 
      
        |  |  | 111 | 	rjmp	sync6			; jump if D+ == 1 | 
      
        |  |  | 112 | 	ldi	count, 1<<USB_INT_PENDING_BIT | 
      
        |  |  | 113 | 	out	USB_INT_PENDING, count | 
      
        |  |  | 114 | 	rjmp	return			; ==> false start, bail out | 
      
        |  |  | 115 |  | 
      
        |  |  | 116 | sync6: | 
      
        |  |  | 117 | 	; we are now between -1 and +1 cycle from the center of the bit | 
      
        |  |  | 118 | 	; following the 0-->1 transition | 
      
        |  |  | 119 | 	lds	YL, usb_rx_off | 
      
        |  |  | 120 | 	clr	YH | 
      
        |  |  | 121 | 	subi	YL, lo8(-(usb_rx_buf))	; Y = & usb_rx_buf[usb_rx_off] | 
      
        |  |  | 122 | 	sbci	YH, hi8(-(usb_rx_buf)) | 
      
        |  |  | 123 | 	ldi	count, USB_BUFSIZE	; limit on number of bytes to receive | 
      
        |  |  | 124 | 	ldi	usbmask, USB_MASK	; why is there no eori instruction? | 
      
        |  |  | 125 | 	ldi	odd, USB_MASK_DPLUS | 
      
        |  |  | 126 |  | 
      
        |  |  | 127 | sync7: | 
      
        |  |  | 128 | 	; the last sync bit should also be 1 | 
      
        |  |  | 129 | 	sbis	USB_IN, USBTINY_DPLUS	; bit 7 of sync byte? | 
      
        |  |  | 130 | 	rjmp	resync			; no, wait for next transition | 
      
        |  |  | 131 | 	push	byte | 
      
        |  |  | 132 | 	push	fixup | 
      
        |  |  | 133 | 	push	even | 
      
        |  |  | 134 |  | 
      
        |  |  | 135 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 136 | ; receiver loop | 
      
        |  |  | 137 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 138 | 	in	even, USB_IN		; sample bit 0 | 
      
        |  |  | 139 | 	ldi	byte, 0x80		; load sync byte for correct unstuffing | 
      
        |  |  | 140 | 	rjmp	rxentry			; 2 cycles | 
      
        |  |  | 141 |  | 
      
        |  |  | 142 | rxloop: | 
      
        |  |  | 143 | 	in	even, USB_IN		; sample bit 0 | 
      
        |  |  | 144 | 	or	fixup, byte | 
      
        |  |  | 145 | 	st	Y+, fixup		; 2 cycles | 
      
        |  |  | 146 | rxentry: | 
      
        |  |  | 147 | 	clr	fixup | 
      
        |  |  | 148 | 	andi	even, USB_MASK | 
      
        |  |  | 149 | 	eor	odd, even | 
      
        |  |  | 150 | 	subi	odd, 1 | 
      
        |  |  | 151 | 	in	odd, USB_IN		; sample bit 1 | 
      
        |  |  | 152 | 	andi	odd, USB_MASK | 
      
        |  |  | 153 | 	breq	eop			; ==> EOP detected | 
      
        |  |  | 154 | 	ror	byte | 
      
        |  |  | 155 | 	cpi	byte, 0xfc | 
      
        |  |  | 156 | 	brcc	skip0 | 
      
        |  |  | 157 | skipped0: | 
      
        |  |  | 158 | 	eor	even, odd | 
      
        |  |  | 159 | 	subi	even, 1 | 
      
        |  |  | 160 | 	in	even, USB_IN		; sample bit 2 | 
      
        |  |  | 161 | 	andi	even, USB_MASK | 
      
        |  |  | 162 | 	ror	byte | 
      
        |  |  | 163 | 	cpi	byte, 0xfc | 
      
        |  |  | 164 | 	brcc	skip1 | 
      
        |  |  | 165 | skipped1: | 
      
        |  |  | 166 | 	eor	odd, even | 
      
        |  |  | 167 | 	subi	odd, 1 | 
      
        |  |  | 168 | 	ror	byte | 
      
        |  |  | 169 | 	in	odd, USB_IN		; sample bit 3 | 
      
        |  |  | 170 | 	andi	odd, USB_MASK | 
      
        |  |  | 171 | 	cpi	byte, 0xfc | 
      
        |  |  | 172 | 	brcc	skip2 | 
      
        |  |  | 173 | 	eor	even, odd | 
      
        |  |  | 174 | 	subi	even, 1 | 
      
        |  |  | 175 | 	ror	byte | 
      
        |  |  | 176 | skipped2: | 
      
        |  |  | 177 | 	cpi	byte, 0xfc | 
      
        |  |  | 178 | 	in	even, USB_IN		; sample bit 4 | 
      
        |  |  | 179 | 	andi	even, USB_MASK | 
      
        |  |  | 180 | 	brcc	skip3 | 
      
        |  |  | 181 | 	eor	odd, even | 
      
        |  |  | 182 | 	subi	odd, 1 | 
      
        |  |  | 183 | 	ror	byte | 
      
        |  |  | 184 | skipped4: | 
      
        |  |  | 185 | 	cpi	byte, 0xfc | 
      
        |  |  | 186 | skipped3: | 
      
        |  |  | 187 | 	brcc	skip4 | 
      
        |  |  | 188 | 	in	odd, USB_IN		; sample bit 5 | 
      
        |  |  | 189 | 	andi	odd, USB_MASK | 
      
        |  |  | 190 | 	eor	even, odd | 
      
        |  |  | 191 | 	subi	even, 1 | 
      
        |  |  | 192 | 	ror	byte | 
      
        |  |  | 193 | skipped5: | 
      
        |  |  | 194 | 	cpi	byte, 0xfc | 
      
        |  |  | 195 | 	brcc	skip5 | 
      
        |  |  | 196 | 	dec	count | 
      
        |  |  | 197 | 	in	even, USB_IN		; sample bit 6 | 
      
        |  |  | 198 | 	brmi	overflow		; ==> overflow | 
      
        |  |  | 199 | 	andi	even, USB_MASK | 
      
        |  |  | 200 | 	eor	odd, even | 
      
        |  |  | 201 | 	subi	odd, 1 | 
      
        |  |  | 202 | 	ror	byte | 
      
        |  |  | 203 | skipped6: | 
      
        |  |  | 204 | 	cpi	byte, 0xfc | 
      
        |  |  | 205 | 	brcc	skip6 | 
      
        |  |  | 206 | 	in	odd, USB_IN		; sample bit 7 | 
      
        |  |  | 207 | 	andi	odd, USB_MASK | 
      
        |  |  | 208 | 	eor	even, odd | 
      
        |  |  | 209 | 	subi	even, 1 | 
      
        |  |  | 210 | 	ror	byte | 
      
        |  |  | 211 | 	cpi	byte, 0xfc | 
      
        |  |  | 212 | 	brcs	rxloop			; 2 cycles | 
      
        |  |  | 213 | 	rjmp	skip7 | 
      
        |  |  | 214 |  | 
      
        |  |  | 215 | eop: | 
      
        |  |  | 216 | 	rjmp	eop2 | 
      
        |  |  | 217 | overflow: | 
      
        |  |  | 218 | 	rjmp	ignore | 
      
        |  |  | 219 |  | 
      
        |  |  | 220 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 221 | ; out-of-line code to skip stuffing bits | 
      
        |  |  | 222 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 223 | skip0:					; 1+6 cycles | 
      
        |  |  | 224 | 	eor	even, usbmask | 
      
        |  |  | 225 | 	in	odd, USB_IN		; resample bit 1 | 
      
        |  |  | 226 | 	andi	odd, USB_MASK | 
      
        |  |  | 227 | 	cbr	byte, (1<<7) | 
      
        |  |  | 228 | 	sbr	fixup, (1<<0) | 
      
        |  |  | 229 | 	rjmp	skipped0 | 
      
        |  |  | 230 |  | 
      
        |  |  | 231 | skip1:					; 2+5 cycles | 
      
        |  |  | 232 | 	cbr	byte, (1<<7) | 
      
        |  |  | 233 | 	sbr	fixup, (1<<1) | 
      
        |  |  | 234 | 	in	even, USB_IN		; resample bit 2 | 
      
        |  |  | 235 | 	andi	even, USB_MASK | 
      
        |  |  | 236 | 	eor	odd, usbmask | 
      
        |  |  | 237 | 	rjmp	skipped1 | 
      
        |  |  | 238 |  | 
      
        |  |  | 239 | skip2:					; 3+7 cycles | 
      
        |  |  | 240 | 	cbr	byte, (1<<7) | 
      
        |  |  | 241 | 	sbr	fixup, (1<<2) | 
      
        |  |  | 242 | 	eor	even, usbmask | 
      
        |  |  | 243 | 	in	odd, USB_IN		; resample bit 3 | 
      
        |  |  | 244 | 	andi	odd, USB_MASK | 
      
        |  |  | 245 | 	eor	even, odd | 
      
        |  |  | 246 | 	subi	even, 1 | 
      
        |  |  | 247 | 	ror	byte | 
      
        |  |  | 248 | 	rjmp	skipped2 | 
      
        |  |  | 249 |  | 
      
        |  |  | 250 | skip3:					; 4+7 cycles | 
      
        |  |  | 251 | 	cbr	byte, (1<<7) | 
      
        |  |  | 252 | 	sbr	fixup, (1<<3) | 
      
        |  |  | 253 | 	eor	odd, usbmask | 
      
        |  |  | 254 | 	ori	byte, 1 | 
      
        |  |  | 255 | 	in	even, USB_IN		; resample bit 4 | 
      
        |  |  | 256 | 	andi	even, USB_MASK | 
      
        |  |  | 257 | 	eor	odd, even | 
      
        |  |  | 258 | 	subi	odd, 1 | 
      
        |  |  | 259 | 	ror	byte | 
      
        |  |  | 260 | 	rjmp	skipped3 | 
      
        |  |  | 261 |  | 
      
        |  |  | 262 | skip4:					; 5 cycles | 
      
        |  |  | 263 | 	cbr	byte, (1<<7) | 
      
        |  |  | 264 | 	sbr	fixup, (1<<4) | 
      
        |  |  | 265 | 	eor	even, usbmask | 
      
        |  |  | 266 | 	rjmp	skipped4 | 
      
        |  |  | 267 |  | 
      
        |  |  | 268 | skip5:					; 5 cycles | 
      
        |  |  | 269 | 	cbr	byte, (1<<7) | 
      
        |  |  | 270 | 	sbr	fixup, (1<<5) | 
      
        |  |  | 271 | 	eor	odd, usbmask | 
      
        |  |  | 272 | 	rjmp	skipped5 | 
      
        |  |  | 273 |  | 
      
        |  |  | 274 | skip6:					; 5 cycles | 
      
        |  |  | 275 | 	cbr	byte, (1<<7) | 
      
        |  |  | 276 | 	sbr	fixup, (1<<6) | 
      
        |  |  | 277 | 	eor	even, usbmask | 
      
        |  |  | 278 | 	rjmp	skipped6 | 
      
        |  |  | 279 |  | 
      
        |  |  | 280 | skip7:					; 7 cycles | 
      
        |  |  | 281 | 	cbr	byte, (1<<7) | 
      
        |  |  | 282 | 	sbr	fixup, (1<<7) | 
      
        |  |  | 283 | 	eor	odd, usbmask | 
      
        |  |  | 284 | 	nop2 | 
      
        |  |  | 285 | 	rjmp	rxloop | 
      
        |  |  | 286 |  | 
      
        |  |  | 287 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 288 | ; end-of-packet detected (worst-case: 3 cycles after end of SE0) | 
      
        |  |  | 289 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 290 | eop2: | 
      
        |  |  | 291 | 	; clear pending interrupt (SE0+3) | 
      
        |  |  | 292 | 	ldi	byte, 1<<USB_INT_PENDING_BIT | 
      
        |  |  | 293 | 	out	USB_INT_PENDING, byte	; clear pending bit at end of packet | 
      
        |  |  | 294 | 	; ignore packets shorter than 3 bytes | 
      
        |  |  | 295 | 	subi	count, USB_BUFSIZE | 
      
        |  |  | 296 | 	neg	count			; count = packet length | 
      
        |  |  | 297 | 	cpi	count, 3 | 
      
        |  |  | 298 | 	brlo	ignore | 
      
        |  |  | 299 | 	; get PID | 
      
        |  |  | 300 | 	sub	YL, count | 
      
        |  |  | 301 | 	ld	pid, Y | 
      
        |  |  | 302 | 	; check for DATA0/DATA1 first, as this is the critical path (SE0+12) | 
      
        |  |  | 303 | 	cpi	pid, USB_PID_DATA0 | 
      
        |  |  | 304 | 	breq	is_data			; handle DATA0 packet | 
      
        |  |  | 305 | 	cpi	pid, USB_PID_DATA1 | 
      
        |  |  | 306 | 	breq	is_data			; handle DATA1 packet | 
      
        |  |  | 307 | 	; check ADDR (SE0+16) | 
      
        |  |  | 308 | 	ldd	addr, Y+1 | 
      
        |  |  | 309 | 	andi	addr, 0x7f | 
      
        |  |  | 310 | 	lds	tmp, usb_address | 
      
        |  |  | 311 | 	cp	addr, tmp		; is this packet for me? | 
      
        |  |  | 312 | 	brne	ignore			; no, ignore | 
      
        |  |  | 313 | 	; check for other PIDs (SE0+23) | 
      
        |  |  | 314 | 	cpi	pid, USB_PID_IN | 
      
        |  |  | 315 | 	breq	is_in			; handle IN packet | 
      
        |  |  | 316 | 	cpi	pid, USB_PID_SETUP | 
      
        |  |  | 317 | 	breq	is_setup_out		; handle SETUP packet | 
      
        |  |  | 318 | 	cpi	pid, USB_PID_OUT | 
      
        |  |  | 319 | 	breq	is_setup_out		; handle OUT packet | 
      
        |  |  | 320 |  | 
      
        |  |  | 321 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 322 | ; exit point for ignored packets | 
      
        |  |  | 323 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 324 | ignore: | 
      
        |  |  | 325 | 	clr	tmp | 
      
        |  |  | 326 | 	sts	token_pid, tmp | 
      
        |  |  | 327 | 	pop	even | 
      
        |  |  | 328 | 	pop	fixup | 
      
        |  |  | 329 | 	pop	byte | 
      
        |  |  | 330 | 	rjmp	return | 
      
        |  |  | 331 |  | 
      
        |  |  | 332 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 333 | ; Handle SETUP/OUT (SE0+30) | 
      
        |  |  | 334 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 335 | is_setup_out: | 
      
        |  |  | 336 | 	sts	token_pid, pid		; save PID of token packet | 
      
        |  |  | 337 | 	pop	even | 
      
        |  |  | 338 | 	pop	fixup | 
      
        |  |  | 339 | 	pop	byte | 
      
        |  |  | 340 | 	in	count, USB_INT_PENDING	; next packet already started? | 
      
        |  |  | 341 | 	sbrc	count, USB_INT_PENDING_BIT | 
      
        |  |  | 342 | 	rjmp	sync			; yes, get it right away (SE0+42) | 
      
        |  |  | 343 |  | 
      
        |  |  | 344 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 345 | ; restore registers and return from interrupt | 
      
        |  |  | 346 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 347 | return: | 
      
        |  |  | 348 | 	pop	count | 
      
        |  |  | 349 | 	out	SREG, count | 
      
        |  |  | 350 | 	pop	YL | 
      
        |  |  | 351 | 	pop	YH | 
      
        |  |  | 352 | 	pop	odd | 
      
        |  |  | 353 | 	pop	usbmask | 
      
        |  |  | 354 | 	pop	count | 
      
        |  |  | 355 | 	reti | 
      
        |  |  | 356 |  | 
      
        |  |  | 357 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 358 | ; Handle IN (SE0+26) | 
      
        |  |  | 359 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 360 | is_in: | 
      
        |  |  | 361 | 	lds	count, usb_tx_len | 
      
        |  |  | 362 | 	tst	count			; data ready? | 
      
        |  |  | 363 | 	breq	nak			; no, reply with NAK | 
      
        |  |  | 364 | 	lds	tmp, usb_rx_len | 
      
        |  |  | 365 | 	tst	tmp			; unprocessed input packet? | 
      
        |  |  | 366 | 	brne	nak			; yes, don't send old data for new packet | 
      
        |  |  | 367 | 	sts	usb_tx_len, tmp		; buffer is available again (after reti) | 
      
        |  |  | 368 | 	ldi	YL, lo8(usb_tx_buf) | 
      
        |  |  | 369 | 	ldi	YH, hi8(usb_tx_buf) | 
      
        |  |  | 370 | 	rjmp	send_packet		; SE0+40, SE0 --> SOP <= 51 | 
      
        |  |  | 371 |  | 
      
        |  |  | 372 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 373 | ; Handle DATA0/DATA1 (SE0+17) | 
      
        |  |  | 374 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 375 | is_data: | 
      
        |  |  | 376 | 	lds	pid, token_pid | 
      
        |  |  | 377 | 	tst	pid			; data following our SETUP/OUT | 
      
        |  |  | 378 | 	breq	ignore			; no, ignore | 
      
        |  |  | 379 | 	lds	tmp, usb_rx_len | 
      
        |  |  | 380 | 	tst	tmp			; buffer free? | 
      
        |  |  | 381 | 	brne	nak			; no, reply with NAK | 
      
        |  |  | 382 | 	sts	usb_rx_len, count	; pass buffer length | 
      
        |  |  | 383 | 	sts	usb_rx_token, pid	; pass PID of token (SETUP or OUT) | 
      
        |  |  | 384 | 	lds	count, usb_rx_off	; switch to other input buffer | 
      
        |  |  | 385 | 	ldi	tmp, USB_BUFSIZE | 
      
        |  |  | 386 | 	sub	tmp, count | 
      
        |  |  | 387 | 	sts	usb_rx_off, tmp | 
      
        |  |  | 388 |  | 
      
        |  |  | 389 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 390 | ; send ACK packet (SE0+35) | 
      
        |  |  | 391 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 392 | ack: | 
      
        |  |  | 393 | 	ldi	YL, lo8(tx_ack) | 
      
        |  |  | 394 | 	ldi	YH, hi8(tx_ack) | 
      
        |  |  | 395 | 	rjmp	send_token | 
      
        |  |  | 396 |  | 
      
        |  |  | 397 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 398 | ; send NAK packet (SE0+36) | 
      
        |  |  | 399 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 400 | nak: | 
      
        |  |  | 401 | 	ldi	YL, lo8(tx_nak) | 
      
        |  |  | 402 | 	ldi	YH, hi8(tx_nak) | 
      
        |  |  | 403 | send_token: | 
      
        |  |  | 404 | 	ldi	count, 1		; SE0+40, SE0 --> SOP <= 51 | 
      
        |  |  | 405 |  | 
      
        |  |  | 406 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 407 | ; acquire the bus and send a packet (11 cycles to SOP) | 
      
        |  |  | 408 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 409 | send_packet: | 
      
        |  |  | 410 | 	in	output, USB_OUT | 
      
        |  |  | 411 | 	cbr	output, USB_MASK | 
      
        |  |  | 412 | 	ori	output, USB_MASK_DMINUS | 
      
        |  |  | 413 | 	in	usbmask, USB_DDR | 
      
        |  |  | 414 | 	ori	usbmask, USB_MASK | 
      
        |  |  | 415 | 	out	USB_OUT, output		; idle state | 
      
        |  |  | 416 | 	out	USB_DDR, usbmask	; acquire bus | 
      
        |  |  | 417 | 	ldi	usbmask, USB_MASK | 
      
        |  |  | 418 | 	ldi	byte, 0x80		; start with sync byte | 
      
        |  |  | 419 |  | 
      
        |  |  | 420 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 421 | ; transmitter loop | 
      
        |  |  | 422 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 423 | txloop: | 
      
        |  |  | 424 | 	sbrs	byte, 0 | 
      
        |  |  | 425 | 	eor	output, usbmask | 
      
        |  |  | 426 | 	out	USB_OUT, output		; output bit 0 | 
      
        |  |  | 427 | 	ror	byte | 
      
        |  |  | 428 | 	ror	done | 
      
        |  |  | 429 | stuffed0: | 
      
        |  |  | 430 | 	cpi	done, 0xfc | 
      
        |  |  | 431 | 	brcc	stuff0 | 
      
        |  |  | 432 | 	sbrs	byte, 0 | 
      
        |  |  | 433 | 	eor	output, usbmask | 
      
        |  |  | 434 | 	ror	byte | 
      
        |  |  | 435 | stuffed1: | 
      
        |  |  | 436 | 	out	USB_OUT, output		; output bit 1 | 
      
        |  |  | 437 | 	ror	done | 
      
        |  |  | 438 | 	cpi	done, 0xfc | 
      
        |  |  | 439 | 	brcc	stuff1 | 
      
        |  |  | 440 | 	sbrs	byte, 0 | 
      
        |  |  | 441 | 	eor	output, usbmask | 
      
        |  |  | 442 | 	ror	byte | 
      
        |  |  | 443 | 	nop | 
      
        |  |  | 444 | stuffed2: | 
      
        |  |  | 445 | 	out	USB_OUT, output		; output bit 2 | 
      
        |  |  | 446 | 	ror	done | 
      
        |  |  | 447 | 	cpi	done, 0xfc | 
      
        |  |  | 448 | 	brcc	stuff2 | 
      
        |  |  | 449 | 	sbrs	byte, 0 | 
      
        |  |  | 450 | 	eor	output, usbmask | 
      
        |  |  | 451 | 	ror	byte | 
      
        |  |  | 452 | 	nop | 
      
        |  |  | 453 | stuffed3: | 
      
        |  |  | 454 | 	out	USB_OUT, output		; output bit 3 | 
      
        |  |  | 455 | 	ror	done | 
      
        |  |  | 456 | 	cpi	done, 0xfc | 
      
        |  |  | 457 | 	brcc	stuff3 | 
      
        |  |  | 458 | 	sbrs	byte, 0 | 
      
        |  |  | 459 | 	eor	output, usbmask | 
      
        |  |  | 460 | 	ld	next, Y+		; 2 cycles | 
      
        |  |  | 461 | 	out	USB_OUT, output		; output bit 4 | 
      
        |  |  | 462 | 	ror	byte | 
      
        |  |  | 463 | 	ror	done | 
      
        |  |  | 464 | stuffed4: | 
      
        |  |  | 465 | 	cpi	done, 0xfc | 
      
        |  |  | 466 | 	brcc	stuff4 | 
      
        |  |  | 467 | 	sbrs	byte, 0 | 
      
        |  |  | 468 | 	eor	output, usbmask | 
      
        |  |  | 469 | 	ror	byte | 
      
        |  |  | 470 | stuffed5: | 
      
        |  |  | 471 | 	out	USB_OUT, output		; output bit 5 | 
      
        |  |  | 472 | 	ror	done | 
      
        |  |  | 473 | 	cpi	done, 0xfc | 
      
        |  |  | 474 | 	brcc	stuff5 | 
      
        |  |  | 475 | 	sbrs	byte, 0 | 
      
        |  |  | 476 | 	eor	output, usbmask | 
      
        |  |  | 477 | 	ror	byte | 
      
        |  |  | 478 | stuffed6: | 
      
        |  |  | 479 | 	ror	done | 
      
        |  |  | 480 | 	out	USB_OUT, output		; output bit 6 | 
      
        |  |  | 481 | 	cpi	done, 0xfc | 
      
        |  |  | 482 | 	brcc	stuff6 | 
      
        |  |  | 483 | 	sbrs	byte, 0 | 
      
        |  |  | 484 | 	eor	output, usbmask | 
      
        |  |  | 485 | 	ror	byte | 
      
        |  |  | 486 | 	mov	byte, next | 
      
        |  |  | 487 | stuffed7: | 
      
        |  |  | 488 | 	ror	done | 
      
        |  |  | 489 | 	out	USB_OUT, output		; output bit 7 | 
      
        |  |  | 490 | 	cpi	done, 0xfc | 
      
        |  |  | 491 | 	brcc	stuff7 | 
      
        |  |  | 492 | 	dec	count | 
      
        |  |  | 493 | 	brpl	txloop			; 2 cycles | 
      
        |  |  | 494 |  | 
      
        |  |  | 495 | 	rjmp	gen_eop | 
      
        |  |  | 496 |  | 
      
        |  |  | 497 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 498 | ; out-of-line code to insert stuffing bits | 
      
        |  |  | 499 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 500 | stuff0:					; 2+3 | 
      
        |  |  | 501 | 	eor	output, usbmask | 
      
        |  |  | 502 | 	clr	done | 
      
        |  |  | 503 | 	out	USB_OUT, output | 
      
        |  |  | 504 | 	rjmp	stuffed0 | 
      
        |  |  | 505 |  | 
      
        |  |  | 506 | stuff1:					; 3 | 
      
        |  |  | 507 | 	eor	output, usbmask | 
      
        |  |  | 508 | 	rjmp	stuffed1 | 
      
        |  |  | 509 |  | 
      
        |  |  | 510 | stuff2:					; 3 | 
      
        |  |  | 511 | 	eor	output, usbmask | 
      
        |  |  | 512 | 	rjmp	stuffed2 | 
      
        |  |  | 513 |  | 
      
        |  |  | 514 | stuff3:					; 3 | 
      
        |  |  | 515 | 	eor	output, usbmask | 
      
        |  |  | 516 | 	rjmp	stuffed3 | 
      
        |  |  | 517 |  | 
      
        |  |  | 518 | stuff4:					; 2+3 | 
      
        |  |  | 519 | 	eor	output, usbmask | 
      
        |  |  | 520 | 	clr	done | 
      
        |  |  | 521 | 	out	USB_OUT, output | 
      
        |  |  | 522 | 	rjmp	stuffed4 | 
      
        |  |  | 523 |  | 
      
        |  |  | 524 | stuff5:					; 3 | 
      
        |  |  | 525 | 	eor	output, usbmask | 
      
        |  |  | 526 | 	rjmp	stuffed5 | 
      
        |  |  | 527 |  | 
      
        |  |  | 528 | stuff6:					; 3 | 
      
        |  |  | 529 | 	eor	output, usbmask | 
      
        |  |  | 530 | 	rjmp	stuffed6 | 
      
        |  |  | 531 |  | 
      
        |  |  | 532 | stuff7:					; 3 | 
      
        |  |  | 533 | 	eor	output, usbmask | 
      
        |  |  | 534 | 	rjmp	stuffed7 | 
      
        |  |  | 535 |  | 
      
        |  |  | 536 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 537 | ; generate EOP, release the bus, and return from interrupt | 
      
        |  |  | 538 | ; ---------------------------------------------------------------------- | 
      
        |  |  | 539 | gen_eop: | 
      
        |  |  | 540 | 	cbr	output, USB_MASK | 
      
        |  |  | 541 | 	out	USB_OUT, output		; output SE0 for 2 bit times | 
      
        |  |  | 542 | 	pop	even | 
      
        |  |  | 543 | 	pop	fixup | 
      
        |  |  | 544 | 	pop	byte | 
      
        |  |  | 545 | 	ldi	count, 1<<USB_INT_PENDING_BIT | 
      
        |  |  | 546 | 	out	USB_INT_PENDING, count	; interrupt was triggered by transmit | 
      
        |  |  | 547 | 	pop	YH			; this is the saved SREG | 
      
        |  |  | 548 | 	pop	YL | 
      
        |  |  | 549 | 	in	usbmask, USB_DDR | 
      
        |  |  | 550 | 	mov	count, output | 
      
        |  |  | 551 | 	ori	output, USB_MASK_DMINUS | 
      
        |  |  | 552 | 	out	USB_OUT, output		; output J state for 1 bit time | 
      
        |  |  | 553 | 	cbr	usbmask, USB_MASK | 
      
        |  |  | 554 | 	out	SREG, YH | 
      
        |  |  | 555 | 	pop	YH | 
      
        |  |  | 556 | 	pop	odd			; is the same register as output! | 
      
        |  |  | 557 | 	nop | 
      
        |  |  | 558 | 	out	USB_DDR, usbmask	; release bus | 
      
        |  |  | 559 | 	out	USB_OUT, count		; disable D- pullup | 
      
        |  |  | 560 | 	pop	usbmask | 
      
        |  |  | 561 | 	pop	count | 
      
        |  |  | 562 | 	reti |