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

📄 usb-prog.asm

📁 单片机的USB ISP软件包,不可多得
💻 ASM
📖 第 1 页 / 共 4 页
字号:
		rjmp	EndInt0HandlerPOP	;inak opakuj od zaciatkuUSBloopEnd:		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 DataPaketTestIOPacket:		cp	temp1,MyAddress		;ak to nie je urcene (adresa) pre mna		brne	TestDataPacket		;tak to moze byt este Data PacketTestSetupPacket:;test na SETUP paket		cpi	temp0,nNRZISETUPPID		brne	TestOutPacket		;ak nie je Setup PID - dekoduj iny paket		ldi	State,SetupState		rjmp	EndInt0HandlerPOP	;ak je Setup PID - prijimaj nasledny Data paketTestOutPacket:	;test na OUT paket		cpi	temp0,nNRZIOUTPID		brne	TestInPacket		;ak nie je Out PID - dekoduj iny paket		ldi	State,OutState		rjmp	EndInt0HandlerPOP	;ak je Out PID - prijimaj nasledny Data paketTestInPacket:	;test na IN paket		cpi	temp0,nNRZIINPID		brne	TestDataPacket		;ak nie je In PID - dekoduj iny paket		rjmp	AnswerToInRequestTestDataPacket:	;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 paketData0Packet:		cpi	State,SetupState	;ak bol stav Setup		breq	ReceiveSetupData	;prijmi ho		cpi	State,OutState		;ak bol stav Out		breq	ReceiveOutData		;prijmi hoNoMyPacked:		ldi	State,BaseState		;znuluj stav		rjmp	EndInt0HandlerPOP	;a prijimaj nasledny Data paketAnswerToInRequest:		push	temp2			;zazalohuj dalsie registre a pokracuj		push	temp3		push	InfraBufptrX		push	ACC		cpi	ActionFlag,DoReadySendAnswer	;ak nie je pripravena odpoved		brne	NoReadySend		;tak posli NAK		rcall	SendPreparedUSBAnswer	;poslanie odpovede naspat		and	MyUpdatedAddress,MyUpdatedAddress	;ak je MyUpdatedAddress nenulova		brne	SetMyNewUSBAddress	;tak treba zmenit USB adresu		ldi	State,InState		ldi	ActionFlag,DoPrepareOutContinuousBuffer		rjmp	EndInt0Handler		;a opakuj - cakaj na dalsiu odozvu z USBReceiveSetupData:		push	temp2			;zazalohuj dalsie registre a pokracuj		push	temp3		push	InfraBufptrX		push	ACC		rcall	SendACK			;akceptovanie Setup Data paketu		rcall	FinishReceiving		;ukonci prijem		ldi	ActionFlag,DoReceiveSetupData		rjmp	EndInt0HandlerReceiveOutData:		push	temp2			;zazalohuj dalsie registre a pokracuj		push	temp3		push	InfraBufptrX		push	ACC		cpi	ActionFlag,DoReceiveSetupData	;ak sa prave spracovava prikaz Setup		breq	NoReadySend		;tak posli NAK		rcall	SendACK			;akceptovanie Out paketu		clr	ActionFlag		rjmp	EndInt0HandlerNoReadySend:		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		clr	MyAddress		;vychodzi stav odpovede - mojej nNRZI USB adresy		ldi	temp2,0b00000001	;maska na xorovanie		ldi	temp3,8			;pocitadlo bitovSetMyNewUSBAddressLoop:		mov	temp0,MyAddress		;zapamatat si koncovu odpoved		ror	MyUpdatedAddress	;do carry vysielany bit LSB (v smere naskor LSB a potom MSB)		brcs	NoXORBit		;ak je jedna - nemen stav		eor	temp0,temp2		;inak sa bude stav menit podla posledneho bitu odpovedeNoXORBit:		ror	temp0			;posledny bit zmenenej odpovede do carry		rol	MyAddress		;a z carry do koncovej odpovede na miesto LSB (a sucasne prehodenie LSB a MSB poradia)		dec	temp3			;zmensi pocitadlo bitov		brne	SetMyNewUSBAddressLoop	;ak pocitadlo bitov nie je nulove opakuj vysielanie s dalsim bitom		clr	MyUpdatedAddress	;znulovanie adresy ako priznak jej buduceho nemenenia		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	bitcountShiftRemainingBits:		rol	shiftbuf		;posun ostavajuce necele bity na spravnu poziciu		dec	bitcount		brne	ShiftRemainingBits		st	Y+,shiftbuf		;a skopiruj shift register bo buffera - necely byteNoRemainingBits:		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	InfraBufptrX,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	MyAddress,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 odpovedeSendUSBAnswer:	;poslanie kodovanim NRZI OUT buffer do USB		ldi	USBBufptrY,OutputBufferBegin		;pointer na zaciatok vysielacieho bufferaSendUSBBuffer:	;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 temp0SendUSBAnswerLoop:		ldi	bitcount,7		;pocitadlo bitovSendUSBAnswerByteLoop:		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 menitNoXORSend:		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 menitNoXORSendLSB:		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	ZeroBitStufSendUSBAnswerBitstuffLoop:		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 menitNoXORBitstuffSend:		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 cyklyZeroBitStuf:		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 DATA1PIDSendData0PID:		sts	OutputBufferBegin+1,temp0	;DATA0PID byte		ret;------------------------------------------------------------------------------------------ComposeZeroDATA1PIDAnswer:		ldi	temp0,DATA0PID			;DATA0 PID - v skutocnosti sa stoggluje na DATA1PID v nahrati deskriptora		sts	OutputBufferBegin+1,temp0	;nahraj do vyst bufferaComposeZeroAnswer:		ldi	temp0,SOPbyte		sts	OutputBufferBegin+0,temp0	;SOP byte		rcall	ToggleDATAPID			;zmen DATAPID		ldi	temp0,0x00		sts	OutputBufferBegin+2,temp0	;CRC byte		sts	OutputBufferBegin+3,temp0	;CRC byte		ldi	ByteCount,2+2			;dlzka vystupneho buffera (SOP a PID + CRC16)		ret;------------------------------------------------------------------------------------------InitACKBufffer:		ldi	temp0,SOPbyte		sts	ACKBufferBegin+0,temp0		;SOP byte		ldi	temp0,ACKPID		sts	ACKBufferBegin+1,temp0		;ACKPID byte		ret;------------------------------------------------------------------------------------------SendACK:		push	USBBufptrY		push	bitcount		push	OutBitStuffNumber		ldi	USBBufptrY,ACKBufferBegin	;pointer na zaciatok ACK buffera		ldi	ByteCount,2			;pocet vyslanych bytov (iba SOP a ACKPID)		clr	OutBitStuffNumber		rcall	SendUSBBuffer		pop	OutBitStuffNumber		pop	bitcount		pop	USBBufptrY		ret;------------------------------------------------------------------------------------------InitNAKBufffer:		ldi	temp0,SOPbyte		sts	NAKBufferBegin+0,temp0		;SOP byte		ldi	temp0,NAKPID		sts	NAKBufferBegin+1,temp0		;NAKPID byte		ret;------------------------------------------------------------------------------------------SendNAK:		push	OutBitStuffNumber		ldi	USBBufptrY,NAKBufferBegin	;pointer na zaciatok ACK buffera		ldi	ByteCount,2			;pocet vyslanych bytov (iba SOP a NAKPID)		clr	OutBitStuffNumber		rcall	SendUSBBuffer		pop	OutBitStuffNumber		ret;------------------------------------------------------------------------------------------ComposeSTALL:		ldi	temp0,SOPbyte		sts	OutputBufferBegin+0,temp0	;SOP byte		ldi	temp0,STALLPID		sts	OutputBufferBegin+1,temp0	;STALLPID byte		ldi	ByteCount,2			;dlzka vystupneho buffera (SOP a PID)		ret;------------------------------------------------------------------------------------------DecodeNRZI:	;enkodovanie buffera z NRZI kodu do binarneho		push	USBBufptrY		;zalohuj pointer do buffera		push	ByteCount		;zalohuj dlzku buffera		add	ByteCount,USBBufptrY	;koniec buffera do ByteCount		ser	temp0			;na zabezpecenie jednotkoveho carry (v nasledujucej rotacii)NRZIloop:		ror	temp0			;naplnenie carry z predchadzajuceho byte		ld	temp0,Y			;nahraj prijaty byte z buffera		mov	temp2,temp0		;posunuty register o jeden bit vpravo a XOR na funkciu NRZI dekodovania		ror	temp2			;carry do najvyssieho bitu a sucasne posuv		eor	temp2,temp0		;samotne dekodovanie NRZI		com	temp2			;negovanie		st	Y+,temp2		;ulozenie spat ako dekodovany byte a zvys pointer do buffera		cp	USBBufptrY,ByteCount	;ak este neboli vsetky		brne	NRZIloop		;tak opakuj		pop	ByteCount		;obnov dlzku buffera		pop	USBBufptrY		;obnov pointer do buffera		ret				;inak skonci;------------------------------------------------------------------------------------------BitStuff:	;odstranenie bit-stuffingu v buffri		clr	temp3			;pocitadlo vynechanych bitov		clr	lastBitstufNumber	;0xFF do lastBitstufNumber		dec	lastBitstufNumberBitStuffRepeat:		push	USBBufptrY		;zalohuj pointer do buffera		push	ByteCount		;zalohuj dlzku buffera		mov	temp1,temp3		;pocitadlo vsetkych bitov		ldi	temp0,8			;spocitat vsetky bity v bufferiSumAllBits:		add	temp1,temp0		dec	ByteCount		brne	SumAllBits		ldi	temp2,6			;inicializuj pocitadlo jednotiek		pop	ByteCount		;obnov dlzku buffera		push	ByteCount		;zalohuj dlzku buffera		add	ByteCount,USBBufptrY	;koniec buffera do ByteCount		inc	ByteCount		;a pre istotu ho zvys o 2 (kvoli posuvaniu)		inc	ByteCountBitStuffLoop:		ld	temp0,Y			;nahraj prijaty byte z buffera		ldi	bitcount,8		;pocitadlo bitov v byteBitStuffByteLoop:		ror	temp0			;naplnenie carry z LSB		brcs	IncrementBitstuff	;ak LSB=0		ldi	temp2,7			;inicializuj pocitadlo jednotiek +1 (ak bola nula)IncrementBitstuff:		dec	temp2			;zniz pocitadlo jednotiek (predpoklad jednotkoveho bitu)		brne	NeposunBuffer		;ak este nebolo 6 jednotiek za sebou - neposun buffer		cp	temp1,lastBitstufNumber	;		ldi	temp2,6			;inicializuj pocitadlo jednotiek (ak by sa nerobil bitstuffing tak sa musi zacat odznova)		brcc	NeposunBuffer		;ak sa tu uz robil bitstuffing - neposun buffer		dec	temp1		mov	lastBitstufNumber,temp1	;zapamataj si poslednu poziciu bitstuffingu		cpi	bitcount,1		;aby sa ukazovalo na 7 bit (ktory sa ma vymazat alebo kde sa ma vlozit nula)		brne	NoBitcountCorrect		ldi	bitcount,9		inc	USBBufptrY		;zvys pointer do bufferaNoBitcountCorrect:		dec	bitcount		bst	BitStuffInOut,0		brts	CorrectOutBuffer	;ak je Out buffer - zvys dlzku buffera		rcall	PosunDeleteBuffer	;posun In buffer		dec	temp3			;zniz pocitadlo vynechani		rjmp	CorrectBufferEndCorrectOutBuffer:		rcall	PosunInsertBuffer	;posun Out buffer		inc	temp3			;zvys pocitadlo vynechaniCorrectBufferEnd:		pop	ByteCount		;obnov dlzku buffera		pop	USBBufptrY		;obnov pointer do buffera		rjmp	BitStuffRepeat		;a restartni od zaciatkuNeposunBuffer:		dec	temp1			;ak uz boli vsetky bity		breq	EndBitStuff		;ukonci cyklus		dec	bitcount		;zniz pocitadlo bitov v byte		brne	BitStuffByteLoop	;ak este neboli vsetky bity v byte - chod na dalsi bit						;inak nahraj dalsi byte		inc	USBBufptrY		;zvys pointer do buffera		rjmp	BitStuffLoop		;a opakujEndBitStuff:		pop	ByteCount		;obnov dlzku buffera		pop	USBBufptrY		;obnov pointer do buffera		bst	BitStuffInOut,0		brts	IncrementLength		;ak je Out buffer - zvys dlzku Out bufferaDecrementLength:				;ak je In buffer - zniz dlzku In buffera		cpi	temp3,0			;bolo aspon jedno znizenie		breq	NoChangeByteCount	;ak nie - nemen dlzku buffera		dec	ByteCount		;ak je In buffer - zniz dlzku buffera		subi	temp3,256-8		;ak nebolo viac ako 8 bitov naviac		brcc	NoChangeByteCount	;tak skonci		dec	ByteCount		;inak este zniz dlzku buffera		ret				;a skonciIncrementLength:		mov	OutBitStuffNumber,temp3	;zapamataj si pocet bitov naviac		subi	temp3,8			;ak nebolo viac ako 8 bitov naviac		brcs	NoChangeByteCount	;tak skonci		inc	ByteCount		;inak zvys dlzku buffera		mov	OutBitStuffNumber,temp3	;a zapamataj si pocet bitov naviac (znizene o 8)NoChangeByteCount:		ret				;skonci;------------------------------------------------------------------------------------------PosunInsertBuffer:	;posuv buffera o jeden bit vpravo od konca az po poziciu: byte-USBBufptrY a bit-bitcount		mov	temp0,bitcount		;vypocet: bitcount= 9-bitcount		ldi	bitcount,9		sub	bitcount,temp0		;do bitcount poloha bitu, ktory treba nulovat

⌨️ 快捷键说明

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