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

📄 usbtiny2313.asm

📁 AVR的USB开发源代码 USB-RS232转换
💻 ASM
📖 第 1 页 / 共 5 页
字号:
CRC16End:
		ret				;otherwise finish (in temp0 and temp1 is result)
;------------------------------------------------------------------------------------------
LoadDescriptorFromROM:
		lpm				;load from ROM position pointer to R0
		st	Y+,R0			;R0 save to buffer and increment buffer
		adiw	ZH:ZL,1			;increment index to ROM
		dec	ByteCount		;till are not all bytes
		brne	LoadDescriptorFromROM	;then load next
		rjmp	EndFromRAMROM		;otherwise finish
;------------------------------------------------------------------------------------------
LoadDescriptorFromROMZeroInsert:
		lpm				;load from ROM position pointer to R0
		st	Y+,R0			;R0 save to buffer and increment buffer

		bst	RAMread,3		;if bit 3 is one - don't insert zero
		brtc	InsertingZero		;otherwise zero will be inserted
		adiw	ZH:ZL,1			;increment index to ROM
		lpm				;load from ROM position pointer to R0
		st	Y+,R0			;R0 save to buffer and increment buffer
		clt				;and clear
		bld	RAMread,3		;the third bit in RAMread - for to the next zero insertion will be made
		rjmp	InsertingZeroEnd	;and continue
InsertingZero:
		clr	R0			;for insertion of zero
		st	Y+,R0			;zero save to buffer and increment buffer
InsertingZeroEnd:
		adiw	ZH:ZL,1			;increment index to ROM
		subi	ByteCount,2		;till are not all bytes
		brne	LoadDescriptorFromROMZeroInsert	;then load next
		rjmp	EndFromRAMROM		;otherwise finish
;------------------------------------------------------------------------------------------
LoadDescriptorFromSRAM:
		ld	R0,Z			;load from position RAM pointer to R0
		st	Y+,R0			;R0 save to buffer and increment buffer
		inc	ZL			;increment index to RAM
		dec	ByteCount		;till are not all bytes
		brne	LoadDescriptorFromSRAM  ;then load next
		rjmp	EndFromRAMROM		;otherwise finish
;------------------------------------------------------------------------------------------
LoadDescriptorFromEEPROM:
		out	EEAR,ZL			;set the address EEPROM
		sbi	EECR,EERE		;read EEPROM to register EEDR
		in	R0,EEDR			;load from EEDR to R0
		st	Y+,R0			;R0 save to buffer and increment buffer
		inc	ZL			;increment index to EEPROM
		dec	ByteCount		;till are not all bytes
		brne	LoadDescriptorFromEEPROM;then load next
		rjmp	EndFromRAMROM		;otherwise finish
;------------------------------------------------------------------------------------------
LoadXXXDescriptor:
		ldi	temp0,SOPbyte			;SOP byte
		sts	OutputBufferBegin,temp0		;to begin of tramsmiting buffer store SOP
		ldi	ByteCount,8			;8 byte store
		ldi	USBBufptrY,OutputBufferBegin+2	;to transmitting buffer

		and	RAMread,RAMread			;if will be reading from RAM or ROM or EEPROM
		brne	FromRAMorEEPROM			;0=ROM,1=RAM,2=EEPROM,4=ROM with zero insertion (string)
FromROM:
		rjmp	LoadDescriptorFromROM		;load descriptor from ROM
FromRAMorEEPROM:
		sbrc	RAMread,2			;if RAMREAD=4
		rjmp	LoadDescriptorFromROMZeroInsert	;read from ROM with zero insertion
		sbrc	RAMread,0			;if RAMREAD=1
		rjmp	LoadDescriptorFromSRAM		;load data from SRAM
		rjmp	LoadDescriptorFromEEPROM	;otherwise read from EEPROM
