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

📄 usb90s2313.asm

📁 USB技术大全-54.8M.zip
💻 ASM
📖 第 1 页 / 共 5 页
字号:
		dec	temp3			;boli uz vsetky bity v byte
		brne	CRC16LoopByte		;ak nie, tak chod na dalsi bit
		cp	USBBufptrY,ByteCount	;bol uz koniec spravy
		brne	CRC16Loop		;ak nie tak opakuj
CRC16End:
		ret				;inak skonci (v temp0 a temp1 je vysledok)
;------------------------------------------------------------------------------------------
LoadDescriptorFromROM:
		lpm				;nahraj z pozicie ROM pointra do R0
		st	Y+,R0			;R0 uloz do buffera a zvys buffer
		adiw	ZH:ZL,1			;zvys ukazovatel do ROM
		dec	ByteCount		;pokial nie su vsetky byty
		brne	LoadDescriptorFromROM	;tak nahravaj dalej
		rjmp	EndFromRAMROM		;inak skonci
;------------------------------------------------------------------------------------------
LoadDescriptorFromROMZeroInsert:
		lpm				;nahraj z pozicie ROM pointra do R0
		st	Y+,R0			;R0 uloz do buffera a zvys buffer

		bst	RAMread,3		;ak je 3 bit jednotkovy - nebude sa vkladat nula
		brtc	InsertingZero		;inak sa bude vkladat nula
		adiw	ZH:ZL,1			;zvys ukazovatel do ROM
		lpm				;nahraj z pozicie ROM pointra do R0
		st	Y+,R0			;R0 uloz do buffera a zvys buffer
		clt				;a znuluj
		bld	RAMread,3		;treti bit v RAMread - aby sa v dalsom vkladali nuly
		rjmp	InsertingZeroEnd	;a pokracuj
InsertingZero:
		clr	R0			;na vkladanie nul
		st	Y+,R0			;nulu uloz do buffera a zvys buffer
InsertingZeroEnd:
		adiw	ZH:ZL,1			;zvys ukazovatel do ROM
		subi	ByteCount,2		;pokial nie su vsetky byty
		brne	LoadDescriptorFromROMZeroInsert	;tak nahravaj dalej
		rjmp	EndFromRAMROM		;inak skonci
;------------------------------------------------------------------------------------------
LoadDescriptorFromSRAM:
		ld	R0,Z			;nahraj z pozicie RAM pointra do R0
		st	Y+,R0			;R0 uloz do buffera a zvys buffer
		inc	ZL			;zvys ukazovatel do RAM
		dec	ByteCount		;pokial nie su vsetky byty
		brne	LoadDescriptorFromSRAM	;tak nahravaj dalej
		rjmp	EndFromRAMROM		;inak skonci
;------------------------------------------------------------------------------------------
LoadDescriptorFromEEPROM:
		out	EEAR,ZL			;nastav adresu EEPROM
		sbi	EECR,EERE		;vycitaj EEPROM do registra EEDR
		in	R0,EEDR			;nahraj z EEDR do R0
		st	Y+,R0			;R0 uloz do buffera a zvys buffer
		inc	ZL			;zvys ukazovatel do RAM
		dec	ByteCount		;pokial nie su vsetky byty
		brne	LoadDescriptorFromEEPROM;tak nahravaj dalej
		rjmp	EndFromRAMROM		;inak skonci
;------------------------------------------------------------------------------------------
LoadXXXDescriptor:
		ldi	temp0,SOPbyte			;SOP byte
		sts	OutputBufferBegin,temp0		;na zaciatok vysielacieho buffera dat SOP
		ldi	ByteCount,8			;8 bytov nahrat
		ldi	USBBufptrY,OutputBufferBegin+2	;do vysielacieho buffera

		and	RAMread,RAMread			;ci sa bude citat z RAM alebo ROM-ky alebo EEPROM-ky
		brne	FromRAMorEEPROM			;0=ROM,1=RAM,2=EEPROM,4=ROM s vkladanim nuly
FromROM:
		rjmp	LoadDescriptorFromROM		;nahrat descriptor z ROM-ky
FromRAMorEEPROM:
		sbrc	RAMread,2			;ak RAMread=4
		rjmp	LoadDescriptorFromROMZeroInsert	;citaj z ROM s vkladanim nuly
		sbrc	RAMread,0			;ak RAMread=1
		rjmp	LoadDescriptorFromSRAM		;nahraj data zo SRAM-ky
		rjmp	LoadDescriptorFromEEPROM	;inak citaj z EEPROM
