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

📄 usb90s2313.asm

📁 USB技术大全-54.8M.zip
💻 ASM
📖 第 1 页 / 共 5 页
字号:
		sts	OutputBufferBegin+1,temp0	;nahraj do vyst buffera
ComposeZeroAnswer:
		ldi	temp0,SOPbyte
		sts	OutputBufferBegin+0,temp0	;SOP byte
		rcall	ToggleDATAPID			;zmen DATAPID
		ldi	temp0,0x00
		sts	OutputBufferBegin+2,temp0	;CRC byte
		sts	OutputBufferBegin+3,temp0	;CRC byte
		ldi	ByteCount,2+2			;dlzka vystupneho buffera (SOP a PID + CRC16)
		ret
;------------------------------------------------------------------------------------------
InitACKBufffer:
		ldi	temp0,SOPbyte
		sts	ACKBufferBegin+0,temp0		;SOP byte
		ldi	temp0,ACKPID
		sts	ACKBufferBegin+1,temp0		;ACKPID byte
		ret
;------------------------------------------------------------------------------------------
SendACK:
		push	USBBufptrY
		push	bitcount
		push	OutBitStuffNumber
		ldi	USBBufptrY,ACKBufferBegin	;pointer na zaciatok ACK buffera
		ldi	ByteCount,2			;pocet vyslanych bytov (iba SOP a ACKPID)
		clr	OutBitStuffNumber
		rcall	SendUSBBuffer
		pop	OutBitStuffNumber
		pop	bitcount
		pop	USBBufptrY
		ret
;------------------------------------------------------------------------------------------
InitNAKBufffer:
		ldi	temp0,SOPbyte
		sts	NAKBufferBegin+0,temp0		;SOP byte
		ldi	temp0,NAKPID
		sts	NAKBufferBegin+1,temp0		;NAKPID byte
		ret
;------------------------------------------------------------------------------------------
SendNAK:
		push	OutBitStuffNumber
		ldi	USBBufptrY,NAKBufferBegin	;pointer na zaciatok ACK buffera
		ldi	ByteCount,2			;pocet vyslanych bytov (iba SOP a NAKPID)
		clr	OutBitStuffNumber
		rcall	SendUSBBuffer
		pop	OutBitStuffNumber
		ret
;------------------------------------------------------------------------------------------
ComposeSTALL:
		ldi	temp0,SOPbyte
		sts	OutputBufferBegin+0,temp0	;SOP byte
		ldi	temp0,STALLPID
		sts	OutputBufferBegin+1,temp0	;STALLPID byte
		ldi	ByteCount,2			;dlzka vystupneho buffera (SOP a PID)
		ret
;------------------------------------------------------------------------------------------
DecodeNRZI:	;enkodovanie buffera z NRZI kodu do binarneho
		push	USBBufptrY		;zalohuj pointer do buffera
		push	ByteCount		;zalohuj dlzku buffera
		add	ByteCount,USBBufptrY	;koniec buffera do ByteCount
		ser	temp0			;na zabezpecenie jednotkoveho carry (v nasledujucej rotacii)
NRZIloop:
		ror	temp0			;naplnenie carry z predchadzajuceho byte
		ld	temp0,Y			;nahraj prijaty byte z buffera
		mov	temp2,temp0		;posunuty register o jeden bit vpravo a XOR na funkciu NRZI dekodovania
		ror	temp2			;carry do najvyssieho bitu a sucasne posuv
		eor	temp2,temp0		;samotne dekodovanie NRZI
		com	temp2			;negovanie
		st	Y+,temp2		;ulozenie spat ako dekodovany byte a zvys pointer do buffera
		cp	USBBufptrY,ByteCount	;ak este neboli vsetky
		brne	NRZIloop		;tak opakuj
		pop	ByteCount		;obnov dlzku buffera
		pop	USBBufptrY		;obnov pointer do buffera
		ret				;inak skonci
;------------------------------------------------------------------------------------------
BitStuff:	;odstranenie bit-stuffingu v buffri
		clr	temp3			;pocitadlo vynechanych bitov
		clr	lastBitstufNumber	;0xFF do lastBitstufNumber
		dec	lastBitstufNumber
BitStuffRepeat:
		push	USBBufptrY		;zalohuj pointer do buffera
		push	ByteCount		;zalohuj dlzku buffera
		mov	temp1,temp3		;pocitadlo vsetkych bitov
		ldi	temp0,8			;spocitat vsetky bity v bufferi
