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

📄 usb90s2313.asm

📁 USB技术大全-54.8M.zip
💻 ASM
📖 第 1 页 / 共 5 页
字号:
		mov	ByteCount,InputBufferLength	;dlzka vstupneho buffera
		rcall	DecodeNRZI		;prevod kodovania NRZI na bity
		rcall	MirrorInBufferBytes	;prehodit poradie bitov v bajtoch
		rcall	BitStuff		;odstranenie bit stuffing
		;rcall	CheckCRCIn		;kontrola CRC
		rcall	PrepareUSBOutAnswer	;pripravenie odpovede do vysielacieho buffera
		ldi	ActionFlag,DoReadySendAnswer
		rjmp	Main
;********************************************************************
;* Main program END
;********************************************************************
;------------------------------------------------------------------------------------------
;********************************************************************
;* Interrupt0 interrupt handler
;********************************************************************
INT0Handler:					;prerusenie INT0
		in	backupSREG,SREG
		push	temp0
		push	temp1

		ldi	temp0,3			;pocitadlo trvania log0
		ldi	temp1,2			;pocitadlo trvania log1
		;cakanie na zaciatok paketu
CheckchangeMinus:
		sbis	inputport,DATAminus	;cakanie az sa zmeni D- na 1
		rjmp	CheckchangeMinus
CheckchangePlus:
		sbis	inputport,DATAplus	;cakanie az sa zmeni D+ na 1
		rjmp	CheckchangePlus
DetectSOPEnd:
		sbis	inputport,DATAplus
		rjmp	Increment0		;D+ =0
Increment1:
		ldi	temp0,3			;pocitadlo trvania log0
		dec	temp1			;kolko cyklov trvala log1
		nop
		breq	USBBeginPacket		;ak je to koniec SOP - prijimaj paket
		rjmp	DetectSOPEnd
Increment0:
		ldi	temp1,2			;pocitadlo trvania log1
		dec	temp0			;kolko cyklov trvala log0
		nop
		brne	DetectSOPEnd		;ak nenastal SOF - pokracuj
		rjmp	EndInt0HandlerPOP2
EndInt0Handler:
		pop	ACC
		pop	RS232BufptrX
		pop	temp3
		pop	temp2
EndInt0HandlerPOP:
		pop	USBBufptrY
		pop	ByteCount
		mov	bitcount,backupbitcount	;obnova bitcount registra
EndInt0HandlerPOP2:
		pop	temp1
		pop	temp0
		out	SREG,backupSREG
		ldi	shiftbuf,1<<INTF0	;znulovat flag interruptu INTF0
		out	GIFR,shiftbuf
		reti				;inak skonci (bol iba SOF - kazdu milisekundu)

USBBeginPacket:
		mov	backupbitcount,bitcount	;zaloha bitcount registra
		in	shiftbuf,inputport	;ak ano nacitaj ho ako nulty bit priamo do shift registra
USBloopBegin:
		push	ByteCount		;dalsia zaloha registrov (setrenie casu)
		push	USBBufptrY
		ldi	bitcount,6		;inicializacia pocitadla bitov v bajte
		ldi	ByteCount,MAXUSBBYTES	;inicializacia max poctu prijatych bajtov v pakete
		ldi	USBBufptrY,InputShiftBufferBegin	;nastav vstupny buffer
USBloop1_6:
		in	inputbuf,inputport
		cbr	inputbuf,USBpinmask	;odmaskovat spodne 2 bity
		breq	USBloopEnd		;ak su nulove - koniec USB packetu
		ror	inputbuf		;presun Data+ do shift registra
		rol	shiftbuf
		dec	bitcount		;zmensi pocitadlo bitov
		brne	USBloop1_6		;ak nie je nulove - opakuj naplnanie shift registra
		nop				;inak bude nutne skopirovat shift register bo buffera
USBloop7:
		in	inputbuf,inputport
		cbr	inputbuf,USBpinmask	;odmaskovat spodne 2 bity
		breq	USBloopEnd		;ak su nulove - koniec USB packetu
		ror	inputbuf		;presun Data+ do shift registra
		rol	shiftbuf
		ldi	bitcount,7		;inicializacia pocitadla bitov v bajte
		st	Y+,shiftbuf		;skopiruj shift register bo buffera a zvys pointer do buffera
