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

📄 usb90s23x3.asm

📁 单片机的USB ISP软件包,不可多得
💻 ASM
📖 第 1 页 / 共 5 页
字号:
		pop	ByteCount		pop	USBBufptrY		ret;------------------------------------------------------------------------------------------MirrorBufferBytes:		add	ByteCount,USBBufptrY	;ByteCount ukazuje na koniec spravyMirrorBufferloop:		ld	temp0,Y			;nahraj prijaty byte z buffera		ldi	temp1,8			;pocitadlo bitovMirrorBufferByteLoop:		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 - temp3CRC16LoopByte:		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 byteCRC16NoXOR:		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 opakujCRC16End:		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 pokracujInsertingZero:		clr	R0			;na vkladanie nul		st	Y+,R0			;nulu uloz do buffera a zvys bufferInsertingZeroEnd:		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 nulyFromROM:		rjmp	LoadDescriptorFromROM		;nahrat descriptor z ROM-kyFromRAMorEEPROM:		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 EEPROMEndFromRAMROM:		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 bufferaMakeOutBitStuff:		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:		clr	InfraBufferFull			;nastav prazdnost bufferaSendZeroAnswerInfraEmpty:		rjmp	OneZeroAnswer			;potvrd prijem jednou nulou;--------------------------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		rjmp	ZeroDATA1Answer			;ak to bolo nieco nezname, tak priprav nulovu odpoved;----------------------------- USER FUNCTIONS --------------------------------------DoGetInfraCode:		cpi	InfraBufferFull,0		;ak je Infra Buffer prazdny		breq	SendZeroAnswerInfraEmpty	;tak nic neposli		ldi	ZL,InfraBufferBegin		lds	temp1,InputBufferBegin+4	;prvy parameter - offset v infra bufferi		add	ZL,temp1			;plus offset v buffri		lds	temp0,InfraBufferBegin		;pocet mojich bytovych odpovedi do temp0		ldi	temp1,3				;plus 3 byty hlavicky		add	temp0,temp1		inc	RAMread				;RAMread=1 - cita sa z RAM-ky		rjmp	ComposeEndXXXDescriptor		;a priprav dataDoEEPROMRead:		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 dataDoEEPROMWrite:		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 prikazDoSetDataPortDirection:		lds	ACC,InputBufferBegin+4		;prvy parameter - smer datovych bitov		rcall	SetDataPortDirection		rjmp	OneZeroAnswer			;potvrd prijem jednou nulouDoGetDataPortDirection:		rcall	GetDataPortDirection		rjmp	DoGetInDoSetOutDataPort:		lds	ACC,InputBufferBegin+4		;prvy parameter - hodnota datovych bitov		rcall	SetOutDataPort		rjmp	OneZeroAnswer			;potvrd prijem jednou nulouDoGetOutDataPort:		rcall	GetOutDataPort		rjmp	DoGetInDoGetInDataPort:		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 dataDoSetRS232Baud:		lds	temp0,InputBufferBegin+4	;prvy parameter - hodnota baudrate na RS232		out	UBRR,temp0			;nastav rychlost UART-u		rjmp	OneZeroAnswer			;potvrd prijem jednou nulouDoGetRS232Baud:		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 UARTWaitForRS232Send:		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 nulouDoRS232Read:		sbis	USR,RXC				;ak je prijimaci register prazdny		rjmp	TwoZeroAnswer			;tak iba potvrd prijem dvoma nulami		in	R0,UDR				;inak nacitaj do R0 prijate data z UART-u		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		sbic	USR,OR				;ak bolo pretecenie prijimacieho buffera		ldi	temp0,3				;posli 3 byty :prvy je prijata hodnota (na ostatnych nezalezi)		rjmp	ComposeEndXXXDescriptor		;tak priprav data;----------------------------- END USER FUNCTIONS ----------------------------------OneZeroAnswer:		;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

⌨️ 快捷键说明

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