SumAllBits:
		add	temp1,temp0
		dec	ByteCount
		brne	SumAllBits
		ldi	temp2,6			;inicializuj pocitadlo jednotiek
		pop	ByteCount		;obnov dlzku buffera
		push	ByteCount		;zalohuj dlzku buffera
		add	ByteCount,USBBufptrY	;koniec buffera do ByteCount
		inc	ByteCount		;a pre istotu ho zvys o 2 (kvoli posuvaniu)
		inc	ByteCount
BitStuffLoop:
		ld	temp0,Y			;nahraj prijaty byte z buffera
		ldi	bitcount,8		;pocitadlo bitov v byte
BitStuffByteLoop:
		ror	temp0			;naplnenie carry z LSB
		brcs	IncrementBitstuff	;ak LSB=0
		ldi	temp2,7			;inicializuj pocitadlo jednotiek +1 (ak bola nula)
IncrementBitstuff:
		dec	temp2			;zniz pocitadlo jednotiek (predpoklad jednotkoveho bitu)
		brne	DontShiftBuffer		;ak este nebolo 6 jednotiek za sebou - neposun buffer
		cp	temp1,lastBitstufNumber	;
		ldi	temp2,6			;inicializuj pocitadlo jednotiek (ak by sa nerobil bitstuffing tak sa musi zacat odznova)
		brcc	DontShiftBuffer		;ak sa tu uz robil bitstuffing - neposun buffer

		dec	temp1
		mov	lastBitstufNumber,temp1	;zapamataj si poslednu poziciu bitstuffingu
		cpi	bitcount,1		;aby sa ukazovalo na 7 bit (ktory sa ma vymazat alebo kde sa ma vlozit nula)
		brne	NoBitcountCorrect
		ldi	bitcount,9
		inc	USBBufptrY		;zvys pointer do buffera
NoBitcountCorrect:
		dec	bitcount
		bst	BitStuffInOut,0
		brts	CorrectOutBuffer	;ak je Out buffer - zvys dlzku buffera
		rcall	ShiftDeleteBuffer	;posun In buffer
		dec	temp3			;zniz pocitadlo vynechani
		rjmp	CorrectBufferEnd
CorrectOutBuffer:
		rcall	ShiftInsertBuffer	;posun Out buffer
		inc	temp3			;zvys pocitadlo vynechani
CorrectBufferEnd:
		pop	ByteCount		;obnov dlzku buffera
		pop	USBBufptrY		;obnov pointer do buffera
		rjmp	BitStuffRepeat		;a restartni od zaciatku
DontShiftBuffer:
		dec	temp1			;ak uz boli vsetky bity
		breq	EndBitStuff		;ukonci cyklus
		dec	bitcount		;zniz pocitadlo bitov v byte
		brne	BitStuffByteLoop	;ak este neboli vsetky bity v byte - chod na dalsi bit
						;inak nahraj dalsi byte
		inc	USBBufptrY		;zvys pointer do buffera
		rjmp	BitStuffLoop		;a opakuj
EndBitStuff:
		pop	ByteCount		;obnov dlzku buffera
		pop	USBBufptrY		;obnov pointer do buffera
		bst	BitStuffInOut,0
		brts	IncrementLength		;ak je Out buffer - zvys dlzku Out buffera
DecrementLength:				;ak je In buffer - zniz dlzku In buffera
		cpi	temp3,0			;bolo aspon jedno znizenie
		breq	NoChangeByteCount	;ak nie - nemen dlzku buffera
		dec	ByteCount		;ak je In buffer - zniz dlzku buffera
		subi	temp3,256-8		;ak nebolo viac ako 8 bitov naviac
		brcc	NoChangeByteCount	;tak skonci
		dec	ByteCount		;inak este zniz dlzku buffera
		ret				;a skonci
IncrementLength:
		mov	OutBitStuffNumber,temp3	;zapamataj si pocet bitov naviac
		subi	temp3,8			;ak nebolo viac ako 8 bitov naviac
		brcs	NoChangeByteCount	;tak skonci
		inc	ByteCount		;inak zvys dlzku buffera
		mov	OutBitStuffNumber,temp3	;a zapamataj si pocet bitov naviac (znizene o 8)
NoChangeByteCount:
		ret				;skonci
