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

📄 usb-prog.asm

📁 单片机的USB ISP软件包,不可多得
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;***************************************************************************;* U S B   S T A C K   F O R   T H E   A V R   F A M I L Y;* ;* File Name            :"USB90S2313.asm";* Title                :USB stack + Infrared remote control to nonUSB MCU;* Date                 :5.4.2003;* Version              :1.6;* Target MCU           :AT90S2313-10,AT90S2323-10,AT90S2343-10;* AUTHOR		:Ing. Igor Cesko;* 			 Slovakia;* 			 cesko@internet.sk;* 			 http://www.cesko.host.sk;*;* DESCRIPTION:;*  USB protocol implementation into MCU with noUSB interface:;*  Device:;*  Infrared remote control with TSOP17xx/SFH511x sensor and USB connection;*  + Universal USB interface (8-bit I/O port + RS232 serial line + EEPROM);*;* The timing is adapted for 12 MHz crystal (overclocked MCU !!!);*;* Copyright (c) Ing. Igor Cesko 2002-2003;*;*    This program is free software; you can redistribute it and/or modify;*    it under the terms of the GNU General Public License as published by;*    the Free Software Foundation; either version 2 of the License, or;*    (at your option) any later version.;*;*    This program is distributed in the hope that it will be useful,;*    but WITHOUT ANY WARRANTY; without even the implied warranty of;*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the;*    GNU General Public License for more details.;*;*    You should have received a copy of the GNU General Public License;*    along with this program; if not, write to the Free Software;*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.;*;***************************************************************************;***************************************************************************.include "2313def.inc".equ	inputport		=PINB.equ	outputport		=PORTB.equ	USBdirection		=DDRB.equ	DATAplus		=1		;signal D+ na PB1.equ	DATAminus		=0		;signal D- na PB0 - treba dat na tento pin pull-up 1.5kOhm.equ	USBpinmask		=0b11111100	;mask low 2 bits (D+,D-) on PB.equ	USBpinmaskDplus		=~(1<<DATAplus)	;mask D+ bit on PB.equ	USBpinmaskDminus	=~(1<<DATAminus);mask D- bit on PB.equ	TSOPPort		=PINB.equ	TSOPpullupPort		=PORTB.equ	TSOPPin			=2		;signal OUT z IR senzora TSOP1738 na PB2.equ	LEDPortLSB		=PORTD		;pripojenie LED diod LSB.equ	LEDPinLSB		=PIND		;pripojenie LED diod LSB (vstup).equ	LEDdirectionLSB		=DDRD		;vstup/vystup LED LSB.equ	LEDPortMSB		=PORTB		;pripojenie LED diod MSB.equ	LEDPinMSB		=PINB		;pripojenie LED diod MSB  (vstup).equ	LEDdirectionMSB		=DDRB		;vstup/vystup LED MSB.equ	LEDlsb0			=3		;LED0 na pin PD3.equ	LEDlsb1			=5		;LED1 na pin PD5.equ	LEDlsb2			=6		;LED2 na pin PD6.equ	LEDmsb3			=3		;LED3 na pin PB3.equ	LEDmsb4			=4		;LED4 na pin PB4.equ	LEDmsb5			=5		;LED5 na pin PB5.equ	LEDmsb6			=6		;LED6 na pin PB6.equ	LEDmsb7			=7		;LED7 na pin PB7.equ	SOPbyte			=0b10000000	;Start of Packet byte.equ	DATA0PID		=0b11000011	;PID pre DATA0 pole.equ	DATA1PID		=0b01001011	;PID pre DATA1 pole.equ	OUTPID			=0b11100001	;PID pre OUT pole.equ	INPID			=0b01101001	;PID pre IN pole.equ	SOFPID			=0b10100101	;PID pre SOF pole.equ	SETUPPID		=0b00101101	;PID pre SETUP pole.equ	ACKPID			=0b11010010	;PID pre ACK pole.equ	NAKPID			=0b01011010	;PID pre NAK pole.equ	STALLPID		=0b00011110	;PID pre STALL pole.equ	PREPID			=0b00111100	;PID pre PRE pole.equ	nSOPbyte		=0b00000001	;Start of Packet byte - opacne poradie.equ	nDATA0PID		=0b11000011	;PID pre DATA0 pole - opacne poradie.equ	nDATA1PID		=0b11010010	;PID pre DATA1 pole - opacne poradie.equ	nOUTPID			=0b10000111	;PID pre OUT pole - opacne poradie.equ	nINPID			=0b10010110	;PID pre IN pole - opacne poradie.equ	nSOFPID			=0b10100101	;PID pre SOF pole - opacne poradie.equ	nSETUPPID		=0b10110100	;PID pre SETUP pole - opacne poradie.equ	nACKPID			=0b01001011	;PID pre ACK pole - opacne poradie.equ	nNAKPID			=0b01011010	;PID pre NAK pole - opacne poradie.equ	nSTALLPID		=0b01111000	;PID pre STALL pole - opacne poradie.equ	nPREPID			=0b00111100	;PID pre PRE pole - opacne poradie.equ	nNRZITokenPID		=~0b10000000	;PID maska pre Token paket (IN,OUT,SOF,SETUP) - opacne poradie NRZI.equ	nNRZISOPbyte		=~0b10101011	;Start of Packet byte - opacne poradie NRZI.equ	nNRZIDATA0PID		=~0b11010111	;PID pre DATA0 pole - opacne poradie NRZI.equ	nNRZIDATA1PID		=~0b11001001	;PID pre DATA1 pole - opacne poradie NRZI.equ	nNRZIOUTPID		=~0b10101111	;PID pre OUT pole - opacne poradie NRZI.equ	nNRZIINPID		=~0b10110001	;PID pre IN pole - opacne poradie NRZI.equ	nNRZISOFPID		=~0b10010011	;PID pre SOF pole - opacne poradie NRZI.equ	nNRZISETUPPID		=~0b10001101	;PID pre SETUP pole - opacne poradie NRZI.equ	nNRZIACKPID		=~0b00100111	;PID pre ACK pole - opacne poradie NRZI.equ	nNRZINAKPID		=~0b00111001	;PID pre NAK pole - opacne poradie NRZI.equ	nNRZISTALLPID		=~0b00000111	;PID pre STALL pole - opacne poradie NRZI.equ	nNRZIPREPID		=~0b01111101	;PID pre PRE pole - opacne poradie NRZI.equ	nNRZIADDR0		=~0b01010101	;Adresa = 0 - opacne poradie NRZI						;stavove byty - State.equ	BaseState		=0		;.equ	SetupState		=1		;.equ	InState			=2		;.equ	OutState		=3		;.equ	SOFState		=4		;.equ	DataState		=5		;						;Flagy pozadovanej akcie.equ	DoNone					=0.equ	DoReceiveOutData			=1.equ	DoReceiveSetupData			=2.equ	DoPrepareOutContinuousBuffer		=3.equ	DoReadySendAnswer			=4.equ	CRC5poly		=0b00101		;CRC5 polynom.equ	CRC5zvysok		=0b01100		;CRC5 zvysok po uspesnpm CRC5.equ	CRC16poly		=0b1000000000000101	;CRC16 polynom.equ	CRC16zvysok		=0b1000000000001101	;CRC16 zvysok po uspesnom CRC16.equ	MAXUSBBYTES		=14			;maximum bytes in USB input message.equ	NumberOfFirstBits	=10			;kolko prvych bitov moze byt dlhsich.equ	NoFirstBitsTimerOffset	=256-12800*12/1024	;Timeout 12.8ms (12800us) na ukoncenie prijmu po uvodnych bitoch (12Mhz:clock, 1024:timer predivider, 256:timer overflow value).equ	BaudRate		=12000000/16/57600-1	;nastavit vysielaciu rychlost UART-u na 57600 (pre 12MHz=12000000Hz).equ	InputBufferBegin	=RAMEND-127				;zaciatok prijimacieho shift buffera.equ	InputShiftBufferBegin	=InputBufferBegin+MAXUSBBYTES		;zaciatok prijimacieho buffera.equ	SPIBuffer       	=InputShiftBufferBegin+MAXUSBBYTES	; location of SPI return value buffer ;was zaciatok buffera pre Infra prijem.equ	OutputBufferBegin	=RAMEND-MAXUSBBYTES-2	;zaciatok vysielacieho buffera.equ	AckBufferBegin		=OutputBufferBegin-3	;zaciatok vysielacieho buffera Ack.equ	NakBufferBegin		=AckBufferBegin-3	;zaciatok vysielacieho buffera Nak.equ	StackBegin		=NakBufferBegin-1	;spodok zasobnika.def	ConfigByte		=R1		;0=unconfigured state.def	backupbitcount		=R2		;zaloha bitcount registra v INT0 preruseni.def	RAMread			=R3		;ci sa ma citat zo SRAM-ky.def	backupSREGTimer		=R4		;zaloha Flag registra v Timer interrupte.def	backupSREG		=R5		;zaloha Flag registra v INT0 preruseni.def	ACC			=R6		;accumulator.def	lastBitstufNumber	=R7		;pozicia bitstuffingu.def	OutBitStuffNumber	=R8		;kolko bitov sa ma este odvysielat z posledneho bytu - bitstuffing.def	BitStuffInOut		=R9		;ci sa ma vkladat alebo mazat bitstuffing.def	TotalBytesToSend	=R10		;kolko sa ma poslat bytov.def	TransmitPart		=R11		;poradove cislo vysielacej casti.def	InputBufferLength	=R12		;dlzka pripravena vo vstupnom USB bufferi.def	OutputBufferLength	=R13		;dlzka odpovede pripravena v USB bufferi.def	MyUpdatedAddress	=R14		;moja USB adresa na update.def	MyAddress		=R15		;moja USB adresa.def	ActionFlag		=R16		;co sa ma urobit v hlavnej slucke programu.def	temp3			=R17		;temporary register.def	temp2			=R18		;temporary register.def	temp1			=R19		;temporary register.def	temp0			=R20		;temporary register.def	bitcount		=R21		;counter of bits in byte.def	ByteCount		=R22		;pocitadlo maximalneho poctu prijatych bajtov.def	inputbuf		=R23		;prijimaci register.def	shiftbuf		=R24		;posuvny prijimaci register.def	State			=R25		;byte stavu stavoveho stroja.def	InfraBufptrX		=R26		;XL register - pointer do buffera prijatych IR kodov.def	InfraBufferFull		=R27		;XH register - priznak plneho Infra Buffera.def	USBBufptrY		=R28		;YL register - pointer do USB buffera input/output.def	ROMBufptrZ		=R30		;ZL register - pointer do buffera ROM dat;poziadavky na deskriptory.equ	GET_STATUS		=0.equ	CLEAR_FEATURE		=1.equ	SET_FEATURE		=3.equ	SET_ADDRESS		=5.equ	GET_DESCRIPTOR		=6.equ	SET_DESCRIPTOR		=7.equ	GET_CONFIGURATION	=8.equ	SET_CONFIGURATION	=9.equ	GET_INTERFACE		=10.equ	SET_INTERFACE		=11.equ	SYNCH_FRAME		=12;typy deskriptorov.equ	DEVICE			=1.equ	CONFIGURATION		=2.equ	STRING			=3.equ	INTERFACE		=4.equ	ENDPOINT		=5;------------------------------------------------------------------------------------------;********************************************************************;* Interrupt table;********************************************************************.cseg;------------------------------------------------------------------------------------------.org 0						;po resete		rjmp	reset;------------------------------------------------------------------------------------------.org INT0addr					;externe prerusenie INT0		rjmp	INT0handler;------------------------------------------------------------------------------------------.org OVF0addr					;citac/casovac 0OVF0handler:		reti;********************************************************************;* Init program;********************************************************************;------------------------------------------------------------------------------------------reset:			;inicializacia procesora a premennych na spravne hodnoty		ldi	temp0,StackBegin	;inicializacia stacku		out	SPL,temp0		clr	XH			;was Infra pointer		clr	YH			;USB pointer		clr	ZH			;ROM pointer		clr	MyUpdatedAddress	;nova adresa USB -  nedekodovana		rcall	InitACKBufffer		;inicializacia ACK buffera		rcall	InitNAKBufffer		;inicializacia NAK buffera		rcall	USBReset		;inicializacia USB adresy		;	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;------------------------------------------------------------------------------------------;********************************************************************;* 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

⌨️ 快捷键说明

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