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

📄 usb90s23x3.asm

📁 单片机AT90S系列 制作简易USB接口(软件模拟,无usb硬件)。asm源代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
		rjmp	ComposeEndXXXDescriptor		;tak 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
		breq	ComposeSET_ADDRESS		;nastav adresu

		cpi		temp1,GET_DESCRIPTOR		;ak sa ziada descriptor
		breq	ComposeGET_DESCRIPTOR		;vygeneruj ho

		cpi		temp1,SET_DESCRIPTOR		;
		breq	ComposeSET_DESCRIPTOR		;

		cpi		temp1,GET_CONFIGURATION		;
		breq	ComposeGET_CONFIGURATION	;

		cpi		temp1,SET_CONFIGURATION		;
		breq	ComposeSET_CONFIGURATION	;

		cpi		temp1,GET_INTERFACE		;
		breq	ComposeGET_INTERFACE		;

		cpi		temp1,SET_INTERFACE		;
		breq	ComposeSET_INTERFACE		;

		cpi		temp1,SYNCH_FRAME		;
		breq	ComposeSYNCH_FRAME		;
							;ak sa nenasla znama poziadavka
		rjmp	ZeroDATA1Answer			;ak to bolo nieco nezname, tak priprav nulovu odpoved

ComposeSET_ADDRESS:
		lds		MyUpdatedAddress,InputBufferBegin+4	;nova adresa do MyUpdatedAddress
		rjmp	ZeroDATA1Answer			;posli nulovu odpoved

ComposeSET_CONFIGURATION:
		lds		ConfigByte,InputBufferBegin+4	;cislo konfiguracie do premennej ConfigByte
ComposeCLEAR_FEATURE:
ComposeSET_FEATURE:
ComposeSET_INTERFACE:
ZeroStringAnswer:
		rjmp	ZeroDATA1Answer			;posli nulovu odpoved
ComposeGET_STATUS:
TwoZeroAnswer:
		ldi		temp0,2				;pocet mojich bytovych odpovedi do temp0
ComposeGET_STATUS2:
		ldi		ZH, high(StatusAnswer<<1)	;ROMpointer na odpoved
		ldi		ZL,  low(StatusAnswer<<1)
		rjmp	ComposeEndXXXDescriptor		;a dokonci
ComposeGET_CONFIGURATION:
		and		ConfigByte,ConfigByte		;ak som nenakonfigurovany
		breq	OneZeroAnswer			;tak posli jednu nulu - inak posli moju konfiguraciu
		ldi		temp0,1				;pocet mojich bytovych odpovedi do temp0
		ldi		ZH, high(ConfigAnswerMinus1<<1)	;ROMpointer na odpoved
		ldi		ZL,  low(ConfigAnswerMinus1<<1)+1
		rjmp	ComposeEndXXXDescriptor		;a dokonci
ComposeGET_INTERFACE:
		ldi		ZH, high(InterfaceAnswer<<1)	;ROMpointer na odpoved
		ldi		ZL,  low(InterfaceAnswer<<1)
		ldi		temp0,1				;pocet mojich bytovych odpovedi do temp0
		rjmp	ComposeEndXXXDescriptor		;a dokonci
ComposeSYNCH_FRAME:
ComposeSET_DESCRIPTOR:
		rcall	ComposeSTALL
		ret
ComposeGET_DESCRIPTOR:
		lds		temp1,InputBufferBegin+5	;DescriptorType do temp1
		cpi		temp1,DEVICE			;DeviceDescriptor
		breq	ComposeDeviceDescriptor		;
		cpi		temp1,CONFIGURATION		;ConfigurationDescriptor
		breq	ComposeConfigDescriptor		;
		cpi		temp1,STRING			;StringDeviceDescriptor
		breq	ComposeStringDescriptor		;
		ret
ComposeDeviceDescriptor:
		ldi		ZH, high(DeviceDescriptor<<1)	;ROMpointer na descriptor
		ldi		ZL,  low(DeviceDescriptor<<1)
		ldi		temp0,0x12			;pocet mojich bytovych odpovedi do temp0
		rjmp	ComposeEndXXXDescriptor		;a dokonci