EndFromRAMROM:
		sbrc	RAMread,7			;ak je najvyssi bit v premennej RAMread=1
		clr	RAMread				;znuluj RAMread
		rcall	ToggleDATAPID			;zmenit DATAPID
		ldi	USBBufptrY,OutputBufferBegin+1	;do vysielacieho buffera - pozicia DATA PID
		ret
;------------------------------------------------------------------------------------------
PrepareUSBOutAnswer:	;pripravenie odpovede do buffera
		rcall	PrepareUSBAnswer		;pripravenie odpovede do buffera
MakeOutBitStuff:
		inc	BitStuffInOut			;vysielaci buffer - vkladanie bitstuff bitov
		ldi	USBBufptrY,OutputBufferBegin	;do vysielacieho buffera
		rcall	BitStuff
		mov	OutputBufferLength,ByteCount	;dlzku odpovede zapamatat pre vysielanie
		clr	BitStuffInOut			;prijimaci buffer - mazanie bitstuff bitov
		ret
;------------------------------------------------------------------------------------------
PrepareUSBAnswer:	;pripravenie odpovede do buffera
		clr	RAMread				;nulu do RAMread premennej - cita sa z ROM-ky
		lds	temp0,InputBufferBegin+2	;bmRequestType do temp0
		lds	temp1,InputBufferBegin+3	;bRequest do temp1
		cbr	temp0,0b10011111		;ak je 5 a 6 bit nulovy
		brne	VendorRequest			;tak to nie je  Vendor Request
		rjmp	StandardRequest			;ale je to standardny request
;--------------------------
DoSetInfraBufferEmpty:
		rjmp	OneZeroAnswer			;potvrd prijem jednou nulou
;--------------------------
DoSetRS232Baud:
		lds	temp0,InputBufferBegin+4	;prvy parameter - hodnota baudrate na RS232
		out	UBRR,temp0			;nastav rychlost UART-u
		rjmp	OneZeroAnswer			;potvrd prijem jednou nulou
;--------------------------
DoGetRS232Baud:
		in	R0,UBRR				;vrat rychlost UART-u v R0
		rjmp	DoGetIn				;a ukonci
;--------------------------
DoRS232Send:
		lds	temp0,InputBufferBegin+4	;prvy parameter - hodnota vysielana na RS232
		out	UDR,temp0			;vysli data na UART
WaitForRS232Send:
		sbis	UCR,TXEN			;ak nie je povoleny UART vysielac
		rjmp	OneZeroAnswer			;tak skonci - ochrana kvoli zacykleniu v AT90S2323/2343
		sbis	USR,TXC				;pockat na dovysielanie bytu
		rjmp	WaitForRS232Send
		rjmp	OneZeroAnswer			;potvrd prijem jednou nulou
;--------------------------
DoRS232Read:
		rjmp	TwoZeroAnswer			;iba potvrd prijem dvoma nulami
;--------------------------
VendorRequest:
		clr	ZH				;pre citanie z RAM alebo EEPROM

		cpi	temp1,1				;
		breq	DoSetInfraBufferEmpty		;restartne infra prijimanie (ak bolo zastavene citanim z RAM-ky)

		cpi	temp1,2				;
		breq	DoGetInfraCode			;vysle prijaty infra kod (ak je v bufferi)

		cpi	temp1,3				;
		breq	DoSetDataPortDirection		;nastavi smer toku datovych bitov
		cpi	temp1,4				;
		breq	DoGetDataPortDirection		;zisti smer toku datovych bitov

		cpi	temp1,5				;
		breq	DoSetOutDataPort		;nastavi datove bity (ak su vstupne, tak ich pull-up)
		cpi	temp1,6				;
		breq	DoGetOutDataPort		;zisti nastavenie datovych out bitov (ak su vstupne, tak ich pull-up)

		cpi	temp1,7				;
		breq	DoGetInDataPort			;vrati hodnotu datoveho vstupneho portu

		cpi	temp1,8				;
		breq	DoEEPROMRead			;vrati obsah EEPROM od urcitej adresy
		cpi	temp1,9				;
		breq	DoEEPROMWrite			;zapise EEPROM na urcitu adresu urcite data

		cpi	temp1,10			;
		breq	DoRS232Send			;vysle byte na seriovy linku
		cpi	temp1,11			;
		breq	DoRS232Read			;vrati prijaty byte zo seriovej linky (ak sa nejaky prijal)

		cpi	temp1,12			;
		breq	DoSetRS232Baud			;nastavi prenosovu rychlost seriovej linky
		cpi	temp1,13			;
		breq	DoGetRS232Baud			;vrati prenosovu rychlost seriovej linky
		cpi	temp1,14			;
		breq	DoGetRS232Buffer		;vrati RS232 buffer

		cpi	temp1,USER_FNC_NUMBER+0		;
		breq	DoUserFunction0			;vykona uzivatelsku rutinu0
		cpi	temp1,USER_FNC_NUMBER+1		;
		breq	DoUserFunction1			;vykona uzivatelsku rutinu1
		cpi	temp1,USER_FNC_NUMBER+2		;
		breq	DoUserFunction2			;vykona uzivatelsku rutinu2

		rjmp	ZeroDATA1Answer			;ak to bolo nieco nezname, tak priprav nulovu odpoved