;------------------------------------------------------------------------------------------
ShiftInsertBuffer:	;posuv buffera o jeden bit vpravo od konca az po poziciu: byte-USBBufptrY a bit-bitcount
		mov	temp0,bitcount		;vypocet: bitcount= 9-bitcount
		ldi	bitcount,9
		sub	bitcount,temp0		;do bitcount poloha bitu, ktory treba nulovat

		ld	temp1,Y			;nahraj byte ktory este treba posunut od pozicie bitcount
		rol	temp1			;a posun vlavo cez Carry (prenos z vyssieho byte a LSB do Carry)
		ser	temp2			;FF do masky - temp2
HalfInsertPosuvMask:
		lsl	temp2			;nula do dalsieho spodneho bitu masky
		dec	bitcount		;az pokial sa nedosiahne hranica posuvania v byte
		brne	HalfInsertPosuvMask

		and	temp1,temp2		;odmaskuj aby zostali iba vrchne posunute bity v temp1
		com	temp2			;invertuj masku
		lsr	temp2			;posun masku vpravo - na vlozenie nuloveho bitu
		ld	temp0,Y			;nahraj byte ktory este treba posunut od pozicie bitcount do temp0
		and	temp0,temp2		;odmaskuj aby zostali iba spodne neposunute bity v temp0
		or	temp1,temp0		;a zluc posunutu a neposunutu cast

		ld	temp0,Y			;nahraj byte ktory este treba posunut od pozicie bitcount
		rol	temp0			;a posun ho vlavo cez Carry (aby sa nastavilo spravne Carry pre dalsie prenosy)
		st	Y+,temp1		;a nahraj spat upraveny byte
ShiftInsertBufferLoop:
		cpse	USBBufptrY,ByteCount	;ak nie su vsetky cele byty
		rjmp	NoEndShiftInsertBuffer	;tak pokracuj
		ret				;inak skonci
NoEndShiftInsertBuffer:
		ld	temp1,Y			;nahraj byte
		rol	temp1			;a posun vlavo cez Carry (prenos z nizsieho byte a LSB do Carry)
		st	Y+,temp1		;a nahraj spat
		rjmp	ShiftInsertBufferLoop	;a pokracuj
;------------------------------------------------------------------------------------------
ShiftDeleteBuffer:	;posuv buffera o jeden bit vlavo od konca az po poziciu: byte-USBBufptrY a bit-bitcount
		mov	temp0,bitcount		;vypocet: bitcount= 9-bitcount
		ldi	bitcount,9
		sub	bitcount,temp0		;do bitcount poloha bitu, ktory este treba posunut
		mov	temp0,USBBufptrY	;uschovanie pointera do buffera
		inc	temp0			;pozicia celych bytov do temp0
		mov	USBBufptrY,ByteCount	;maximalna pozicia do pointra
ShiftDeleteBufferLoop:
		ld	temp1,-Y		;zniz buffer a nahraj byte
		ror	temp1			;a posun vpravo cez Carry (prenos z vyssieho byte a LSB do Carry)
		st	Y,temp1			;a nahraj spat
		cpse	USBBufptrY,temp0	;ak nie su vsetky cele byty
		rjmp	ShiftDeleteBufferLoop	;tak pokracuj

		ld	temp1,-Y		;zniz buffer a nahraj byte ktory este treba posunut od pozicie bitcount
		ror	temp1			;a posun vpravo cez Carry (prenos z vyssieho byte a LSB do Carry)
		ser	temp2			;FF do masky - temp2
HalfDeletePosuvMask:
		dec	bitcount		;az pokial sa nedosiahne hranica posuvania v byte
		breq	DoneMask
		lsl	temp2			;nula do dalsieho spodneho bitu masky
		rjmp	HalfDeletePosuvMask
DoneMask:
		and	temp1,temp2		;odmaskuj aby zostali iba vrchne posunute bity v temp1
		com	temp2			;invertuj masku
		ld	temp0,Y			;nahraj byte ktory este treba posunut od pozicie bitcount do temp0
		and	temp0,temp2		;odmaskuj aby zostali iba spodne neposunute bity v temp0
		or	temp1,temp0		;a zluc posunutu a neposunutu cast
		st	Y,temp1			;a nahraj spat
		ret				;a skonci
;------------------------------------------------------------------------------------------
MirrorInBufferBytes:
		push	USBBufptrY
		push	ByteCount
		ldi	USBBufptrY,InputBufferBegin
		rcall	MirrorBufferBytes
		pop	ByteCount
		pop	USBBufptrY
		ret
