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

📄 usbtors232.asm

📁 USB技术大全-54.8M.zip
💻 ASM
📖 第 1 页 / 共 5 页
字号:


		rcall	InitACKBufffer		;initialization of ACK buffer
		rcall	InitNAKBufffer		;initialization of NAK buffer

		rcall	USBReset		;initialization of USB addresses

		ldi	temp0,0b00111100	;set pull-up on PORTB
		out	PORTB,temp0
		ldi	temp0,0b11111111	;set pull-up on PORTC
		out	PORTC,temp0
		ldi	temp0,0b11111011	;set pull-up on PORTD
		out	PORTD,temp0

		clr	temp0			;
		out	UBRRH,temp0		;set UART speed High
		out	EEARH,temp0		;zero EEPROM index

		ldi	temp0,1<<U2X		;set mode X2 on UART
		out	USR,temp0
		ldi	temp0,InitBaudRate	;set UART speed
		out	UBRR,temp0
		sbi	UCR,TXEN		;enable transmiting of UART
		sbi	UCR,RXEN		;enable receiving of UART
		sbi	UCR,RXCIE		;enable interrupt from receiving of UART

		ldi	temp0,0x0F		;INT0 - respond to leading edge
		out	MCUCR,temp0		;
		ldi	temp0,1<<INT0		;enable external interrupt INT0
		out	GIMSK,temp0
;------------------------------------------------------------------------------------------
;********************************************************************
;* Main program
;********************************************************************
		sei					;enable interrupts globally
Main:
		sbis	inputport,DATAminus	;waiting till change D- to 0
		rjmp	CheckUSBReset		;and check, if isn't USB reset

		cpi	ActionFlag,DoReceiveSetupData
		breq	ProcReceiveSetupData
		cpi	ActionFlag,DoPrepareOutContinuousBuffer
		breq	ProcPrepareOutContinuousBuffer
		rjmp	Main

CheckUSBReset:
		ldi	temp0,255		;counter duration of reset (according to specification is that cca 10ms - here is cca 100us)
WaitForUSBReset:
		sbic	inputport,DATAminus	;waiting till change D+ to 0
		rjmp	Main
		dec	temp0
		brne	WaitForUSBReset
		rcall	USBReset
		rjmp	Main

ProcPrepareOutContinuousBuffer:
		rcall	PrepareOutContinuousBuffer	;prepare next sequence of answer to buffer
		ldi	ActionFlag,DoReadySendAnswer
		rjmp	Main
ProcReceiveSetupData:
		ldi	USBBufptrY,InputBufferBegin	;pointer to begin of receiving buffer
		mov	ByteCount,InputBufferLength	;length of input buffer
		rcall	DecodeNRZI		;transfer NRZI coding to bits
		rcall	MirrorInBufferBytes	;invert bits order in bytes
		rcall	BitStuff		;removal of bitstuffing
		;rcall	CheckCRCIn		;check CRC
		rcall	PrepareUSBOutAnswer	;prepare answers to transmitting buffer
		ldi	ActionFlag,DoReadySendAnswer
		rjmp	Main
;********************************************************************
;* Main program END
;********************************************************************
;------------------------------------------------------------------------------------------
;********************************************************************
;* Interrupt0 interrupt handler
;********************************************************************
INT0Handler:					;interrupt INT0
		in	backupSREG,SREG
		push	temp0
		push	temp1

		ldi	temp0,3			;counter of duration log0
		ldi	temp1,2			;counter of duration log1
		;waiting for begin packet
CheckchangeMinus:
		sbis	inputport,DATAminus	;waiting till change D- to 1
		rjmp	CheckchangeMinus
CheckchangePlus:
		sbis	inputport,DATAplus	;waiting till change D+ to 1
		rjmp	CheckchangePlus
DetectSOPEnd:
		sbis	inputport,DATAplus
		rjmp	Increment0		;D+ =0
Increment1:
		ldi	temp0,3			;counter of duration log0
		dec	temp1			;how many cycles takes log1
		nop
		breq	USBBeginPacket		;if this is end of SOP - receive packet
		rjmp	DetectSOPEnd
Increment0:
		ldi	temp1,2			;counter of duration log1
		dec	temp0			;how many cycles take log0
		nop
		brne	DetectSOPEnd		;if there isn't SOF - continue
		rjmp	EndInt0HandlerPOP2
EndInt0Handler:
		pop	ACC
		pop	RS232BufptrX
		pop	temp3
		pop	temp2
EndInt0HandlerPOP:
		pop	USBBufptrY
		pop	ByteCount
		mov	bitcount,backupbitcount	;restore bitcount register
EndInt0HandlerPOP2:
		pop	temp1
		pop	temp0
		out	SREG,backupSREG
		ldi	shiftbuf,1<<INTF0	;zero interruptu flag INTF0
		out	GIFR,shiftbuf
		reti				;otherwise finish (was only SOF - every millisecond)