USBloop0:					;a zacni prijimat dalsi bajt
		in	shiftbuf,inputport	;nulty bit priamo do shift registra
		cbr	shiftbuf,USBpinmask	;odmaskovat spodne 2 bity
		breq	USBloopEnd		;ak su nulove - koniec USB packetu
		dec	bitcount		;zmensi pocitadlo bitov
		nop				;
		dec	ByteCount		;ak sa nedosiahol maximum buffera
		brne	USBloop1_6		;tak prijimaj dalej

		rjmp	EndInt0HandlerPOP	;inak opakuj od zaciatku

USBloopEnd:
		cpi	USBBufptrY,InputShiftBufferBegin+3	;ak sa neprijali aspon 3 byte
		brcs	EndInt0HandlerPOP	;tak skonci
		lds	temp0,InputShiftBufferBegin+0	;identifikator paketu do temp0
		lds	temp1,InputShiftBufferBegin+1	;adresa do temp1
		brne	TestDataPacket		;ak je dlzka ina ako 3 - tak to moze byt iba DataPaket
TestIOPacket:
;		cp	temp1,MyInAddress	;ak to nie je urcene (adresa) pre mna
;		brne	TestDataPacket		;tak to moze byt este Data Packet
TestSetupPacket:;test na SETUP paket
		cpi	temp0,nNRZISETUPPID
		brne	TestOutPacket		;ak nie je Setup PID - dekoduj iny paket
		cp	temp1,MyInAddress	;ak to nie je urcene (adresa) pre mna	;ENG;if this isn't assigned (address) for me
		brne	TestDataPacket		;tak to moze byt este Data Packet	;ENG;then this can be still DataPacket
		ldi	State,SetupState
		rjmp	EndInt0HandlerPOP	;ak je Setup PID - prijimaj nasledny Data paket
TestOutPacket:	;test na OUT paket
		cpi	temp0,nNRZIOUTPID
		brne	TestInPacket		;ak nie je Out PID - dekoduj iny paket
		cp	temp1,MyOutAddress	;ak to nie je urcene (adresa) pre mna	;ENG;if this isn't assigned (address) for me
		brne	TestDataPacket		;tak to moze byt este Data Packet	;ENG;then this can be still DataPacket
		ldi	State,OutState
		rjmp	EndInt0HandlerPOP	;ak je Out PID - prijimaj nasledny Data paket
TestInPacket:	;test na IN paket
		cpi	temp0,nNRZIINPID
		brne	TestDataPacket		;ak nie je In PID - dekoduj iny paket
		cp	temp1,MyInAddress	;ak to nie je urcene (adresa) pre mna	;ENG;if this isn't assigned (address) for me
		breq	AnswerToInRequest	;tak to moze byt este Data Packet	;ENG;then this can be still DataPacket
TestDataPacket:	;test na DATA0 a DATA1 paket
		cpi	temp0,nNRZIDATA0PID
		breq	Data0Packet		;ak nie je Data0 PID - dekoduj iny paket
		cpi	temp0,nNRZIDATA1PID
		brne	NoMyPacked		;ak nie je Data1 PID - dekoduj iny paket
Data0Packet:
		cpi	State,SetupState	;ak bol stav Setup
		breq	ReceiveSetupData	;prijmi ho
		cpi	State,OutState		;ak bol stav Out
		breq	ReceiveOutData		;prijmi ho
NoMyPacked:
		ldi	State,BaseState		;znuluj stav
		rjmp	EndInt0HandlerPOP	;a prijimaj nasledny Data paket

AnswerToInRequest:
		push	temp2			;zazalohuj dalsie registre a pokracuj
		push	temp3
		push	RS232BufptrX
		push	ACC
		cpi	ActionFlag,DoReadySendAnswer	;ak nie je pripravena odpoved
		brne	NoReadySend		;tak posli NAK
		rcall	SendPreparedUSBAnswer	;poslanie odpovede naspat
		cpi	State,AddressChangeState;ak je stav AddressChange
		breq	SetMyNewUSBAddress	;tak treba zmenit USB adresu
		ldi	State,InState
		ldi	ActionFlag,DoPrepareOutContinuousBuffer
		rjmp	EndInt0Handler		;a opakuj - cakaj na dalsiu odozvu z USB