EndFromRAMROM:
		sbrc	RAMread,7			;if is most significant bit in variable RAMread=1
		clr	RAMread				;clear RAMread
		rcall	ToggleDATAPID			;change DATAPID
		ldi	USBBufptrY,OutputBufferBegin+1	;to transmitting buffer - position of DATA PID
		ret
;------------------------------------------------------------------------------------------
PrepareUSBOutAnswer:	;prepare answer to buffer
		rcall	PrepareUSBAnswer		;prepare answer to buffer
MakeOutBitStuff:
		inc	BitStuffInOut			;transmitting buffer - insertion of bitstuff bits
		ldi	USBBufptrY,OutputBufferBegin	;to transmitting buffer
		rcall	BitStuff
		mov	OutputBufferLength,ByteCount	;length of answer store for transmiting
		clr	BitStuffInOut			;receiving buffer - deletion of bitstuff bits
		ret
;------------------------------------------------------------------------------------------
PrepareUSBAnswer:	;prepare answer to buffer
		clr	RAMread				;zero to RAMread variable - reading from ROM
		lds	temp0,InputBufferBegin+2	;bmRequestType to temp0
		lds	temp1,InputBufferBegin+3	;bRequest to temp1
		cbr	temp0,0b10011111		;if is 5 and 6 bit zero
		brne	VendorRequest			;then this isn't  Vendor Request
		rjmp	StandardRequest			;but this is standard Request
;--------------------------
DoSetInfraBufferEmpty:
		rjmp	OneZeroAnswer			;confirm receiving with one zero
;--------------------------
DoSetRS232Baud:
		lds	temp0,InputBufferBegin+4	;first parameter - RS232 baudrate value
		out	UBRRL,temp0			;set UART speed
		rjmp	OneZeroAnswer			;confirm receiving with one zero
;--------------------------
DoGetRS232Baud:
		in	R0,UBRRL			;return UART speed in R0
		rjmp	DoGetIn				;and finish
;--------------------------
DoRS232Send:
		lds	temp0,InputBufferBegin+4	;first parameter - value transmitted to RS232
		out	UDR,temp0			;transmit data to UART
WaitForRS232Send:
		sbis	UCSRB,TXEN			;if disabled UART transmitter
		rjmp	OneZeroAnswer			;then finish - protection because loop lock in AT90S2323/2343
		sbis	UCSRA,TXC			;wait for transmition finish
		rjmp	WaitForRS232Send
		rjmp	OneZeroAnswer			;acknowledge reception with single zero
;--------------------------
DoRS232Read:
		rjmp	TwoZeroAnswer			;only acknowledge reception with two zero
;--------------------------
VendorRequest:
		clr	ZH				;for reading from RAM or EEPROM

		cpi	temp1,1				;
		breq	DoSetInfraBufferEmpty		;restart infra receiving (if it was stopped by reading from RAM)

		cpi	temp1,2				;
		breq	DoGetInfraCode			;transmit received infra code (if it is in buffer)

		cpi	temp1,3				;
		breq	DoSetDataPortDirection		;set flow direction of datal bits
		cpi	temp1,4				;
		breq	DoGetDataPortDirection		;detect of flow direction of data bits

		cpi	temp1,5				;
		breq	DoSetOutDataPort		;set data bits (if they are inputs, then pull-ups)
		cpi	temp1,6				;
		breq	DoGetOutDataPort		;detect settings of data out bits (if they are input, then pull-ups)

		cpi	temp1,7				;
		breq	DoGetInDataPort			;return value of input data port

		cpi	temp1,8				;
		breq	DoEEPROMRead			;return contents of EEPROM from given address
		cpi	temp1,9				;
		breq	DoEEPROMWrite			;write to EEPROM to given address given data

		cpi	temp1,10			;
		breq	DoRS232Send			;transmit byte to serial line
		cpi	temp1,11			;
		breq	DoRS232Read			;returns received byte from serial line(if some was received)

		cpi	temp1,12			;
		breq	DoSetRS232Baud			;set line speed of of serial line
		cpi	temp1,13			;
		breq	DoGetRS232Baud			;return line speed of serial line
		cpi	temp1,14			;
		breq	DoGetRS232Buffer		;return RS232 buffer

		cpi	temp1,USER_FNC_NUMBER+0		;
		breq	DoUserFunction0			;execute of user function0
		cpi	temp1,USER_FNC_NUMBER+1		;
		breq	DoUserFunction1			;execute of user function1
		cpi	temp1,USER_FNC_NUMBER+2		;
		breq	DoUserFunction2			;execute of user function2

		rjmp	ZeroDATA1Answer			;if that it was something unknown, then prepare zero answer

;----------------------------- USER FUNCTIONS --------------------------------------

;------------------------------TEMPLATE OF YOUR FUNCTION----------------------------
;------------------ BEGIN: This is template how to write own function --------------

;free of use are registers:
	;temp0,temp1,temp2,temp3,ACC,ZH,ZL
	;registers are destroyed after execution (use push/pop to save content)

;at the end of routine you must correctly set registers:
	;RAMread - 0=reading from ROM, 1=reading from RAM, 2=reading from EEPROM
	;temp0 - number of transmitted data bytes
	;ZH,ZL - pointer to buffer of transmitted data (pointer to ROM/RAM/EEPROM)

;to transmit data (preparing data to buffer) :
	;to transmit data you must jump to "ComposeEndXXXDescriptor"
	;to transmit one zero byte you can jump to "OneZeroAnswer"  (commonly used as confirmation of correct processing)
	;to transmit two zero byte you can jump to "TwoZeroAnswer"  (commonly used as confirmation of error in processing)

DoUserFunctionX:
DoUserFunction0:  ;send byte(s) of RAM starting at position given by first parameter in function
		lds	temp0,InputBufferBegin+4	;first parameter Lo into temp0
		;lds	temp1,InputBufferBegin+5	;first  parameter Hi into temp1
		;lds	temp2,InputBufferBegin+6	;second parameter Lo into temp2
		;lds	temp3,InputBufferBegin+7	;second parameter Hi into temp3
		;lds	ACC,InputBufferBegin+8		;number of requested bytes from USB host (computer) into ACC

		;Here add your own code:
		;-------------------------------------------------------------------
		nop					;example of code - nothing to do
		nop
		nop
		nop
		nop
		;-------------------------------------------------------------------

		mov	ZL,temp0			;will be sending value of RAM - from address stored in temp0 (first parameter Lo of function)
		inc	RAMread				;RAMread=1 - cita sa z RAM-ky
		ldi	temp0,RAMEND+1			;send max number of bytes - whole RAM
		rjmp	ComposeEndXXXDescriptor		;a prepare data
DoUserFunction1:
		rjmp	OneZeroAnswer			;only confirm receiving by one zero byte answer
DoUserFunction2:
		rjmp	TwoZeroAnswer			;only confirm receiving by two zero bytes answer
;------------------ END: This is template how to write own function ----------------

;----------------------------- USER FUNCTIONS --------------------------------------

DoGetInfraCode:
		rjmp	OneZeroAnswer			;acknowledge reception with single zero

DoEEPROMRead:
		lds	ZL,InputBufferBegin+4		;first parameter - offset in EEPROM
		ldi	temp0,2
		mov	RAMread,temp0			;RAMREAD=2 - reading from EEPROM
		ldi	temp0,E2END+1			;number my byte answers to temp0 - entire length of EEPROM
		rjmp	ComposeEndXXXDescriptor		;otherwise prepare data
DoEEPROMWrite:
		lds	ZL,InputBufferBegin+4		;first parameter - offset in EEPROM (address)
		lds	R0,InputBufferBegin+6		;second parameter - data to store to EEPROM (data)
		rjmp	EEPROMWrite			;write to EEPROM and finish this command