USBBeginPacket:
		mov	backupbitcount,bitcount	;backup bitcount register
		in	shiftbuf,inputport	;if yes load it as zero bit directly to shift register
USBloopBegin:
		push	ByteCount		;additional backup of registers (save of time)
		push	USBBufptrY
		ldi	bitcount,6		;initialization of bits counter in byte
		ldi	ByteCount,MAXUSBBYTES	;initialization of max number of received bytes in packet
		ldi	USBBufptrY,InputShiftBufferBegin	;set the input buffer
USBloop1_6:
		in	inputbuf,inputport
		cbr	inputbuf,USBpinmask	;unmask low 2 bits
		breq	USBloopEnd		;if they are zeros - end of USB packet
		ror	inputbuf		;transfer Data+ to shift register
		rol	shiftbuf
		dec	bitcount		;decrement bits counter
		brne	USBloop1_6		;if it isn't zero - repeat filling of shift register
		nop				;otherwise is necessary copy shift register to buffer
USBloop7:
		in	inputbuf,inputport
		cbr	inputbuf,USBpinmask	;unmask low 2 bits
		breq	USBloopEnd		;if they are zeros - end of USB packet
		ror	inputbuf		;transfer Data+ to shift register
		rol	shiftbuf
		ldi	bitcount,7		;initialization of bits counter in byte
		st	Y+,shiftbuf		;copy shift register into buffer and increment pointer to buffer
USBloop0:					;and start receiving next byte
		in	shiftbuf,inputport	;zero bit directly to shift register
		cbr	shiftbuf,USBpinmask	;unmask low 2 bits
		breq	USBloopEnd		;if they are zeros - end of USB packet
		dec	bitcount		;decrement bits counter
		nop				;
		dec	ByteCount		;if not reached maximum buffer
		brne	USBloop1_6		;then receive next

		rjmp	EndInt0HandlerPOP	;otherwise repeat back from begin

USBloopEnd:
		cpi	USBBufptrY,InputShiftBufferBegin+3	;if at least 3 byte not received
		brcs	EndInt0HandlerPOP	;then finish
		lds	temp0,InputShiftBufferBegin+0	;identifier of packet to temp0
		lds	temp1,InputShiftBufferBegin+1	;address to temp1
		brne	TestDataPacket		;if is length different from 3 - then this can be only DataPaket
TestIOPacket:
;		cp	temp1,MyAddress		;if this isn't assigned (address) for me
;		brne	TestDataPacket		;then this can be still DataPacket
TestSetupPacket:;test to SETUP packet
		cpi	temp0,nNRZISETUPPID
		brne	TestOutPacket		;if this isn't Setup PID - decode other packet
		cp	temp1,MyInAddress	;if this isn't assigned (address) for me
		brne	TestDataPacket		;then this can be still DataPacket
		ldi	State,SetupState
		rjmp	EndInt0HandlerPOP	;if this is Setup PID - receive consecutive Data packet
TestOutPacket:	;test for OUT packet
		cpi	temp0,nNRZIOUTPID
		brne	TestInPacket		;if this isn't Out PID - decode other packet
		cp	temp1,MyOutAddress	;if this isn't assigned (address) for me
		brne	TestDataPacket		;then this can be still DataPacket
		ldi	State,OutState
		rjmp	EndInt0HandlerPOP	;if this is Out PID - receive consecutive Data packet
TestInPacket:	;test on IN packet
		cpi	temp0,nNRZIINPID
		brne	TestDataPacket		;if this isn't In PID - decode other packet
		cp	temp1,MyInAddress	;if this isn't assigned (address) for me
		breq	AnswerToInRequest
TestDataPacket:	;test for DATA0 and DATA1 packet
		cpi	temp0,nNRZIDATA0PID
		breq	Data0Packet		;if this isn't Data0 PID - decode other packet
		cpi	temp0,nNRZIDATA1PID
		brne	NoMyPacked		;if this isn't Data1 PID - decode other packet
Data0Packet:
		cpi	State,SetupState	;if was state Setup
		breq	ReceiveSetupData	;receive it
		cpi	State,OutState		;if was state Out
		breq	ReceiveOutData		;receive it
NoMyPacked:
		ldi	State,BaseState		;zero state
		rjmp	EndInt0HandlerPOP	;and receive consecutive Data packet

AnswerToInRequest:
		push	temp2			;backup next registers and continue
		push	temp3
		push	RS232BufptrX
		push	ACC
		cpi	ActionFlag,DoReadySendAnswer	;if isn't prepared answer
		brne	NoReadySend		;then send NAK
		rcall	SendPreparedUSBAnswer	;transmitting answer back
		cpi	State,AddressChangeState ;if state is AddressChange
		breq	SetMyNewUSBAddress	;then is necessary to change USB address
		ldi	State,InState
		ldi	ActionFlag,DoPrepareOutContinuousBuffer
		rjmp	EndInt0Handler		;and repeat - wait for next response from USB
