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

📄 usb_ch9.asm

📁 基于PIC16C745单片机的一个USB样例程序
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	pagesel	wrongstate
	btfss	STATUS,Z
	goto	wrongstate

get_EP2_status
	bcf 	STATUS,C
	bsf 	STATUS,RP0
	btfsc	UEP2,EP_STALL
	bsf 	STATUS,C
	pagesel	build_status_buffer
	goto	build_status_buffer

get_EP1_status
	bcf 	STATUS,C
	bsf 	STATUS,RP0
	btfsc	UEP1,EP_STALL
	bsf 	STATUS,C
 
build_status_buffer
	movf	BD0IAL,w	; get address of buffer
	movwf	FSR
	clrf	INDF		; clear byte 0 in buffer
	rlf 	INDF,f		; rotate in carry bit (EP_stall bit)
	incf	FSR,f		; bump pointer
	clrf	INDF		; clear byte

	movlw	0x02
	movwf	BD0IBC		; set byte count to 2
	movlw	0xC8
	movwf	BD0IST		; Data 1 packet, set owns bit
	return

; *********************************************************************
; The low order byte of wValue now has the new device address as assigned
; from the host.  Save it in the UADDR, transition to the ADDRESSED state
; and clear the current configuration.
; This assumes the SIE has already sent the status stage of the transaction
; as implied by Figure 3-35 of the DOS (Rev A-7)
; ******************************************************************
Set_Address  ; starts in bank 2
	movf	BufferData+wValue,w ; new address in low order byte of wValue
	movwf	USB_address_pending
	pagesel	wrongstate
	btfsc	USB_address_pending, 7
	goto	wrongstate
	pagesel	Send_0Len_pkt
	call	Send_0Len_pkt	; send zero length packet
	movlw	SET_ADDRESS
	movwf	USB_dev_req	; currently processing a get descriptor request
	return

finish_set_address  ; starts in bank 2
	clrf	USB_dev_req	; no request pending
	clrf	USB_Curr_Config	; make sure current configuration is 0
	movf	USB_address_pending,w
	bsf 	STATUS, RP0
	movwf	UADDR		; set the device address
	pagesel	endfinishsetaddr
	btfsc	STATUS,Z	; was address 0?
	goto	endfinishsetaddr ; yes: don't change state

	movlw	ADDRESS_STATE	; non-zero: transition to addressed state
	movwf	USWSTAT		; transition to addressed state
#ifdef SHOW_ENUM_STATUS
	banksel	PORTB
	bsf 	PORTB,2		; set bit 2 to indicate Addressed state
	banksel	USWSTAT		; not necessary, Send_0LenPkt resets bank bits
#endif

endfinishsetaddr
	return

; ******************************************************************
; only feature valid for device feature is Device Remote wakeup
; ******************************************************************
Clear_Device_Feature  ; starts in bank2
	movf	BufferData+wValue,w
	xorlw	0x01		; was it a Device Remote wakeup? If not, return STALL,
	pagesel	wrongstate
	btfss	STATUS,Z	; since we only implement this feature on this device.
	goto	wrongstate

right_state_clear_feature
	bcf	USB_status_device,1 ; set device remote wakeup
	pagesel	Send_0Len_pkt
	call	Send_0Len_pkt
	return

; ******************************************************************
; Only endpoint feature is Endpoint halt.
; ******************************************************************
Clear_Endpoint_Feature  ; starts in bank 2
	movf	BufferData+wValue, w
	pagesel	wrongstate
	btfss	STATUS, Z	; only valid feature is 0 (Remote Wakeup)
	goto	wrongstate
	movf	BufferData+(wValue+1), w
	btfss	STATUS, Z
	goto	wrongstate

	bsf 	STATUS, RP0	; bank3
	movlw	0x03		; if ((USWSTAT & 0x03) == ADDRESS_STATE)
	andwf	USWSTAT, w			
	xorlw	ADDRESS_STATE
	pagesel clear_endpoint_feature2
	btfss	STATUS, Z
	goto	clear_endpoint_feature2
	bcf 	STATUS, RP0	; bank2
	movlw	0x0F		; if ((Bufferdata+wIndex & 0x07) = 0)
	andwf	BufferData+wIndex, w
	btfss 	STATUS, Z
	goto	clear_endpoint_feature2	
	bsf 	STATUS, RP0	; bank 3
	bcf 	UEP0, 0			
	pagesel	Send_0Len_pkt
	call	Send_0Len_pkt
	return

