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

📄 usbtiny2313.asm

📁 AVR的USB开发源代码 USB-RS232转换
💻 ASM
📖 第 1 页 / 共 5 页
字号:
		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		;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
		rcall	CheckCRC
		com	temp0			;negation of CRC
		com	temp1
		st	Y+,temp1		;save CRC to the end of buffer (at first MSB)
		st	Y,temp0			;save CRC to the end of buffer (then LSB)
		dec	USBBufptrY		;pointer to CRC position
		ldi	ByteCount,2		;reverse bits order in 2 bytes CRC
		rcall	MirrorBufferBytes	;reverse bits order in CRC (transmiting CRC - MSB first)
		pop	ByteCount
		pop	USBBufptrY
		ret
;------------------------------------------------------------------------------------------
CheckCRC:	;input: USBBufptrY = begin of message	,ByteCount = length of message
		add	ByteCount,USBBufptrY	;ByteCount points to the end of message
		inc	USBBufptrY		;set the pointer to message start - omit SOP
		ld	temp0,Y+		;load PID to temp0
						;and set the pointer to start of message - omit also PID
		cpi	temp0,DATA0PID		;if is DATA0 field
		breq	ComputeDATACRC		;compute CRC16
		cpi	temp0,DATA1PID		;if is DATA1 field
		brne	CRC16End		;if no then finish
ComputeDATACRC:
		ser	temp0			;initialization of remaider LSB to 0xff
		ser	temp1			;initialization of remaider MSB to 0xff
CRC16Loop:
		ld	temp2,Y+		;load message to temp2 and increment pointer to buffer
		ldi	temp3,8			;bits counter in byte - temp3
CRC16LoopByte:
		bst	temp1,7			;to T save MSB of remainder (remainder is only 16 bits - 8 bit of higher byte)
		bld	bitcount,0		;to bitcount LSB save T - of MSB remainder
		eor	bitcount,temp2		;XOR of bit message and bit remainder - in LSB bitcount
		rol	temp0			;shift remainder to the left - low byte (two bytes - through carry)
		rol	temp1			;shift remainder to the left - high byte (two bytes - through carry)
		cbr	temp0,1			;znuluj LSB remains
		lsr	temp2			;shift message to right
		ror	bitcount		;result of XOR bits from LSB to carry
		brcc	CRC16NoXOR		;if is XOR bitmessage and MSB of remainder = 0 , then no XOR
		ldi	bitcount,CRC16poly>>8	;to bitcount CRC polynomial - high byte
		eor	temp1,bitcount		;and make XOR from remains and CRC polynomial - high byte
		ldi	bitcount,LOW(CRC16poly)	;to bitcount CRC polynomial - low byte
		eor	temp0,bitcount		;and make XOR of remainder and CRC polynomial - low byte
CRC16NoXOR:
		dec	temp3			;were already all bits in byte
		brne	CRC16LoopByte		;unless, then go to next bit
		cp	USBBufptrY,ByteCount	;was already end-of-message
		brne	CRC16Loop		;unless then repeat

⌨️ 快捷键说明

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