;----------------------------- USER FUNCTIONS --------------------------------------

;------------------------------TEMPLATE OF YOUR FUNCTION----------------------------
;------------------ BEGIN: This is template how to write own function --------------

;free of use are registers:
	;temp0,temp1,temp2,temp3,ACC,ZH,ZL
	;registers are destroyed after execution (use push/pop to save content)

;at the end of routine you must correctly set registers:
	;RAMread - 0=reading from ROM, 1=reading from RAM, 2=reading from EEPROM
	;temp0 - number of transmitted data bytes
	;ZH,ZL - pointer to buffer of transmitted data (pointer to ROM/RAM/EEPROM)

;to transmit data (preparing data to buffer) :
	;to transmit data you must jump to "ComposeEndXXXDescriptor"
	;to transmit one zero byte you can jump to "OneZeroAnswer"  (commonly used as confirmation of correct processing)
	;to transmit two zero byte you can jump to "TwoZeroAnswer"  (commonly used as confirmation of error in processing)

DoUserFunctionX:
DoUserFunction0:  ;send byte(s) of RAM starting at position given by first parameter in function
		lds	temp0,InputBufferBegin+4	;prvy  parameter Lo do temp0
		;lds	temp1,InputBufferBegin+5	;prvy  parameter Hi do temp1
		;lds	temp2,InputBufferBegin+6	;druhy parameter Lo do temp2
		;lds	temp3,InputBufferBegin+7	;druhy parameter Hi do temp3
		;lds	ACC,InputBufferBegin+8		;pocet pozadovanych bytov do ACC

		;Tu si pridajte vlastny kod:
		;-------------------------------------------------------------------
		nop					;priklad na kod - nic nerobi
		nop
		nop
		nop
		nop
		;-------------------------------------------------------------------

		mov	ZL,temp0			;bude sa posielat hodnota RAM adresy ulozena v temp0 (prvy parameter funkcie)
		inc	RAMread				;RAMread=1 - cita sa z RAM-ky
		ldi	temp0,RAMEND+1			;posli max pocet byte - celu RAM
		rjmp	ComposeEndXXXDescriptor		;a priprav data
DoUserFunction1:
		rjmp	OneZeroAnswer			;potvrd prijem jednou nulou
DoUserFunction2:
		rjmp	TwoZeroAnswer			;potvrd prijem dvoma nulami
;------------------ END: This is template how to write own function ----------------

;----------------------------- USER FUNCTIONS --------------------------------------

DoGetInfraCode:
		rjmp	OneZeroAnswer			;potvrd prijem jednou nulou

DoEEPROMRead:
		lds	ZL,InputBufferBegin+4		;prvy parameter - offset v EEPROM-ke
		ldi	temp0,2
		mov	RAMread,temp0			;RAMread=2 - cita sa z EEPROM-ky
		ldi	temp0,E2END+1			;pocet mojich bytovych odpovedi do temp0 - cela dlzka EEPROM
		rjmp	ComposeEndXXXDescriptor		;inak priprav data
DoEEPROMWrite:
		lds	ZL,InputBufferBegin+4		;prvy parameter - offset v EEPROM-ke (adresa)
		lds	R0,InputBufferBegin+6		;druhy parameter - data, ktore sa maju zapisat do EEPROM-ky (data)
		rjmp	EEPROMWrite			;zapis do EEPROM a aj ukonci prikaz