clear_endpoint_feature2
	bsf 	STATUS, RP0
	movlw	0x03		; if ((USWSTAT & 0X03) == CONFIG_STATE)
	andwf	USWSTAT, w
	xorlw	CONFIG_STATE
	pagesel wrongstate
	btfss	STATUS, Z
	goto	wrongstate
	bcf 	STATUS, RP0	; bank2
	movlw	0x0F
	andwf	BufferData+wIndex, w ; if (BufferData+wIndex < 3)
	sublw	2
	pagesel wrongstate
	btfss	STATUS, C	
	goto	wrongstate
	bsf 	STATUS, IRP
	movlw	0x0F
	andwf	BufferData+wIndex,w
	bsf 	STATUS, RP0 	; bank3
	addlw	UEP0&0xFF
	movwf	FSR
	bcf 	INDF, 0
	pagesel	Send_0Len_pkt
	call	Send_0Len_pkt
	return

Clear_Interface_Feature ; starts in bank2
	pagesel	wrongstate
	goto	wrongstate

; ******************************************************************
; only feature valid for device feature is Device Remote wakeup
; ******************************************************************
Set_Device_Feature  ; starts in bank 2
	movf	BufferData+wValue,w ; get high order byte of wValue
	xorlw	0x01		; was it a Device Remote wakeup?
	pagesel	wrongstate
	btfss	STATUS,Z
	goto	wrongstate	; request error
	bsf 	USB_status_device,1 ; set device remote wakeup
	pagesel	Send_0Len_pkt
	call	Send_0Len_pkt
	return

; ******************************************************************
; Only endpoint feature is Endpoint halt.
; ******************************************************************
Set_Endpoint_Feature  ; starts in bank 2
	movf	BufferData+wValue, w
	pagesel	wrongstate
	btfss	STATUS, Z	; only valid feature is 0 (Remote Wakeup)
	goto	wrongstate
	movf	BufferData+(wValue+1), w
	btfss	STATUS, Z
	goto	wrongstate

	bsf 	STATUS, RP0	; bank3
	movlw	0x03		; if ((USWSTAT & 0x03) == ADDRESS_STATE)
	andwf	USWSTAT, w			
	xorlw	ADDRESS_STATE
	pagesel set_endpoint_feature2
	btfss	STATUS, Z
	goto	set_endpoint_feature2
	bcf 	STATUS, RP0	; bank2
	movlw	0x0F		; if ((Bufferdata+wIndex & 0x07) = 0)
	andwf	BufferData+wIndex, w
	btfss 	STATUS, Z
	goto	set_endpoint_feature2	
	bsf 	STATUS, RP0	; bank 3
	bsf 	UEP0, 0			
	pagesel	Send_0Len_pkt
	call	Send_0Len_pkt
	return

set_endpoint_feature2
	bsf 	STATUS, RP0
	movlw	0x03		; if ((USWSTAT & 0X03) == CONFIG_STATE)
	andwf	USWSTAT, w
	xorlw	CONFIG_STATE
	pagesel wrongstate
	btfss	STATUS, Z
	goto	wrongstate
	bcf 	STATUS, RP0	; bank2
	movlw	0x0F
	andwf	BufferData+wIndex, w ; if (BufferData+wIndex < 3)
	sublw	2
	pagesel wrongstate
	btfss	STATUS, C	
	goto	wrongstate
	bsf 	STATUS, IRP
	movlw	0x0F
	andwf	BufferData+wIndex,w
	bsf 	STATUS, RP0 	; bank3
	addlw	UEP0&0xFF
	movwf	FSR
	bsf 	INDF, 0
	pagesel	Send_0Len_pkt
	call	Send_0Len_pkt
	return

Set_Interface_Feature; starts in bank 2
	pagesel	wrongstate
	goto	wrongstate	; invalid request

; ********************************************************************
; Get configuration returns a single byte Data1 packet indicating the 
; configuration in use.
; Default State- undefined
; Addressed State  - returns 0
; Configured state - returns current configured state.
; ******************************************************************
Get_Configuration  ; starts in bank 2
	bsf 	STATUS, RP0
	movf	low BD0IAL,w	; get address of buffer
	movwf	FSR
	bcf 	STATUS, RP0
	bsf 	STATUS,IRP	; indirectly to banks 2-3
	movf	USB_Curr_Config,w
	movwf	INDF		; write byte to buffer
	bsf 	STATUS, RP0
	movlw	0x01
	movwf	BD0IBC		; set byte count to 1
	movlw	0xc8		; DATA1 packet, DTS enabled
	movwf	BD0IST		; give buffer back to SIE
	return