ComposeConfigDescriptor:
		ldi		ZH, high(ConfigDescriptor<<1)	;ROMpointer na descriptor
		ldi		ZL,  low(ConfigDescriptor<<1)
		ldi		temp0,9+9+7			;pocet mojich bytovych odpovedi do temp0
ComposeEndXXXDescriptor:
		lds		TotalBytesToSend,InputBufferBegin+8	;pocet pozadovanych bytov do TotalBytesToSend
		cp		TotalBytesToSend,temp0			;ak sa neziada viac ako mozem dodat
		brcs	HostConfigLength		;vysli tolko kolko sa ziada
		mov		TotalBytesToSend,temp0		;inak posli pocet mojich odpovedi
HostConfigLength:
		mov		temp0,TotalBytesToSend		;
		clr		TransmitPart			;nuluj pocet 8 bytovych odpovedi
		andi	temp0,0b00000111		;ak je dlzka delitelna 8-mimi
		breq	Length8Multiply			;tak nezapocitaj jednu necelu odpoved (pod 8 bytov)
		inc	TransmitPart			;inak ju zapocitaj
Length8Multiply:
		mov		temp0,TotalBytesToSend		;
		lsr		temp0				;dlzka 8 bytovych odpovedi sa dosiahne
		lsr		temp0				;delenie celociselne 8-mimi
		lsr		temp0
		add		TransmitPart,temp0		;a pripocitanim k poslednej necelej 8-mici do premennej TransmitPart
		ldi		temp0,DATA0PID			;DATA0 PID - v skutocnosti sa stoggluje na DATA1PID v nahrati deskriptora
		sts		OutputBufferBegin+1,temp0	;nahraj do vyst buffera
		rjmp	ComposeNextAnswerPart
ComposeStringDescriptor:
		ldi		temp1,4+8			;ak RAMread=4(vkladaj nuly z ROM-koveho citania) + 8(za prvy byte nevkldadaj nulu)
		mov		RAMread,temp1
		lds		temp1,InputBufferBegin+4	;DescriptorIndex do temp1
		cpi		temp1,0				;LANGID String
		breq	ComposeLangIDString		;
		cpi		temp1,2				;DevNameString
		breq	ComposeDevNameString		;
		brcc	ZeroStringAnswer		;ak je DescriptorIndex vyssi nez 2 - posli nulovu odpoved
							;inak to bude VendorString
ComposeVendorString:
		ldi		ZH, high(VendorStringDescriptor<<1)	;ROMpointer na descriptor
		ldi		ZL,  low(VendorStringDescriptor<<1)
		ldi		temp0,(VendorStringDescriptorEnd-VendorStringDescriptor)*4-2	;pocet mojich bytovych odpovedi do temp0
		rjmp	ComposeEndXXXDescriptor		;a dokonci
ComposeDevNameString:
		ldi		ZH, high(DevNameStringDescriptor<<1)	;ROMpointer na descriptor
		ldi		ZL,  low(DevNameStringDescriptor<<1)
		ldi	temp0,(DevNameStringDescriptorEnd-DevNameStringDescriptor)*4-2	;pocet mojich bytovych odpovedi do temp0
		rjmp	ComposeEndXXXDescriptor		;a dokonci
ComposeLangIDString:
		clr		RAMread
		ldi		ZH, high(LangIDStringDescriptor<<1)	;ROMpointer na descriptor
		ldi		ZL,  low(LangIDStringDescriptor<<1)
		ldi		temp0,(LangIDStringDescriptorEnd-LangIDStringDescriptor)*2;pocet mojich bytovych odpovedi do temp0
		rjmp	ComposeEndXXXDescriptor		;a dokonci
;------------------------------------------------------------------------------------------
ZeroDATA1Answer:
		rcall	ComposeZeroDATA1PIDAnswer
		ret
;------------------------------------------------------------------------------------------
PrepareOutContinuousBuffer:
		rcall	PrepareContinuousBuffer
		rcall	MakeOutBitStuff
		ret
;------------------------------------------------------------------------------------------
PrepareContinuousBuffer:
		mov		temp0,TransmitPart
		cpi		temp0,1
		brne	NextAnswerInBuffer		;ak uz je buffer prazdny
		rcall	ComposeZeroAnswer		;priprav nulovu odpoved
		ret
