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

📄 usbtors232.asm

📁 USB技术大全-54.8M.zip
💻 ASM
📖 第 1 页 / 共 5 页
字号:
		out	outputport,temp0	;send out to USB
		dec	bitcount		;decrement bits counter - according to carry flag
		brne	SendUSBAnswerByteLoop	;if bits counter isn't zero - repeat transmiting with next bit
		sbrs	inputbuf,0		;if is transmiting bit one - don't change USB state
		eor	temp0,temp2		;otherwise state will be changed
NoXORSendLSB:
		dec	temp3			;decrement bytes counter
		ld	inputbuf,Y+		;load next byte and increment pointer to buffer
		out	outputport,temp0	;transmit to USB
		brne	SendUSBAnswerLoop	;repeat for all buffer (till temp3=0)

		mov	bitcount,OutBitStuffNumber	;bits counter for bitstuff
		cpi	bitcount,0		;if not be needed bitstuff
		breq	ZeroBitStuf
SendUSBAnswerBitstuffLoop:
		ror	inputbuf		;to carry transmiting bit (in direction first LSB then MSB)
		brcs	NoXORBitstuffSend	;if is one - don't change state on USB
		eor	temp0,temp2		;otherwise state will be changed
NoXORBitstuffSend:
		out	outputport,temp0	;transmit to USB
		nop				;delay because of timing
		dec	bitcount		;decrement bits counter - according to carry flag
		brne	SendUSBAnswerBitstuffLoop	;if bits counter isn't zero - repeat transmiting with next bit
		ld	inputbuf,Y		;delay 2 cycle
ZeroBitStuf:
		nop				;delay 1 cycle
		cbr	temp0,3
		out	outputport,temp0	;transmit EOP on USB

		ldi	bitcount,5		;delay counter: EOP shouls exists 2 bits (16 cycle at 12MHz)
SendUSBWaitEOP:
		dec	bitcount
		brne	SendUSBWaitEOP

		sbi	outputport,DATAminus	;set DATAMINUS : idle state on USB port
		sbi	outputport,DATAminus	;delay 2 cycle: Idle should exists 1 bit (8 cycle at 12MHz)
		cbi	USBdirection,DATAplus	;DATAPLUS as input
		cbi	USBdirection,DATAminus	;DATAMINUS as input
		cbi	outputport,DATAminus	;reset DATAMINUS : the third state on USB port
		ret
;------------------------------------------------------------------------------------------
ToggleDATAPID:
		lds	temp0,OutputBufferBegin+1	;load last PID
		cpi	temp0,DATA1PID			;if last was DATA1PID byte
		ldi	temp0,DATA0PID
		breq	SendData0PID			;then send zero answer with DATA0PID
		ldi	temp0,DATA1PID			;otherwise send zero answer with DATA1PID
SendData0PID:
		sts	OutputBufferBegin+1,temp0	;DATA0PID byte
		ret
;------------------------------------------------------------------------------------------
ComposeZeroDATA1PIDAnswer:
		ldi	temp0,DATA0PID			;DATA0 PID - in the next will be toggled to DATA1PID in load descriptor
		sts	OutputBufferBegin+1,temp0	;load to output buffer