DoSetDataPortDirection:
		lds	ACC,InputBufferBegin+4		;prvy parameter - smer datovych bitov
		rcall	SetDataPortDirection
		rjmp	OneZeroAnswer			;potvrd prijem jednou nulou
DoGetDataPortDirection:
		rcall	GetDataPortDirection
		rjmp	DoGetIn

DoSetOutDataPort:
		lds	ACC,InputBufferBegin+4		;prvy parameter - hodnota datovych bitov
		rcall	SetOutDataPort
		rjmp	OneZeroAnswer			;potvrd prijem jednou nulou
DoGetOutDataPort:
		rcall	GetOutDataPort
		rjmp	DoGetIn

DoGetInDataPort:
		rcall	GetInDataPort
 DoGetIn:
		ldi	ZL,0				;posiela sa hodnota v R0
		ldi	temp0,0x81			;RAMread=1 - cita sa z RAM-ky
		mov	RAMread,temp0			;(najvyssi bit na 1 - aby sa hned premenna RAMread znulovala)
		ldi	temp0,1				;posli iba jeden byte
		rjmp	ComposeEndXXXDescriptor		;a priprav data

DoGetRS232Buffer:
		mov	temp0,RS232BufferFull		;zisti dlzku buffera RS232 kodu
		cpi	temp0,0				;ak je RS232 Buffer prazdny
		breq	OneZeroAnswer			;tak nic neposli a potvrd prijem jednou nulou

		lds	ACC,InputBufferBegin+8		;pocet pozadovanych bytov do ACC
		inc	temp0				;pocet moznych dodanych bajtov (plus byte dlzky buffera)
		cp	ACC,temp0			;ak sa neziada viac ako mozem dodat
		brcc	NoShortGetRS232Buffer		;vysli tolko kolko sa ziada
		mov	temp0,ACC
NoShortGetRS232Buffer:
		dec	temp0				;uber byte dlzky
		lds	temp1,RS232BufferBegin+1	;zisti ukazovatel citania buffera RS232 kodu : 2.byte hlavicky (dlzka kodu + citanie + zapis + rezerva)
		add	temp1,temp0			;zisti kde je koniec
		cpi	temp1,RS232BufferBegin+MAXRS232LENGTH+1	;ak by mal pretiect
		brcs	ReadNoOverflow
		subi	temp1,RS232BufferBegin+MAXRS232LENGTH+1	;vypocitaj kolko sa neprenesie
		sub	temp0,temp1			;a o to skrat dlzku citania
		ldi	temp1,RS232BufferBegin+4	;a zacni od nuly
ReadNoOverflow:
		lds	ZL,RS232BufferBegin+1		;zisti ukazovatel citania buffera RS232 kodu : 2.byte hlavicky (dlzka kodu + citanie + zapis + rezerva)
		sts	RS232BufferBegin+1,temp1	;zapis novy ukazovatel citania buffera RS232 kodu : 2.byte hlavicky (dlzka kodu + citanie + zapis + rezerva)
		dec	ZL				;priestor pre udaj dlky - prenasa sa ako prvy bajt

		sub	RS232BufferFull,temp0		;zniz dlzku buffera
		st	Z,RS232BufferFull		;a uloz skutocnu dlzku do paketu
		inc	temp0				;a o tento jeden bajt zvys pocet prenasanych bajtov (dlzka buffera)
		inc	RAMread				;RAMread=1 - cita sa z RAM-ky
		rjmp	ComposeEndXXXDescriptor		;a priprav data
;----------------------------- END USER FUNCTIONS ----------------------------------

OneZeroAnswer:		;posle jednu nulu
		ldi	temp0,1				;pocet mojich bytovych odpovedi do temp0
		rjmp	ComposeGET_STATUS2

StandardRequest:
		cpi	temp1,GET_STATUS		;
		breq	ComposeGET_STATUS		;

		cpi	temp1,CLEAR_FEATURE		;
		breq	ComposeCLEAR_FEATURE		;

		cpi	temp1,SET_FEATURE		;
		breq	ComposeSET_FEATURE		;

		cpi	temp1,SET_ADDRESS		;ak sa ma nastavit adresa

⌨️ 快捷键说明

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