ReceiveSetupData:
		push	temp2			;backup next registers and continue
		push	temp3
		push	RS232BufptrX
		push	ACC
		rcall	SendACK			;accept Setup Data packet
		rcall	FinishReceiving		;finish receiving
		ldi	ActionFlag,DoReceiveSetupData
		rjmp	EndInt0Handler
ReceiveOutData:
		push	temp2			;backup next registers and continue
		push	temp3
		push	RS232BufptrX
		push	ACC
		cpi	ActionFlag,DoReceiveSetupData	;if is currently in process command Setup
		breq	NoReadySend		;then send NAK
		rcall	SendACK			;accept Out packet
		clr	ActionFlag
		rjmp	EndInt0Handler
NoReadySend:
		rcall	SendNAK			;still I am not ready to answer
		rjmp	EndInt0Handler		;and repeat - wait for next response from USB
;------------------------------------------------------------------------------------------
SetMyNewUSBAddress:		;set new USB address in NRZI coded
		lds	MyInAddress,MyInAddressSRAM
		lds	MyOutAddress,MyOutAddressSRAM
		rjmp	EndInt0Handler
;------------------------------------------------------------------------------------------
FinishReceiving:		;corrective actions for receive termination
		cpi	bitcount,7		;transfer to buffer also last not completed byte
		breq	NoRemainingBits		;if were all bytes transfered, then nothing transfer
		inc	bitcount
ShiftRemainingBits:
		rol	shiftbuf		;shift remaining not completed bits on right position
		dec	bitcount
		brne	ShiftRemainingBits
		st	Y+,shiftbuf		;and copy shift register bo buffer - not completed byte
NoRemainingBits:
		mov	ByteCount,USBBufptrY
		subi	ByteCount,InputShiftBufferBegin-1	;in ByteCount is number of received bytes (including not completed bytes)

		mov	InputBufferLength,ByteCount		;and save for use in main program
		ldi	USBBufptrY,InputShiftBufferBegin	;pointer to begin of receiving shift buffer
		ldi	RS232BufptrX,InputBufferBegin+1		;data buffer (leave out SOP)
		push	XH					;save RS232BufptrX Hi index
		clr	XH
MoveDataBuffer:
		ld	temp0,Y+
		st	X+,temp0
		dec	ByteCount
		brne	MoveDataBuffer

		pop	XH					;restore RS232BufptrX Hi index
		ldi	ByteCount,nNRZISOPbyte
		sts	InputBufferBegin,ByteCount		;like received SOP - it is not copied from shift buffer
		ret
;------------------------------------------------------------------------------------------
;********************************************************************
;* Other procedures
;********************************************************************
;------------------------------------------------------------------------------------------
USBReset:		;initialization of USB state engine
		ldi	temp0,nNRZIADDR0	;initialization of USB address
		mov	MyOutAddress,temp0
		mov	MyInAddress,temp0
		clr	State			;initialization of state engine
		clr	BitStuffInOut
		clr	OutBitStuffNumber
		clr	ActionFlag
		clr	RAMread			;will be reading from ROM
		sts	ConfigByte,RAMread	;unconfigured state
		ret
;------------------------------------------------------------------------------------------
SendPreparedUSBAnswer:	;transmitting by NRZI coding OUT buffer with length OutputBufferLength to USB
		mov	ByteCount,OutputBufferLength		;length of answer
SendUSBAnswer:	;transmitting by NRZI coding OUT buffer to USB
		ldi	USBBufptrY,OutputBufferBegin		;pointer to begin of transmitting buffer
SendUSBBuffer:	;transmitting by NRZI coding given buffer to USB
		ldi	temp1,0			;incrementing pointer (temporary variable)
		mov	temp3,ByteCount		;byte counter: temp3 = ByteCount
		ldi	temp2,0b00000011	;mask for xoring
		ld	inputbuf,Y+		;load first byte to inputbuf and increment pointer to buffer
						;USB as output:
		cbi	outputport,DATAplus	;down DATAPLUS : idle state of USB port
		sbi	outputport,DATAminus	;set DATAMINUS : idle state of USB port
		sbi	USBdirection,DATAplus	;DATAPLUS as output
		sbi	USBdirection,DATAminus	;DATAMINUS as output

		in	temp0,outputport	;idle state of USB port to temp0
SendUSBAnswerLoop:
		ldi	bitcount,7		;bits counter
SendUSBAnswerByteLoop:
		nop				;delay because timing
		ror	inputbuf		;to carry transmiting bit (in direction first LSB then MSB)
		brcs	NoXORSend		;if that it is one - don't change USB state
		eor	temp0,temp2		;otherwise state will be changed
NoXORSend:

⌨️ 快捷键说明

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