ComposeZeroAnswer:
		ldi	temp0,SOPbyte
		sts	OutputBufferBegin+0,temp0	;SOP byte
		rcall	ToggleDATAPID			;change DATAPID
		ldi	temp0,0x00
		sts	OutputBufferBegin+2,temp0	;CRC byte
		sts	OutputBufferBegin+3,temp0	;CRC byte
		ldi	ByteCount,2+2			;length of output buffer (SOP and 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 to begin of ACK buffer
		ldi	ByteCount,2			;number of transmit bytes (only SOP and 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 to begin of ACK buffer
		ldi	ByteCount,2			;number of transmited bytes (only SOP and 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			;length of output buffer (SOP and PID)
		ret
;------------------------------------------------------------------------------------------
DecodeNRZI:	;encoding of buffer from NRZI code to binary
		push	USBBufptrY		;back up pointer to buffer
		push	ByteCount		;back up length of buffer
		add	ByteCount,USBBufptrY	;end of buffer to ByteCount
		ser	temp0			;to ensure unit carry (in the next rotation)
NRZIloop:
		ror	temp0			;filling carry from previous byte
		ld	temp0,Y			;load received byte from buffer
		mov	temp2,temp0		;shifted register to one bit to the right and XOR for function of NRZI decoding
		ror	temp2			;carry to most significant digit bit and shift
		eor	temp2,temp0		;NRZI decoding
		com	temp2			;negate
		st	Y+,temp2		;save back as decoded byte and increment pointer to buffer
		cp	USBBufptrY,ByteCount	;if not all bytes
		brne	NRZIloop		;then repeat
		pop	ByteCount		;restore buffer length
		pop	USBBufptrY		;restore pointer to buffer
		ret				;otherwise finish
;------------------------------------------------------------------------------------------
BitStuff:	;removal of bitstuffing in buffer
		clr	temp3			;counter of omitted bits
		clr	lastBitstufNumber	;0xFF to lastBitstufNumber
		dec	lastBitstufNumber
BitStuffRepeat:
		push	USBBufptrY		;back up pointer to buffer
		push	ByteCount		;back up buffer length
		mov	temp1,temp3		;counter of all bits
		ldi	temp0,8			;sum all bits in buffer
SumAllBits:
		add	temp1,temp0
		dec	ByteCount
		brne	SumAllBits
		ldi	temp2,6			;initialize counter of ones
		pop	ByteCount		;restore buffer length
		push	ByteCount		;back up buffer length
		add	ByteCount,USBBufptrY	;end of buffer to ByteCount
		inc	ByteCount		;and for safety increment it with 2 (because of shifting)
		inc	ByteCount
BitStuffLoop:
		ld	temp0,Y			;load received byte from buffer
		ldi	bitcount,8		;bits counter in byte
BitStuffByteLoop:
		ror	temp0			;filling carry from LSB
		brcs	IncrementBitstuff	;if that LSB=0
		ldi	temp2,7			;initialize counter of ones +1 (if was zero)
IncrementBitstuff:
		dec	temp2			;decrement counter of ones (assumption of one bit)
		brne	DontShiftBuffer		;if there was not 6 ones together - don't shift buffer
		cp	temp1,lastBitstufNumber	;
		ldi	temp2,6			;initialize counter of ones (if no bitstuffing will be made then must be started again)
		brcc	DontShiftBuffer		;if already was made bitstuffing - don't shift buffer

		dec	temp1	;
		mov	lastBitstufNumber,temp1	;remember last position of bitstuffing
		cpi	bitcount,1		;for pointing to 7-th bit (which must be deleted or where to insert zero)
		brne	NoBitcountCorrect
		ldi	bitcount,9	;
		inc	USBBufptrY		;zvys pointer do buffera	ENG;increment pointer to buffer
NoBitcountCorrect:
		dec	bitcount
		bst	BitStuffInOut,0
		brts	CorrectOutBuffer	;if this is Out buffer - increment buffer length
		rcall	ShiftDeleteBuffer	;shift In buffer
		dec	temp3			;decrement counter of omission
		rjmp	CorrectBufferEnd
CorrectOutBuffer:
		rcall	ShiftInsertBuffer	;shift Out buffer
		inc	temp3			;increment counter of omission
CorrectBufferEnd:
		pop	ByteCount		;restore buffer length
		pop	USBBufptrY		;restore pointer to buffer
		rjmp	BitStuffRepeat		;and restart from begin
DontShiftBuffer:
		dec	temp1			;if already were all bits
		breq	EndBitStuff		;finish cycle
		dec	bitcount		;decrement bits counter in byte
		brne	BitStuffByteLoop	;if not yet been all bits in byte - go to next bit
						;otherwise load next byte
		inc	USBBufptrY		;increment pointer to buffer
		rjmp	BitStuffLoop		;and repeat
EndBitStuff:
		pop	ByteCount		;restore buffer length
		pop	USBBufptrY		;restore pointer to buffer
		bst	BitStuffInOut,0
		brts	IncrementLength		;if this is Out buffer - increment length of Out buffer
DecrementLength:				;if this is In buffer - decrement length of In buffer
		cpi	temp3,0			;was at least one decrement
		breq	NoChangeByteCount	;if no - don't change buffer length
		dec	ByteCount		;if this is In buffer - decrement buffer length
		subi	temp3,256-8		;if there wasn't above 8 bits over
		brcc	NoChangeByteCount	;then finish
		dec	ByteCount		;otherwise next decrement buffer length
		ret				;and finish
IncrementLength:
		mov	OutBitStuffNumber,temp3	;remember number of bits over
		subi	temp3,8			;if there wasn't above 8 bits over
		brcs	NoChangeByteCount	;then finish
		inc	ByteCount		;otherwise increment buffer length
		mov	OutBitStuffNumber,temp3	;and remember number of bits over (decremented by 8)
NoChangeByteCount:
		ret				;finish
;------------------------------------------------------------------------------------------
ShiftInsertBuffer:	;shift buffer by one bit to right from end till to position: byte-USBBufptrY and bit-bitcount
		mov	temp0,bitcount		;calculation: bitcount= 9-bitcount
		ldi	bitcount,9
		sub	bitcount,temp0		;to bitcount bit position, which is necessary to clear

		ld	temp1,Y			;load byte which still must be shifted from position bitcount
		rol	temp1			;and shift to the left through Carry (transmission from higher byte and LSB to Carry)
		ser	temp2			;FF to mask - temp2
HalfInsertPosuvMask:
		lsl	temp2			;zero to the next low bit of mask
		dec	bitcount		;till not reached boundary of shifting in byte
		brne	HalfInsertPosuvMask

		and	temp1,temp2		;unmask that remains only high shifted bits in temp1
		com	temp2			;invert mask
		lsr	temp2			;shift mask to the right - for insertion of zero bit
		ld	temp0,Y			;load byte which must be shifted from position bitcount to temp0
		and	temp0,temp2		;unmask to remains only low non-shifted bits in temp0
		or	temp1,temp0		;and put together shifted and nonshifted part

		ld	temp0,Y			;load byte which must be shifted from position bitcount
		rol	temp0			;and shift it to the left through Carry (to set right Carry for further carry)
		st	Y+,temp1		;and load back modified byte
ShiftInsertBufferLoop:
		cpse	USBBufptrY,ByteCount	;if are not all entire bytes
		rjmp	NoEndShiftInsertBuffer	;then continue
		ret				;otherwise finish
NoEndShiftInsertBuffer:
		ld	temp1,Y			;load byte
		rol	temp1			;and shift to the left through Carry (carry from low byte and LSB to Carry)
		st	Y+,temp1		;and store back
		rjmp	ShiftInsertBufferLoop	;and continue
;------------------------------------------------------------------------------------------
ShiftDeleteBuffer:	;shift buffer one bit to the left from end to position: byte-USBBufptrY and bit-bitcount
		mov	temp0,bitcount		;calculation: bitcount= 9-bitcount
		ldi	bitcount,9
		sub	bitcount,temp0		;to bitcount bit position, which must be shifted
		mov	temp0,USBBufptrY	;backup pointera to buffer
		inc	temp0			;position of completed bytes to temp0
		mov	USBBufptrY,ByteCount	;maximum position to pointer
ShiftDeleteBufferLoop:
		ld	temp1,-Y		;decrement buffer and load byte
		ror	temp1			;and right shift through Carry (carry from higher byte and LSB to Carry)
		st	Y,temp1			;and store back
		cpse	USBBufptrY,temp0	;if there are not all entire bytes
		rjmp	ShiftDeleteBufferLoop	;then continue

		ld	temp1,-Y		;decrement buffer and load byte which must be shifted from position bitcount
		ror	temp1			;and right shift through Carry (carry from higher byte and LSB to Carry)
		ser	temp2			;FF to mask - temp2
HalfDeletePosuvMask:
		dec	bitcount		;till not reached boundary of shifting in byte
		breq	DoneMask
		lsl	temp2			;zero to the next low bit of mask
		rjmp	HalfDeletePosuvMask
DoneMask:
		and	temp1,temp2		;unmask to remain only high shifted bits in temp1
		com	temp2			;invert mask
		ld	temp0,Y			;load byte which must be shifted from position bitcount to temp0
		and	temp0,temp2		;unmask to remain only low nonshifted bits in temp0
		or	temp1,temp0		;and put together shifted and nonshifted part
		st	Y,temp1			;and store back
		ret				;and finish
;------------------------------------------------------------------------------------------
MirrorInBufferBytes:
		push	USBBufptrY
		push	ByteCount
		ldi	USBBufptrY,InputBufferBegin
		rcall	MirrorBufferBytes
		pop	ByteCount
		pop	USBBufptrY
		ret
;------------------------------------------------------------------------------------------
MirrorBufferBytes:
		add	ByteCount,USBBufptrY	;ByteCount shows to the end of message
MirrorBufferloop:
		ld	temp0,Y			;load received byte from buffer
		ldi	temp1,8			;bits counter
MirrorBufferByteLoop:
		ror	temp0			;to carry next least bit
		rol	temp2			;from carry next bit to reverse order
		dec	temp1			;was already entire byte
		brne	MirrorBufferByteLoop	;if no then repeat next least bit
		st	Y+,temp2		;save back as reversed byte  and increment pointer to buffer
		cp	USBBufptrY,ByteCount	;if not yet been all
		brne	MirrorBufferloop	;then repeat
		ret				;otherwise finish
;------------------------------------------------------------------------------------------
;CheckCRCIn:
;		kiss	USBBUFPTRY
;		kiss	ByteCount
;		ldi	USBBUFPTRY,InputBuffercompare
;		rcall	CheckCRC
;		pope	ByteCount
;		pope	USBBUFPTRY
;		lip
;------------------------------------------------------------------------------------------
AddCRCOut:
		push	USBBufptrY
		push	ByteCount
		ldi	USBBufptrY,OutputBufferBegin

⌨️ 快捷键说明

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