; ******************************************************************
; Set configuration uses the configuration selected by the low order
; byte of wValue.  Sets up a zero length data1 packet as a reply.
; ******************************************************************
Set_Configuration  ; starts in bank 2
; All we do is set a meaningless number.  This'll 
; need more code here to actually give meaning to each configuration
; we choose.
	movf	BufferData+wValue,w ; is it a valid configuration?
	sublw	NUM_CONFIGURATIONS
	pagesel	wrongstate
	btfss	STATUS,C	; if config <= num configs, request appears valid
	goto	wrongstate

	movf	BufferData+wValue,w
	movwf	USB_Curr_Config	; store new state in configuration

	pagesel	AckSetConfigCmd
	btfsc	STATUS,Z	; was the configuration zero?
	goto	AckSetConfigCmd	; yes: stay in the addressed state

	bsf 	STATUS, RP0 	; bank 3
	movlw	CONFIG_STATE	; No: transition to configured
	movwf	USWSTAT		; save new state.
#ifdef SHOW_ENUM_STATUS
	banksel	PORTB
	bsf 	PORTB,3		; set bit 3 to show configured
#endif

AckSetConfigCmd
	pagesel	Send_0Len_pkt
	call	Send_0Len_pkt

; These configure the EP1 and EP2  endpoints.  Change these as necessary
; for your application.
	banksel	BD1OAL
	movlw	USB_Buffer+0x10	; Endpoint 1 OUT gets a buffer
	movwf	BD1OAL		; set up buffer address
	movlw	8
	movwf	BD1OBC		; set byte count
	movlw	0x88		; set own bit of EP1 (SIE can write)
	movwf	BD1OST

	movlw	8	
	movwf	BD1IBC		; set byte count
	movlw	USB_Buffer+0x18	; Endpoint 1 IN gets a buffer
	movwf	BD1IAL		; set up buffer address
	movlw	0x48		; set own bit of EP1 (PIC can write)
	movwf	BD1IST

	movlw	USB_Buffer+0x20	; Endpoint 2 OUT gets a buffer
	movwf	BD2OAL		; set up buffer address
	movlw	8
	movwf	BD2OBC		; set byte count
	movlw	0x88		; set own bit of EP2 (SIE can write)
	movwf	BD2OST

	movlw	8	
	movwf	BD2IBC		; set byte count
	movlw	USB_Buffer+0x20	; EP1 In and EP2 In share a buffer
	movwf	BD2IAL		; set up buffer address
	movlw	0x48		; set own bit of EP2 (PIC can write)
	movwf	BD2IST
; Set up the Endpoint Control Registers.  The following patterns are defined
; ENDPT_DISABLED - endpoint not used
; ENDPT_IN_ONLY  - endpoint supports IN transactions only
; ENDPT_OUT_ONLY - endpoint supports OUT transactions only
; ENDPT_CONTROL - Supports IN, OUT and CONTROL transactions - Only use with EP0
; ENDPT_NON_CONTROL - Supports both IN and OUT transactions
	movlw	ENDPT_NON_CONTROL
	movwf	UEP1		; enable EP's 1 and 2 for In and Outs...
	movlw	ENDPT_NON_CONTROL
	movwf	UEP2

;pagesel SetConfiguration; call SetConfiguration etc. after configuration changed
;movfUSB_Curr_Config,w; if you have multiple configurations
;callSetConfiguration
;pagesel Set_Configuration
	return


; ********************************************************************
; Get interface returns a single byte Data1 packet indicating the 
; interface in use.
; Default State- undefined
; Addressed State  - Not valid - returns stall
; Configured state - returns current configured state.
; ******************************************************************
Get_Interface  ; STARTS IN BANK 2
	bsf 	STATUS, RP0
	movf	USWSTAT,w	; Only valid in the configured state
	xorlw	CONFIG_STATE
	pagesel	wrongstate
	btfss	STATUS, Z
	goto	wrongstate

	bcf 	STATUS, RP0
	movf	BufferData+wIndex,w ; if Interface < NUM_INTERFACES
	sublw	(NUM_INTERFACES-1)
	pagesel	wrongstate
	btfss	STATUS, C
	goto	wrongstate

	movf	BufferData+wIndex,w ; get interface ID
	addlw	low USB_Interface
	movwf	FSR
	bsf 	STATUS,IRP
	movf	INDF,w
	movwf	temp		; store in temp register

	bsf 	STATUS,RP0	; bank 3
	movf	BD0IAL,w	; get address of buffer
	movwf	FSR
	movf	temp,w		; load temp
	movwf	INDF		; write byte to buffer

	movlw	0x01
	movwf	BD0IBC		; set byte count to 1
	movlw	0xc8		; DATA1 packet, DTS enabled
	movwf	BD0IST		; give buffer back to SIE
	return