NextAnswerInBuffer:
		dec		TransmitPart			;znizit celkovu dlzku odpovede
ComposeNextAnswerPart:
		mov		temp1,TotalBytesToSend	;zniz pocet bytov na vyslanie 
		subi	temp1,8			;ci je este treba poslat viac ako 8 bytov
		ldi		temp3,8			;ak ano - posli iba 8 bytov
		brcc	Nad8Bytov
		mov		temp3,TotalBytesToSend	;inak posli iba dany pocet bytov
		clr		TransmitPart
		inc		TransmitPart		;a bude to posledna odpoved
Nad8Bytov:
		mov		TotalBytesToSend,temp1	;znizeny pocet bytov do TotalBytesToSend
		rcall	LoadXXXDescriptor
		ldi		ByteCount,2		;dlzka vystupneho buffera (iba SOP a PID)
		add		ByteCount,temp3		;+ pocet bytov
		rcall	AddCRCOut		;pridanie CRC do buffera
		inc		ByteCount		;dlzka vystupneho buffera + CRC16
		inc		ByteCount
		ret				;skonci
;------------------------------------------------------------------------------------------
.EQU	USBversion		=0x0100		;pre aku verziu USB je to (1.00)
.EQU	VendorUSBID		=0x03EB		;identifikator dodavatela (Atmel0x03EB)
.EQU	DeviceUSBID		=0x0002		;identifikator vyrobku (USB dialkove ovladanie=0x0002)
.EQU	DeviceVersion	=0x0001		;cislo verzie vyrobku (verzia=0.01)
.EQU	MaxUSBCurrent	=40		;prudovy odber z USB (40mA)
;------------------------------------------------------------------------------------------
DeviceDescriptor:
		.db	0x12,0x01		;0 byte - velkost deskriptora v bytoch
						;1 byte - typ deskriptora: Deskriptor zariadenia
		.dw	USBversion		;2,3 byte - verzia USB LSB (1.00)
		.db	0x00,0x00		;4 byte - trieda zariadenia
						;5 byte - podtrieda zariadenia
		.db	0x00,0x08		;6 byte - kod protokolu
						;7 byte - velkost FIFO v bytoch
		.dw	VendorUSBID		;8,9 byte - identifikator dodavatela (Cypress=0x04B4)
		.dw	DeviceUSBID		;10,11 byte - identifikator vyrobku (teplomer=0x0002)
		.dw	DeviceVersion		;12,13 byte - cislo verzie vyrobku (verzia=0.01)
		.db	0x01,0x02		;14 byte - index stringu "vyrobca"
						;15 byte - index stringu "vyrobok"
		.db	0x00,0x01		;16 byte - index stringu "seriove cislo"
						;17 byte - pocet moznych konfiguracii
DeviceDescriptorEnd:
;------------------------------------------------------------------------------------------
ConfigDescriptor:
		.db	0x9,0x02		;dlzka,typ deskriptoru
ConfigDescriptorLength:
		.dw	9+9+7			;celkova dlzka vsetkych deskriptorov
	ConfigAnswerMinus1:			;pre poslanie cisla congiguration number (pozor je  treba este pricitat 1)
		.db	1,1			;numInterfaces,congiguration number
		.db	0,0x80			;popisny index stringu, atributy;bus powered
		.db	MaxUSBCurrent/2,0x09	;prudovy odber, interface descriptor length
		.db	0x04,0			;interface descriptor; cislo interface
	InterfaceAnswer:			;pre poslanie cisla alternativneho interface
		.db	0,1			;alternativne nastavenie interface; pocet koncovych bodov okrem EP0
	StatusAnswer:				;2 nulove odpovede (na usetrenie miestom)
		.db	0,0			;trieda rozhrania; podtrieda rozhrania
		.db	0,0			;kod protokolu; index popisneho stringu
		.db	0x07,0x5		;dlzka,typ deskriptoru - endpoint
		.db	0x81,0			;endpoint address; transfer type
		.dw	0x08			;max packet size
		.db	10,0			;polling interval [ms]; dummy byte (pre vyplnenie)
