📄 usbdrvasm15.inc
字号:
andi shift, 0x9f ;1 [06] 0b10011111 breq unstuff4 ;1 [07] nop2 ;2 [08+09] in x2, USBIN ;1 [00] [10] <-- sample bit 5 andi x2, USBMASK ;1 [01] breq se0 ;1 [02] SE0 check for bit 5 eor x1, x2 ;1 [03] bst x1, USBMINUS ;1 [04] bld shift, 5 ;1 [05]didUnstuff5: ;- [05] andi shift, 0x3f ;1 [06] 0b00111111 breq unstuff5 ;1 [07] nop2 ;2 [08+09] in x1, USBIN ;1 [00] [10] <-- sample bit 6 andi x1, USBMASK ;1 [01] breq se0 ;1 [02] SE0 check for bit 6 eor x2, x1 ;1 [03] bst x2, USBMINUS ;1 [04] bld shift, 6 ;1 [05]didUnstuff6: ;- [05] cpi shift, 0x02 ;1 [06] 0b00000010 brlo unstuff6 ;1 [07] nop2 ;2 [08+09] in x2, USBIN ;1 [00] [10] <-- sample bit 7 andi x2, USBMASK ;1 [01] breq se0 ;1 [02] SE0 check for bit 7 eor x1, x2 ;1 [03] bst x1, USBMINUS ;1 [04] bld shift, 7 ;1 [05]didUnstuff7: ;- [05] cpi shift, 0x04 ;1 [06] 0b00000100 brlo unstuff7 ;1 [07] eor x3, shift ;1 [08] reconstruct: x3 is 0 at bit locations we changed, 1 at others nop ;1 [09] in x1, USBIN ;1 [00] [10] <-- sample bit 0 st y+, x3 ;2 [01+02] store data eor x2, x1 ;1 [03] bst x2, USBMINUS ;1 [04] bld shift, 0 ;1 [05] subi cnt, 1 ;1 [06] brcs overflow ;1 [07] rjmp rxLoop ;2 [08];-----------------------------------------------------unstuff4: ;- [08] andi x3, ~0x10 ;1 [09] in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 4 andi x1, USBMASK ;1 [01] breq se0 ;1 [02] SE0 check for stuffed bit 4 ori shift, 0x10 ;1 [03] rjmp didUnstuff4 ;2 [04];-----------------------------------------------------unstuff5: ;- [08] ori shift, 0x20 ;1 [09] in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 5 andi x2, USBMASK ;1 [01] breq se0 ;1 [02] SE0 check for stuffed bit 5 andi x3, ~0x20 ;1 [03] rjmp didUnstuff5 ;2 [04];-----------------------------------------------------unstuff6: ;- [08] andi x3, ~0x40 ;1 [09] in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 6 andi x1, USBMASK ;1 [01] breq se0 ;1 [02] SE0 check for stuffed bit 6 ori shift, 0x40 ;1 [03] rjmp didUnstuff6 ;2 [04];-----------------------------------------------------unstuff7: ;- [08] andi x3, ~0x80 ;1 [09] in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 7 andi x2, USBMASK ;1 [01] breq se0 ;1 [02] SE0 check for stuffed bit 7 ori shift, 0x80 ;1 [03] rjmp didUnstuff7 ;2 [04] macro POP_STANDARD ; 16 cycles pop x4 pop cnt pop bitcnt pop x3 pop x2 pop x1 pop shift pop YH endmmacro POP_RETI ; 5 cycles pop YL out SREG, YL pop YL endm#include "asmcommon.inc";---------------------------------------------------------------------------; USB spec says:; idle = J; J = (D+ = 0), (D- = 1); K = (D+ = 1), (D- = 0); Spec allows 7.5 bit times from EOP to SOP for replies;---------------------------------------------------------------------------bitstuffN: ;- [04] eor x1, x4 ;1 [05] clr x2 ;1 [06] nop ;1 [07] rjmp didStuffN ;1 [08];--------------------------------------------------------------------------- bitstuff6: ;- [04] eor x1, x4 ;1 [05] clr x2 ;1 [06] rjmp didStuff6 ;1 [07];---------------------------------------------------------------------------bitstuff7: ;- [02] eor x1, x4 ;1 [03] clr x2 ;1 [06] nop ;1 [05] rjmp didStuff7 ;1 [06];---------------------------------------------------------------------------sendNakAndReti: ;- [-19] ldi x3, USBPID_NAK ;1 [-18] rjmp sendX3AndReti ;1 [-17];---------------------------------------------------------------------------sendAckAndReti: ;- [-17] ldi cnt, USBPID_ACK ;1 [-16]sendCntAndReti: ;- [-16] mov x3, cnt ;1 [-15]sendX3AndReti: ;- [-15] ldi YL, 20 ;1 [-14] x3==r20 address is 20 ldi YH, 0 ;1 [-13] ldi cnt, 2 ;1 [-12]; rjmp usbSendAndReti fallthrough;---------------------------------------------------------------------------;usbSend:;pointer to data in 'Y';number of bytes in 'cnt' -- including sync byte [range 2 ... 12];uses: x1...x4, btcnt, shift, cnt, Y;Numbers in brackets are time since first bit of sync pattern is sent;We need not to match the transfer rate exactly because the spec demands ;only 1.5% precision anyway.usbSendAndReti: ;- [-13] 13 cycles until SOP in x2, USBDDR ;1 [-12] ori x2, USBMASK ;1 [-11] sbi USBOUT, USBMINUS ;2 [-09-10] prepare idle state; D+ and D- must have been 0 (no pullups) in x1, USBOUT ;1 [-08] port mirror for tx loop out USBDDR, x2 ;1 [-07] <- acquire bus ; need not init x2 (bitstuff history) because sync starts with 0 ldi x4, USBMASK ;1 [-06] exor mask ldi shift, 0x80 ;1 [-05] sync byte is first byte sent ldi bitcnt, 6 ;1 [-04] txBitLoop: ;- [-04] [06] sbrs shift, 0 ;1 [-03] [07] eor x1, x4 ;1 [-02] [08] ror shift ;1 [-01] [09] didStuffN: ;- [09] out USBOUT, x1 ;1 [00] [10] <-- out N ror x2 ;1 [01] cpi x2, 0xfc ;1 [02] brcc bitstuffN ;1 [03] dec bitcnt ;1 [04] brne txBitLoop ;1 [05] sbrs shift, 0 ;1 [06] eor x1, x4 ;1 [07] ror shift ;1 [08]didStuff6: ;- [08] nop ;1 [09] out USBOUT, x1 ;1 [00] [10] <-- out 6 ror x2 ;1 [01] cpi x2, 0xfc ;1 [02] brcc bitstuff6 ;1 [03] sbrs shift, 0 ;1 [04] eor x1, x4 ;1 [05] ror shift ;1 [06] ror x2 ;1 [07]didStuff7: ;- [07] ldi bitcnt, 6 ;1 [08] cpi x2, 0xfc ;1 [09] out USBOUT, x1 ;1 [00] [10] <-- out 7 brcc bitstuff7 ;1 [01] ld shift, y+ ;2 [02+03] dec cnt ;1 [04] brne txBitLoop ;1 [05]makeSE0: cbr x1, USBMASK ;1 [06] prepare SE0 [spec says EOP may be 19 to 23 cycles] lds x2, usbNewDeviceAddr;2 [07+08] lsl x2 ;1 [09] we compare with left shifted address;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:;set address only after data packet was sent, not after handshake out USBOUT, x1 ;1 [00] [10] <-- out SE0-- from now 2 bits==20 cycl. until bus idle subi YL, 20 + 2 ;1 [01] Only assign address on data packets, not ACK/NAK in x3 sbci YH, 0 ;1 [02] breq skipAddrAssign ;1 [03] sts usbDeviceAddr, x2 ;2 [04+05] if not skipped: SE0 is one cycle longer;----------------------------------------------------------------------------;end of usbDeviceAddress transferskipAddrAssign: ;- [03/04] ldi x2, 1<<USB_INTR_PENDING_BIT ;1 [05] int0 occurred during TX -- clear pending flag USB_STORE_PENDING(x2) ;1 [06] ori x1, USBIDLE ;1 [07] in x2, USBDDR ;1 [08] cbr x2, USBMASK ;1 [09] set both pins to input mov x3, x1 ;1 [10] cbr x3, USBMASK ;1 [11] configure no pullup on both pins ldi x4, 3 ;1 [12]se0Delay: ;- [12] [15] dec x4 ;1 [13] [16] brne se0Delay ;1 [14] [17] nop2 ;2 [18+19] out USBOUT, x1 ;1 [20] <--out J (idle) -- end of SE0 (EOP sig.) out USBDDR, x2 ;1 [21] <--release bus now out USBOUT, x3 ;1 [22] <--ensure no pull-up resistors are active rjmp doReturn ;1 [23];---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -