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

📄 usb-prog.asm

📁 单片机的USB ISP软件包,不可多得
💻 ASM
📖 第 1 页 / 共 4 页
字号:
		clr     ZL		ldi     temp2,8		in      temp3, SLAVE_PORTSPILoop:		LSL     ZL		       ; bits go to bottom of ZL (yes, you read a bit here!)		in      temp0, SLAVE_PIN       ; read MISO from slave (in temp0 and R0)		bst     temp0, SLAVE_MISO_MASK ; pick MISO out		bld     ZL, 0                  ; store in the low bit (will be shifted left enough)		bst     ZH, 7                  ; take the high bit from ZH (or bit shifted there)		bld     temp3, SLAVE_MOSI_MASK ; set MOSI from ZH		cbr     temp3, SLAVE_SCK_MASK  ; turn off sck (it should have already been off!)		out     SLAVE_PORT, temp3      ; and do it		sbi     SLAVE_PORT, SLAVE_SCK		rcall   SPIDelay		cbi     SLAVE_PORT, SLAVE_SCK		rcall   SPIDelay		LSL     ZH                     ; shift output byte		dec     temp2                  ; and loop		brne    SPILoop		retSPIDelay:		nop     ; In theory length of SCK strobe depends on programmed device's clock			nop     ; I know I'm programming at90s2313 also at 12MHz		nop     ; and I will find the right count empirically		ret;----------------------------- END USER FUNCTIONS ----------------------------------LcdWrite:		push ZL		swap ZL		rcall LcdNibble		pop ZLLcdNibble:		andi ZL, 0xf		or ZL, ZH		mov ACC, ZL		rcall SetOutDataPort		sbr ZL, 0x20		mov ACC, ZL		rcall SetOutDataPort		cbr ZL, 0x20		mov ACC, ZL		rcall SetOutDataPort		retOneZeroAnswer:		;posle jednu nulu		ldi	temp0,1				;pocet mojich bytovych odpovedi do temp0		rjmp	ComposeGET_STATUS2StandardRequest:		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 odpovedComposeSET_ADDRESS:		lds	MyUpdatedAddress,InputBufferBegin+4	;nova adresa do MyUpdatedAddress		rjmp	ZeroDATA1Answer			;posli nulovu odpovedComposeSET_CONFIGURATION:		lds	ConfigByte,InputBufferBegin+4	;cislo konfiguracie do premennej ConfigByteComposeCLEAR_FEATURE:ComposeSET_FEATURE:ComposeSET_INTERFACE:ZeroStringAnswer:		rjmp	ZeroDATA1Answer			;posli nulovu odpovedComposeGET_STATUS:TwoZeroAnswer:		ldi	temp0,2				;pocet mojich bytovych odpovedi do temp0ComposeGET_STATUS2:		ldi	ZH, high(StatusAnswer<<1)	;ROMpointer na odpoved		ldi	ZL,  low(StatusAnswer<<1)		rjmp	ComposeEndXXXDescriptor		;a dokonciComposeGET_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 dokonciComposeGET_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 dokonciComposeSYNCH_FRAME:ComposeSET_DESCRIPTOR:		rcall	ComposeSTALL		retComposeGET_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		;		retComposeDeviceDescriptor:		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 dokonciComposeConfigDescriptor:		ldi	ZH, high(ConfigDescriptor<<1)	;ROMpointer na descriptor		ldi	ZL,  low(ConfigDescriptor<<1)		ldi	temp0,9+9+7			;pocet mojich bytovych odpovedi do temp0ComposeEndXXXDescriptor:		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 odpovediHostConfigLength:		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 zapocitajLength8Multiply:		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	ComposeNextAnswerPartComposeStringDescriptor:		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 VendorStringComposeVendorString:		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 dokonciComposeDevNameString:		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 dokonciComposeLangIDString:		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		retNextAnswerInBuffer:		dec	TransmitPart			;znizit celkovu dlzku odpovedeComposeNextAnswerPart:		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 odpovedNad8Bytov:		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 (Atmel=0x03EB).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 konfiguraciiDeviceDescriptorEnd:;------------------------------------------------------------------------------------------ConfigDescriptor:		.db	0x9,0x02		;dlzka,typ deskriptoruConfigDescriptorLength:		.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			;EnglishLangIDStringDescriptorEnd:;------------------------------------------------------------------------------------------VendorStringDescriptor:		.db	(VendorStringDescriptorEnd-VendorStringDescriptor)*4-2,3	;dlzka, typ: string deskriptorCopyRight:		.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 temp1MoveLEDin:		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 prerusenie (este sa vykona nasledujuca instrukcia)		sbi	EECR,EEWE			;samotny zapisWaitForEEPROMReady:		sbic	EECR,EEWE			;pockaj si na koniec zapisu		rjmp	WaitForEEPROMReady		;v slucke (max cca 4ms) (kvoli naslednemu citaniu/zapisu)		rjmp	OneZeroAnswer			;potvrd prijem jednou nulou;------------------------------------------------------------------------------------------;********************************************************************;* End of Program;********************************************************************;------------------------------------------------------------------------------------------;********************************************************************;* EEPROM contents;********************************************************************;------------------------------------------------------------------------------------------.eseg 		;data v EEPROM-ke (vo finalnej verzii zapoznamkovat);.org	0x400	;pre naplnenie EEPROM dat na spravne adresy - hned za kod programu (vo finalnej verzii odpoznamkovat)EEData:		.db	"This device was developed by Ing. Igor Cesko: cesko@internet.sk "		.db	"For more information see: http://www.cesko.host.sk. "		.db	"S/N:00000001";------------------------------------------------------------------------------------------;********************************************************************;* End of file;********************************************************************

⌨️ 快捷键说明

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