ReceiveSetupData:
		push	temp2			;zazalohuj dalsie registre a pokracuj
		push	temp3
		push	RS232BufptrX
		push	ACC
		rcall	SendACK			;akceptovanie Setup Data paketu
		rcall	FinishReceiving		;ukonci prijem
		ldi	ActionFlag,DoReceiveSetupData
		rjmp	EndInt0Handler
ReceiveOutData:
		push	temp2			;zazalohuj dalsie registre a pokracuj
		push	temp3
		push	RS232BufptrX
		push	ACC
		cpi	ActionFlag,DoReceiveSetupData	;ak sa prave spracovava prikaz Setup
		breq	NoReadySend		;tak posli NAK
		rcall	SendACK			;akceptovanie Out paketu
		clr	ActionFlag
		rjmp	EndInt0Handler
NoReadySend:
		rcall	SendNAK			;este nie som pripraveny s odpovedou
		rjmp	EndInt0Handler		;a opakuj - cakaj na dalsiu odozvu z USB
;------------------------------------------------------------------------------------------
SetMyNewUSBAddress:		;nastavi novu USB adresu v NRZI kodovani
		lds	MyInAddress,MyInAddressSRAM
		lds	MyOutAddress,MyOutAddressSRAM
		rjmp	EndInt0Handler
;------------------------------------------------------------------------------------------
FinishReceiving:		;korekcne akcie na ukoncenie prijmu
		cpi	bitcount,7		;prenes do buffera aj posledny necely byte
		breq	NoRemainingBits		;ak boli vsetky byty prenesene, tak neprenasaj nic
		inc	bitcount
ShiftRemainingBits:
		rol	shiftbuf		;posun ostavajuce necele bity na spravnu poziciu
		dec	bitcount
		brne	ShiftRemainingBits
		st	Y+,shiftbuf		;a skopiruj shift register bo buffera - necely byte
NoRemainingBits:
		mov	ByteCount,USBBufptrY
		subi	ByteCount,InputShiftBufferBegin-1	;v ByteCount je pocet prijatych byte (vratane necelych byte)

		mov	InputBufferLength,ByteCount		;a uchovat pre pouzitie v hlavnom programe
		ldi	USBBufptrY,InputShiftBufferBegin	;pointer na zaciatok prijimacieho shift buffera
		ldi	RS232BufptrX,InputBufferBegin+1		;data buffer (vynechat SOP)
MoveDataBuffer:
		ld	temp0,Y+
		st	X+,temp0
		dec	ByteCount
		brne	MoveDataBuffer

		ldi	ByteCount,nNRZISOPbyte
		sts	InputBufferBegin,ByteCount		;ako keby sa prijal SOP - nekopiruje sa zo shift buffera
		ret
;------------------------------------------------------------------------------------------
;********************************************************************
;* Other procedures
;********************************************************************
;------------------------------------------------------------------------------------------
USBReset:		;inicializacia USB stavoveho stroja
		ldi	temp0,nNRZIADDR0	;inicializacia USB adresy
		mov	MyOutAddress,temp0
		mov	MyInAddress,temp0
		clr	State			;inicializacia stavoveho stroja
		clr	BitStuffInOut
		clr	OutBitStuffNumber
		clr	ActionFlag
		clr	RAMread			;bude sa vycitavat z ROM-ky
		clr	ConfigByte		;nenakonfiguravany stav
		ret
;------------------------------------------------------------------------------------------
SendPreparedUSBAnswer:	;poslanie kodovanim NRZI OUT buffer s dlzkou OutputBufferLength do USB
		mov	ByteCount,OutputBufferLength		;dlzka odpovede
SendUSBAnswer:	;poslanie kodovanim NRZI OUT buffer do USB
		ldi	USBBufptrY,OutputBufferBegin		;pointer na zaciatok vysielacieho buffera
SendUSBBuffer:	;poslanie kodovanim NRZI dany buffer do USB
		ldi	temp1,0			;zvysovanie pointra (pomocna premenna)
		mov	temp3,ByteCount		;pocitadlo bytov: temp3 = ByteCount
		ldi	temp2,0b00000011	;maska na xorovanie
		ld	inputbuf,Y+		;nacitanie prveho bytu do inputbuf a zvys pointer do buffera
						;USB ako vystup:
		cbi	outputport,DATAplus	;zhodenie DATAplus : kludovy stav portu USB
		sbi	outputport,DATAminus	;nahodenie DATAminus : kludovy stav portu USB
		sbi	USBdirection,DATAplus	;DATAplus ako vystupny
		sbi	USBdirection,DATAminus	;DATAminus ako vystupny

		in	temp0,outputport	;kludovy stav portu USB do temp0
SendUSBAnswerLoop:
		ldi	bitcount,7		;pocitadlo bitov
SendUSBAnswerByteLoop:
		nop				;oneskorenie kvoli casovaniu
		ror	inputbuf		;do carry vysielany bit (v smere naskor LSB a potom MSB)
		brcs	NoXORSend		;ak je jedna - nemen stav na USB
		eor	temp0,temp2		;inak sa bude stav menit
NoXORSend:
		out	outputport,temp0	;vysli von na USB
		dec	bitcount		;zmensi pocitadlo bitov - podla carry flagu
		brne	SendUSBAnswerByteLoop	;ak pocitadlo bitov nie je nulove - opakuj vysielanie s dalsim bitom
		sbrs	inputbuf,0		;ak je vysielany bit jedna - nemen stav na USB
		eor	temp0,temp2		;inak sa bude stav menit
NoXORSendLSB:
		dec	temp3			;zniz pocitadlo bytov
		ld	inputbuf,Y+		;nacitanie dalsieho bytu a zvys pointer do buffera
		out	outputport,temp0	;vysli von na USB
		brne	SendUSBAnswerLoop	;opakuj pre cely buffer (pokial temp3=0)

		mov	bitcount,OutBitStuffNumber	;pocitadlo bitov pre bitstuff
		cpi	bitcount,0		;ak nie je potrebny bitstuff
		breq	ZeroBitStuf
SendUSBAnswerBitstuffLoop:
		ror	inputbuf		;do carry vysielany bit (v smere naskor LSB a potom MSB)
		brcs	NoXORBitstuffSend	;ak je jedna - nemen stav na USB
		eor	temp0,temp2		;inak sa bude stav menit
NoXORBitstuffSend:
		out	outputport,temp0	;vysli von na USB
		nop				;oneskorenie kvoli casovaniu
		dec	bitcount		;zmensi pocitadlo bitov - podla carry flagu
		brne	SendUSBAnswerBitstuffLoop	;ak pocitadlo bitov nie je nulove - opakuj vysielanie s dalsim bitom
		ld	inputbuf,Y		;oneskorenie 2 cykly
ZeroBitStuf:
		nop				;oneskorenie 1 cyklus
		cbr	temp0,3
		out	outputport,temp0	;vysli EOP na USB

		ldi	bitcount,5		;pocitadlo oneskorenia: EOP ma trvat 2 bity (16 cyklov pri 12MHz)
SendUSBWaitEOP:
		dec	bitcount
		brne	SendUSBWaitEOP

		sbi	outputport,DATAminus	;nahodenie DATAminus : kludovy stav na port USB
		sbi	outputport,DATAminus	;oneskorenie 2 cykly: Idle ma trvat 1 bit (8 cyklov pri 12MHz)
		cbi	USBdirection,DATAplus	;DATAplus ako vstupny
		cbi	USBdirection,DATAminus	;DATAminus ako vstupny
		cbi	outputport,DATAminus	;zhodenie DATAminus : treti stav na port USB
		ret
;------------------------------------------------------------------------------------------
ToggleDATAPID:
		lds	temp0,OutputBufferBegin+1	;nahraj posledne PID
		cpi	temp0,DATA1PID			;ak bolo posledne DATA1PID byte
		ldi	temp0,DATA0PID
		breq	SendData0PID			;tak posli nulovu odpoved s DATA0PID
		ldi	temp0,DATA1PID			;inak posli nulovu odpoved s DATA1PID
SendData0PID:
		sts	OutputBufferBegin+1,temp0	;DATA0PID byte
		ret
;------------------------------------------------------------------------------------------
ComposeZeroDATA1PIDAnswer:
		ldi	temp0,DATA0PID			;DATA0 PID - v skutocnosti sa stoggluje na DATA1PID v nahrati deskriptora

⌨️ 快捷键说明

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