DoSetDataPortDirection:
		lds	ACC,InputBufferBegin+4		;first parameter - direction of data bits
		rcall	SetDataPortDirection
		rjmp	OneZeroAnswer			;acknowledge reception with single zero
DoGetDataPortDirection:
		rcall	GetDataPortDirection
		rjmp	DoGetIn

DoSetOutDataPort:
		lds	ACC,InputBufferBegin+4		;first parameter - value of data bits
		rcall	SetOutDataPort
		rjmp	OneZeroAnswer			;acknowledge reception with single zero
DoGetOutDataPort:
		rcall	GetOutDataPort
		rjmp	DoGetIn

DoGetInDataPort:
		rcall	GetInDataPort
 DoGetIn:
		ldi	ZL,0				;sending value in R0
		ldi	temp0,0x81			;RAMread=1 - reading from RAM
		mov	RAMread,temp0			;(highest bit set to 1 - to zero RAMread immediatelly)
		ldi	temp0,1				;send only single byte
		rjmp	ComposeEndXXXDescriptor		;and prepare data

DoGetRS232Buffer:
		mov	temp0,RS232BufferFull		;obtain buffer length of RS232 code
		cpi	temp0,0				;if is RS232 Buffer empty
		breq	OneZeroAnswer			;then nothing send and acknowledge reception with single zero

		lds	ACC,InputBufferBegin+8		;number of requiring bytes to ACC
		inc	temp0				;number of possible bytes (plus word of buffer length)
		cp	ACC,temp0			;if no requested more that I can send
		brcc	NoShortGetRS232Buffer		;transmit as many as requested
		mov	temp0,ACC
NoShortGetRS232Buffer:
		dec	temp0				;substract word length
		lds	temp1,RS232BufferBegin+1	;obtain index of reading of buffer of RS232 code
		add	temp1,temp0			;obtain where is end
		cpi	temp1,RS232BufferBegin+MAXRS232LENGTH+1	;if it would overflow
		brcs	ReadNoOverflow
		subi	temp1,RS232BufferBegin+MAXRS232LENGTH+1	;caculate how many not transfered
		sub	temp0,temp1			;and with this short length of reading
		ldi	temp1,RS232BufferBegin+4	;and start from zero
ReadNoOverflow:
		lds	ZL,RS232BufferBegin+1		;obtain index of reading of buffer of RS232 code: 2.byte of header (code length + reading + writing + reserve)
		sts	RS232BufferBegin+1,temp1	;write new index of reading of buffer of RS232 code : 2.byte of header (code length + reading + writing + reserve)
		dec	ZL				;space for length data - transmitted as first word

		sub	RS232BufferFull,temp0		;decrement buffer length
		st	Z,RS232BufferFull		;save real length to packet
		inc	temp0				;and about this word increment number of transmited bytes (buffer length)
		inc	RAMread				;RAMread=1 reading from RAM
		rjmp	ComposeEndXXXDescriptor		;and prepare data
;----------------------------- END USER FUNCTIONS ----------------------------------

OneZeroAnswer:		;send single zero
		ldi	temp0,1				;number of my bytes answers to temp0
		rjmp	ComposeGET_STATUS2

StandardRequest:
		cpi	temp1,GET_STATUS		;
		breq	ComposeGET_STATUS		;

		cpi	temp1,CLEAR_FEATURE		;
		breq	ComposeCLEAR_FEATURE		;

		cpi	temp1,SET_FEATURE		;
		breq	ComposeSET_FEATURE		;

		cpi	temp1,SET_ADDRESS		;if to set address
		breq	ComposeSET_ADDRESS		;set the address

		cpi	temp1,GET_DESCRIPTOR		;if requested descriptor
		breq	ComposeGET_DESCRIPTOR		;generate it

		cpi	temp1,SET_DESCRIPTOR		;

⌨️ 快捷键说明

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