ConfigDescriptorEnd:
;------------------------------------------------------------------------------------------
LangIDStringDescriptor:
		.db	(LangIDStringDescriptorEnd-LangIDStringDescriptor)*2,3	;dlzka, typ: string deskriptor
		.dw	0x0409			;English
LangIDStringDescriptorEnd:
;------------------------------------------------------------------------------------------
VendorStringDescriptor:
		.db	(VendorStringDescriptorEnd-VendorStringDescriptor)*4-2,3	;dlzka, typ: string deskriptor
CopyRight:
		.db	"Ing. Igor Cesko, Copyright(c) 2003"
CopyRightEnd:
VendorStringDescriptorEnd:
;------------------------------------------------------------------------------------------
DevNameStringDescriptor:
		.db	(DevNameStringDescriptorEnd-DevNameStringDescriptor)*4-2,3;dlzka, typ: string deskriptor
		.db	"IgorPlug-USB (AVR)"
DevNameStringDescriptorEnd:
;------------------------------------------------------------------------------------------
MaskPortData:
		bst		ACC,0
		bld		temp0,LEDlsb0
		bst		ACC,1
		bld		temp0,LEDlsb1
		bst		ACC,2
		bld		temp0,LEDlsb2
		bst		ACC,3
		bld		temp1,LEDmsb3
		bst		ACC,4
		bld		temp1,LEDmsb4
		bst		ACC,5
		bld		temp1,LEDmsb5
		bst		ACC,6
		bld		temp1,LEDmsb6
		bst		ACC,7
		bld		temp1,LEDmsb7
		ret
;------------------------------------------------------------------------------------------
SetDataPortDirection:
		in		temp0,LEDdirectionLSB		;nacitaj aktualny stav LSB do temp0 (aby sa nezmenili ostatne smery bitov)
		in		temp1,LEDdirectionMSB		;nacitaj aktualny stav MSB do temp1 (aby sa nezmenili ostatne smery bitov)
		rcall	MaskPortData
		out		LEDdirectionLSB,temp0		;a update smeru LSB datoveho portu
		out		LEDdirectionMSB,temp1		;a update smeru MSB datoveho portu
		ret
;------------------------------------------------------------------------------------------
SetOutDataPort:
		in		temp0,LEDPortLSB		;nacitaj aktualny stav LSB do temp0 (aby sa nezmenili ostatne bity)
		in		temp1,LEDPortMSB		;nacitaj aktualny stav MSB do temp1 (aby sa nezmenili ostatne bity)
		rcall	MaskPortData
		out		LEDPortLSB,temp0		;a update LSB datoveho portu
		out		LEDPortMSB,temp1		;a update MSB datoveho portu
		ret
;------------------------------------------------------------------------------------------
GetInDataPort:
		in		temp0,LEDPinMSB			;nacitaj aktualny stav MSB do temp0
		in		temp1,LEDPinLSB			;nacitaj aktualny stav LSB do temp1
MoveLEDin:
		bst		temp1,LEDlsb0			;a daj bity LSB na spravne pozicie (z temp1 do temp0)
		bld		temp0,0				;(bity MSB su na spravnom mieste)
		bst		temp1,LEDlsb1
		bld		temp0,1
		bst		temp1,LEDlsb2
		bld		temp0,2
		mov		R0,temp0			;a vysledok uloz do R0
		ret
;------------------------------------------------------------------------------------------
GetOutDataPort:
		in		temp0,LEDPortMSB		;nacitaj aktualny stav MSB do temp0
		in		temp1,LEDPortLSB		;nacitaj aktualny stav LSB do temp1
		rjmp	MoveLEDin
;------------------------------------------------------------------------------------------
GetDataPortDirection:
		in		temp0,LEDdirectionMSB		;nacitaj aktualny stav MSB do temp0
		in		temp1,LEDdirectionLSB		;nacitaj aktualny stav LSB do temp1
		rjmp	MoveLEDin
;------------------------------------------------------------------------------------------
EEPROMWrite:
		out		EEAR,ZL				;nastav adresu EEPROM
		out		EEDR,R0				;nastav data do EEPROM
		cli					;zakaz prerusenie
		sbi		EECR,EEMWE			;nastav master write enable
		sei					;povol p

⌨️ 快捷键说明

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