; ******************************************************************
; Set configuration uses the configuration selected by the low order
; byte of wValue.  Sets up a zero length data1 packet as a reply.
; ******************************************************************
Set_Interface  ; start bank 2
	bsf 	STATUS, RP0	; bank3
	movf	USWSTAT,w	; test to make sure we're configured
	bcf 	STATUS,RP0	; bank2
	andlw	0x03
	xorlw	CONFIG_STATE
	pagesel	wrongstate
	btfss	STATUS,Z
	goto	wrongstate

	movf	BufferData+wIndex,w ; get interface
	addlw	USB_Interface	; add offset to array
	movwf	FSR
	bsf 	STATUS,IRP	; indirectly to banks 2-3
	movf	BufferData+wValue,w ; get alternate interface
	movwf	INDF		; store in array
; All we do is set a meaningless number.  This'll 
; need more code here to actually give meaning to each configuration
; we choose.
	pagesel	Send_0Len_pkt
	call	Send_0Len_pkt
	return

; *********************************************************************
; copies the next chunk of buffer descriptor over to the EP0 In buffer.
; Inputs:
;	EP0_start - points to first byte of configuration table to transfer
;	EP0_end - total number of bytes to transfer
;	EP0_maxLength - maximum number of bytes that can be sent during
;	a single transfer
;
; toggles the data0/1 bit before setting the UOWN bit over to SIE.
; ******************************************************************
copy_descriptor_to_EP0
	global	copy_descriptor_to_EP0
	banksel	BD0IAL
	bankisel BD0IAL
	movf	BD0IAL,w	; get buffer address
	movwf	FSR		 
	banksel bufindex
	clrf	bufindex	; bufindex = 0
gdd_loop
	movf	bufindex,w	; while (bufindex < EP0_maxLength)
	subwf	EP0_maxLength,w	;  && (EP0_start < EP0_end)
	pagesel	end_gdd_loop
	btfsc	STATUS,Z
	goto	end_gdd_loop

	pagesel	gdd_copy_loop
	decfsz	EP0_end, f
	goto	gdd_copy_loop
	pagesel	end_gdd_loop_short_packet
	goto	end_gdd_loop_short_packet

gdd_copy_loop
	pagesel	Descriptions
	call	Descriptions
	movwf	INDF

	incf	bufindex,f
	incf	FSR,f
	pagesel	gdd_loop
	incfsz	EP0_start,f
	goto	gdd_loop
	incf	EP0_start+1,f
	goto	gdd_loop

end_gdd_loop_short_packet
	clrf	USB_dev_req	; we're sending a short packet, clear the device request
end_gdd_loop
	movf	bufindex,w	; write number of bytes to byte count
	bsf 	STATUS,RP0	; Bank 3
	movwf	BD0IBC
	movlw	(0x01<<DATA01)	; toggle data0/1 bit
	xorwf	BD0IST,w
	andlw	(0x01<<DATA01)	; clear PID bits
	iorlw	0x88		; set OWN and DTS bits
	movwf	BD0IST		; write the whole mess back
	pagesel	copy_descriptor_to_EP0
	return
; *********************************************************************
; SetConfiguration
; 
; This function is called when the host issues a Set Configuration 
; command.  The housekeeping within USB is handled within the CH9 commands
; This function should be filled in to give meaning to the command within
; the application.
;
; SetConfiguration is called from within the ISR so this function should
; be kept as short as possible.
; *********************************************************************
SetConfiguration
	global	SetConfiguration
	return

; *********************************************************************
; Vendor Specific calls
; control is transferred here when bmRequestType bits 5 & 6 = 10 indicating
; the request is a vendor specific request.  This function then would 
; interpret the bRequest field to determine what action is required.
; The end of each vendor specific command should be terminated with a 
; return.  
; *********************************************************************
CheckVendor
	global	CheckVendor
	return	; *** remove this line and uncomment out the remainder

	end

⌨️ 快捷键说明

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