;------------------------------------------------------------------------------------------
MirrorBufferBytes:
		add	ByteCount,USBBufptrY	;ByteCount ukazuje na koniec spravy
MirrorBufferloop:
		ld	temp0,Y			;nahraj prijaty byte z buffera
		ldi	temp1,8			;pocitadlo bitov
MirrorBufferByteLoop:
		ror	temp0			;do carry dalsi najnizsi bit
		rol	temp2			;z carry dalsi bit na obratene poradie
		dec	temp1			;bol uz cely byte
		brne	MirrorBufferByteLoop	;ak nie tak opakuj dalsi najnizsi bit
		st	Y+,temp2		;ulozenie spat ako obrateny byte  a zvys pointer do buffera
		cp	USBBufptrY,ByteCount	;ak este neboli vsetky
		brne	MirrorBufferloop	;tak opakuj
		ret				;inak skonci
;------------------------------------------------------------------------------------------
;CheckCRCIn:
;		push	USBBufptrY
;		push	ByteCount
;		ldi	USBBufptrY,InputBufferBegin
;		rcall	CheckCRC
;		pop	ByteCount
;		pop	USBBufptrY
;		ret
;------------------------------------------------------------------------------------------
AddCRCOut:
		push	USBBufptrY
		push	ByteCount
		ldi	USBBufptrY,OutputBufferBegin
		rcall	CheckCRC
		com	temp0			;negacia CRC
		com	temp1
		st	Y+,temp1		;ulozenie CRC na koniec buffera (najskor MSB)
		st	Y,temp0			;ulozenie CRC na koniec buffera (potom LSB)
		dec	USBBufptrY		;pointer na poziciu CRC
		ldi	ByteCount,2		;otocit 2 byty CRC
		rcall	MirrorBufferBytes	;opacne poradie bitov CRC (pri vysielani CRC sa posiela naskor MSB)
		pop	ByteCount
		pop	USBBufptrY
		ret
;------------------------------------------------------------------------------------------
CheckCRC:	;vstup: USBBufptrY = zaciatok spravy	,ByteCount = dlzka spravy
		add	ByteCount,USBBufptrY	;ByteCount ukazuje na koniec spravy
		inc	USBBufptrY		;nastav pointer na zaciatok spravy - vynechat SOP
		ld	temp0,Y+		;nahraj PID do temp0
						;a nastav pointer na zaciatok spravy - vynechat aj PID
		cpi	temp0,DATA0PID		;ci je DATA0 pole
		breq	ComputeDATACRC		;pocitaj CRC16
		cpi	temp0,DATA1PID		;ci je DATA1 pole
		brne	CRC16End		;ak nie tak skonci
ComputeDATACRC:
		ser	temp0			;inicializacia zvysku LSB na 0xff
		ser	temp1			;inicializacia zvysku MSB na 0xff
CRC16Loop:
		ld	temp2,Y+		;nahraj spravu do temp2 a zvys pointer do buffera
		ldi	temp3,8			;pocitadlo bitov v byte - temp3
CRC16LoopByte:
		bst	temp1,7			;do T uloz MSB zvysku (zvysok je iba 16 bitovy - 8 bit vyssieho byte)
		bld	bitcount,0		;do bitcount LSB uloz T - MSB zvysku
		eor	bitcount,temp2		;XOR bitu spravy a bitu zvysku - v LSB bitcount
		rol	temp0			;posun zvysok dolava - nizsi byte (dva byty - cez carry)
		rol	temp1			;posun zvysok dolava - vyssi byte (dva byty - cez carry)
		cbr	temp0,1			;znuluj LSB zvysku
		lsr	temp2			;posun spravu doprava
		ror	bitcount		;vysledok XOR-u bitov z LSB do carry
		brcc	CRC16NoXOR		;ak je XOR bitu spravy a MSB zvysku = 0 , tak nerob XOR
		ldi	bitcount,CRC16poly>>8	;do bitcount CRC polynom - vrchny byte
		eor	temp1,bitcount		;a urob XOR zo zvyskom a CRC polynomom - vrchny byte
		ldi	bitcount,CRC16poly	;do bitcount CRC polynom - spodny byte
		eor	temp0,bitcount		;a urob XOR zo zvyskom a CRC polynomom - spodny byte
CRC16NoXOR:

⌨️ 快捷键说明

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