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

📄 usb90s23x3.asm

📁 单片机的USB ISP软件包,不可多得
💻 ASM
📖 第 1 页 / 共 5 页
字号:
		reti;********************************************************************;* Init program;********************************************************************;------------------------------------------------------------------------------------------reset:			;inicializacia procesora a premennych na spravne hodnoty		ldi	temp0,StackBegin	;inicializacia stacku		out	SPL,temp0		clr	XH			;Infra pointer		clr	YH			;USB pointer		clr	ZH			;ROM pointer		sts	InfraBufferBegin,YH	;znuluj dlzky Infra kodu v bufferi		sts	InfraBufferBegin+1,YH	;znuluj pocitadlo infra kodov v bufferi		clr	MyUpdatedAddress	;nova adresa USB -  nedekodovana		rcall	InitACKBufffer		;inicializacia ACK buffera		rcall	InitNAKBufffer		;inicializacia NAK buffera		rcall	USBReset		;inicializacia USB adresy				sbi	TSOPpullupPort,TSOPpin	;nahodit pull-up na TSOP vstupe		ldi	temp0,(1<<LEDlsb0)+(1<<LEDlsb1)+(1<<LEDlsb2)		out	LEDPortLSB,temp0	;nahodit pull-up na vsetkych LED vstupoch LSB		ldi	temp0,(1<<LEDmsb3)+(1<<LEDmsb4)+(1<<LEDmsb5)+(1<<LEDmsb6)+(1<<LEDmsb7)		out	LEDPortMSB,temp0	;nahodit pull-up na vsetkych LED vstupoch MSB		sbi	PORTD,0			;nahodit pull-up na RxD vstupe		ldi	temp0,BaudRate		;nastavitvysielaciu rychlost UART-u		out	UBRR,temp0		sbi	UCR,TXEN		;povolit vysielanie UART-u		sbi	UCR,RXEN		;povolit prijimanie UART-u		ldi	temp0,0x0F		;INT0 - reagovanie na nabeznu hranu		out	MCUCR,temp0		;		ldi	temp0,1<<INT0		;povolit externy interrupt INT0		out	GIMSK,temp0		rcall	InitCounter		;inicializacia citaca na TSOP zmenu;------------------------------------------------------------------------------------------;********************************************************************;* Main program;********************************************************************		sei					;povolit interrupty globalneMain:		sbis	inputport,DATAminus	;cakanie az sa zmeni D- na 0		rjmp	CheckUSBReset		;a skontroluj, ci to nie je USB reset		cpi	ActionFlag,DoReceiveSetupData		breq	ProcReceiveSetupData		cpi	ActionFlag,DoPrepareOutContinuousBuffer		breq	ProcPrepareOutContinuousBuffer		rjmp	MainCheckUSBReset:		ldi	temp0,255		;pocitadlo trvania reset-u (podla normy je to cca 10ms - tu je to cca 100us)WaitForUSBReset:		sbic	inputport,DATAminus	;cakanie az sa zmeni D+ na 0		rjmp	Main		dec	temp0		brne	WaitForUSBReset		rcall	USBReset		rjmp	MainProcPrepareOutContinuousBuffer:		rcall	PrepareOutContinuousBuffer	;priprav pokracovanie odpovede do buffera		ldi	ActionFlag,DoReadySendAnswer		rjmp	MainProcReceiveSetupData:		ldi	USBBufptrY,InputBufferBegin	;pointer na zaciatok prijimacieho buffera		mov	ByteCount,InputBufferLength	;dlzka vstupneho buffera		rcall	DecodeNRZI		;prevod kodovania NRZI na bity		rcall	MirrorInBufferBytes	;prehodit poradie bitov v bajtoch		rcall	BitStuff		;odstranenie bit stuffing		rcall	CheckCRCIn		;kontrola CRC		rcall	PrepareUSBOutAnswer	;pripravenie odpovede do vysielacieho buffera		ldi	ActionFlag,DoReadySendAnswer		rjmp	Main;********************************************************************;* Main program END;********************************************************************;------------------------------------------------------------------------------------------;********************************************************************;* Interrupt0 interrupt handler;********************************************************************INT0Handler:					;prerusenie INT0		in	backupSREG,SREG		push	temp0		push	temp1		ldi	temp0,3			;pocitadlo trvania log0		ldi	temp1,2			;pocitadlo trvania log1		;cakanie na zaciatok paketuCheckchangeMinus:		sbis	inputport,DATAminus	;cakanie az sa zmeni D- na 1		rjmp	CheckchangeMinusCheckchangePlus:		sbis	inputport,DATAplus	;cakanie az sa zmeni D+ na 1		rjmp	CheckchangePlusDetectSOPEnd:		sbis	inputport,DATAplus		rjmp	Increment0		;D+ =0Increment1:		ldi	temp0,3			;pocitadlo trvania log0		dec	temp1			;kolko cyklov trvala log1		nop		breq	USBBeginPacket		;ak je to koniec SOP - prijimaj paket		rjmp	DetectSOPEndIncrement0:		ldi	temp1,2			;pocitadlo trvania log1		dec	temp0			;kolko cyklov trvala log0		nop		brne	DetectSOPEnd		;ak nenastal SOF - pokracuj		rjmp	EndInt0HandlerPOP2EndInt0Handler:		pop	ACC		pop	InfraBufptrX		pop	temp3		pop	temp2EndInt0HandlerPOP:		pop	USBBufptrY		pop	ByteCount		mov	bitcount,backupbitcount	;obnova bitcount registraEndInt0HandlerPOP2:		pop	temp1		pop	temp0		out	SREG,backupSREG		ldi	shiftbuf,1<<INTF0	;znulovat flag interruptu INTF0		out	GIFR,shiftbuf		reti				;inak skonci (bol iba SOF - kazdu milisekundu)USBBeginPacket:		mov	backupbitcount,bitcount	;zaloha bitcount registra		in	shiftbuf,inputport	;ak ano nacitaj ho ako nulty bit priamo do shift registraUSBloopBegin:		push	ByteCount		;dalsia zaloha registrov (setrenie casu)		push	USBBufptrY		ldi	bitcount,6		;inicializacia pocitadla bitov v bajte		ldi	ByteCount,MAXUSBBYTES	;inicializacia max poctu prijatych bajtov v pakete		ldi	USBBufptrY,InputShiftBufferBegin	;nastav vstupny bufferUSBloop1_6:		in	inputbuf,inputport		cbr	inputbuf,USBpinmask	;odmaskovat spodne 2 bity		breq	USBloopEnd		;ak su nulove - koniec USB packetu		ror	inputbuf		;presun Data+ do shift registra		rol	shiftbuf		dec	bitcount		;zmensi pocitadlo bitov		brne	USBloop1_6		;ak nie je nulove - opakuj naplnanie shift registra		nop				;inak bude nutne skopirovat shift register bo bufferaUSBloop7:		in	inputbuf,inputport		cbr	inputbuf,USBpinmask	;odmaskovat spodne 2 bity		breq	USBloopEnd		;ak su nulove - koniec USB packetu		ror	inputbuf		;presun Data+ do shift registra		rol	shiftbuf		ldi	bitcount,7		;inicializacia pocitadla bitov v bajte		st	Y+,shiftbuf		;skopiruj shift register bo buffera a zvys pointer do bufferaUSBloop0:					;a zacni prijimat dalsi bajt		in	shiftbuf,inputport	;nulty bit priamo do shift registra		cbr	shiftbuf,USBpinmask	;odmaskovat spodne 2 bity		breq	USBloopEnd		;ak su nulove - koniec USB packetu		dec	bitcount		;zmensi pocitadlo bitov		nop				;		dec	ByteCount		;ak sa nedosiahol maximum buffera		brne	USBloop1_6		;tak prijimaj dalej		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;------------------------------------------------------------------------------------------InitCounter:		;inicializacia countera na prijem zmeny z TSOP		ldi	temp0,6			;na zostupnu hranu casovaca - externy pin		out	TCCR0,temp0		ldi	temp0,0xFF		;napln citac naplno - aby hned na nasledujucu hranu pretiekol		out	TCNT0,temp0		ldi	temp0,1<<TOV0		;znuluj pripadny cakajuci flag pretecenia citaca		out	TIFR,temp0		ldi	temp0,1<<TOIE0		;povolit interrupt od casovaca

⌨️ 快捷键说明

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