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

📄 usb_ch9.asm

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

	movf	BufferData+bmRequestType,w
	andlw	0x60		; mask off type bits
	xorlw	0x20		; test for class specific
	pagesel	ClassSpecificRequest
	btfsc	STATUS,Z	; was it a standard request?
	goto	ClassSpecificRequest ; nope, see if it was a class specific request

CheckForVendorRequest
	movf	BufferData+bmRequestType,w
	andlw	0x60		; mask off type bits
	xorlw	0x40		; test for vendor specific
	pagesel	wrongstate
	btfss	STATUS,Z	; was it a standard request?
	goto	wrongstate
	pagesel	CheckVendor
	goto	CheckVendor	; nope, see if it was a vendor specific
	return

; now test bRequest to see what the request was.

CheckForStandardRequest
; bmRequestType told us it was a Host to Device transfer.  Now look at
; the specifics to see what's up
HostToDevice  ; starts in bank 2
	movf	BufferData+bRequest,w ; what was our request
	xorlw	CLEAR_FEATURE
	pagesel	Clear_Device_Feature
	btfsc	STATUS,Z
	goto	Clear_Device_Feature

	movf	BufferData+bRequest,w ; was our request Set Address
	xorlw	SET_ADDRESS
	pagesel	Set_Address
	btfsc	STATUS,Z
	goto	Set_Address

	movf	BufferData+bRequest,w ; was our request Set Configuration
	xorlw	SET_CONFIGURATION
	pagesel	Set_Configuration
	btfsc	STATUS,Z
	goto	Set_Configuration
	
	movf	BufferData+bRequest,w ; was our request Set Feature
	xorlw	SET_FEATURE
	pagesel	Set_Device_Feature
	btfsc	STATUS,Z
	goto	Set_Device_Feature

	pagesel	wrongstate
	goto	wrongstate

HostToInterface  ; starts in bank 2
	movf	BufferData+bRequest,w ; what was our request
	xorlw	CLEAR_FEATURE 
	pagesel	Clear_Interface_Feature
	btfsc	STATUS,Z
	goto	Clear_Interface_Feature

	movf	BufferData+bRequest,w ; was our request Set Interface
	xorlw	SET_INTERFACE
	pagesel	Set_Interface
	btfsc	STATUS,Z
	goto	Set_Interface

	movf	BufferData+bRequest,w ; was our request Set Feature
	xorlw	SET_FEATURE
	pagesel	Set_Interface_Feature
	btfsc	STATUS,Z
	goto	Set_Interface_Feature

	pagesel	wrongstate
	goto	wrongstate

HostToEndpoint  ; starts in bank2
	movf	BufferData+bRequest,w ; what was our request
	xorlw	CLEAR_FEATURE
	pagesel	Clear_Endpoint_Feature
	btfsc	STATUS,Z
	goto	Clear_Endpoint_Feature

	movf	BufferData+bRequest,w ; was our request Set Feature
	xorlw	SET_FEATURE
	pagesel	Set_Endpoint_Feature
	btfsc	STATUS,Z
	goto	Set_Endpoint_Feature

DeviceToHost  ; starts in bank2
	movf	BufferData+bRequest,w ; what was our request
	xorlw	GET_CONFIGURATION
	pagesel	Get_Configuration
	btfsc	STATUS,Z
	goto	Get_Configuration

	movf	BufferData+bRequest,w ; was our request Get Decriptor?
	xorlw	GET_DESCRIPTOR
	pagesel	Get_Descriptor
	btfsc	STATUS,Z
	goto	Get_Descriptor

	movf	BufferData+bRequest,w ; was our request Get Status?
	xorlw	GET_STATUS
	pagesel	Get_Device_Status
	btfsc	STATUS,Z
	goto	Get_Device_Status

InterfaceToHost  ; starts in bank2
	movf	BufferData+bRequest,w ; was our request Get Interface?
	xorlw	GET_INTERFACE
	pagesel	Get_Interface
	btfsc	STATUS,Z
	goto	Get_Interface

	movf	BufferData+bRequest,w ; was our request Get Status?
	xorlw	GET_STATUS
	pagesel	Get_Interface_Status
	btfsc	STATUS,Z
	goto	Get_Interface_Status

	movf	BufferData+bRequest,w ; was our request Get Decriptor?
	xorlw	GET_DESCRIPTOR
	pagesel	Get_Descriptor
	btfsc	STATUS,Z
	goto	Get_Descriptor

EndpointToHost  ; starts in bank2
	movf	BufferData+bRequest,w ; was our request Get Status?
	xorlw	GET_STATUS
	pagesel	Get_Endpoint_Status
	btfsc	STATUS,Z
	goto	Get_Endpoint_Status

	pagesel	wrongstate	; unrecognised token, stall EP0
	goto	wrongstate

	return

; ******************************************************************
; Get Descriptor
; Handles the three different Get Descriptor commands
; ******************************************************************
Get_Descriptor  ; starts in bank2
	movf	BufferData+(wValue+1),w ; request, which seems to be undefined,
	xorlw	0x22		; but it won't enumerate without it
	pagesel	Get_Report_Descriptor
	btfsc	STATUS,Z
	goto	Get_Report_Descriptor

	movf	BufferData+(wValue+1),w
	xorlw	0x21
	pagesel	Get_HID_Descriptor
	btfsc	STATUS,Z
	goto	Get_HID_Descriptor

GetCh9Descriptor
	movlw	high StartGDIndex ; set up PCLATH with the current address
	movwf	PCLATH		; set up pclath for the computed goto
	bcf 	STATUS, C
	movf	BufferData+(wValue+1),w	; move descriptor type into w
	andlw	0x03		; keep things under control
	addlw	low StartGDIndex
	btfsc	STATUS,C	; was there an overflow?
	incf	PCLATH,f	; yes, bump PCLATH
	movwf	PCL		; adjust PC
StartGDIndex						
	goto	wrongstate	; 0
	goto	Get_Device_Descriptor ; 1
	goto	Get_Config_Descriptor ; 2
	goto	Get_String_Descriptor ; 3


; *********************************************************************
; Looks up the offset of the device descriptor via the low order byte
; of wValue.  The pointers are set up and the data is copied to the 
; buffer, then the flags are set.
;
; EP0_start points to the first word to transfer
; EP0_end points to the last, limited to the least of the message length
; or the number of bytes requested in the message (wLength).
; EP0_maxLength is the number of bytes to transfer at a time, 8 bytes
; ******************************************************************
Get_Device_Descriptor  ; starts in bank 2
	movlw	GET_DESCRIPTOR
	movwf	USB_dev_req	; currently processing a get descriptor request
	
	movlw	8
	movwf	EP0_maxLength

	movlw	low DeviceDescriptor
	movwf	EP0_start
	movlw	high DeviceDescriptor
	movwf	EP0_start+1
	pagesel	Descriptions
	call	Descriptions	; get length of device descriptor
	movwf	EP0_end		; save length

	movf	BufferData+(wLength+1),f ; move it to itself, check for non zero.
	pagesel	DeviceEndPtr
	btfss	STATUS,Z	; if zero, we need to compare EP0_end to requested length.
	goto	DeviceEndPtr	; if not, no need to compare.  EP0_end is shorter than request length

	subwf	BufferData+wLength,w ; compare against requested length
	movf	BufferData+wLength,w
	btfss	STATUS,C
	movwf	EP0_end

DeviceEndPtr
	incf	EP0_end,f
	pagesel	copy_descriptor_to_EP0
	call	copy_descriptor_to_EP0

	return


; *********************************************************************
; Looks up the offset of the config descriptor via the low order byte
; of wValue.  The pointers are set up and the data is copied to the 
; buffer, then the flags are set.
;
; EP0_start points to the first word to transfer
; EP0_end points to the last, limited to the least of the message length
; or the number of bytes requested in the message (wLength).
; EP0_maxLength is the number of bytes to transfer at a time, 8 bytes
; ******************************************************************
Get_Config_Descriptor  ; starts in bank2
	movlw	GET_DESCRIPTOR
	movwf	USB_dev_req	; currently processing a get descriptor request

	bcf 	STATUS,C
	rlf 	BufferData+wValue,w
	pagesel	Config_desc_index
	call	Config_desc_index ; translate index to offset into descriptor table
	movwf	EP0_start
	bcf 	STATUS,C
	rlf 	BufferData+wValue,w
	addlw	1		; point to high order byte
	call	Config_desc_index ; translate index to offset into descriptor table
	movwf	EP0_start+1

	movlw	2		; bump pointer by 2 to get the complete descriptor 
	addwf	EP0_start,f	; length, not just config descriptor
	btfsc	STATUS,C
	incf	EP0_start+1,f
	pagesel	Descriptions
	call	Descriptions	; get length of the config descriptor
	movwf	EP0_end 	; Get message length

	movlw	2		; move EP0_start pointer back to beginning
	subwf	EP0_start,f
	btfss	STATUS,C
	decf	EP0_start+1,f

	movf	BufferData+(wLength+1),f ; test for 0
	pagesel	CmpLowerByte
	btfsc	STATUS,Z
	goto	CmpLowerByte
	pagesel	ConfigEndPtr
	goto	ConfigEndPtr	; if not, no need to compare.  EP0_end is shorter than request length

CmpLowerByte
	movf	EP0_end,w
	subwf	BufferData+wLength,w ; compare against requested length
	pagesel	ConfigEndPtr
	btfsc	STATUS,C
	goto	ConfigEndPtr
LimitSize
	movf	BufferData+wLength,w ; if requested length is shorter..
	movwf	EP0_end		; save it.
ConfigEndPtr

	movlw	8
	movwf	EP0_maxLength
	incf	EP0_end,f

	pagesel	copy_descriptor_to_EP0
	call	copy_descriptor_to_EP0
	return

; ******************************************************************
; Set up to return String descriptors
; Looks up the offset of the string descriptor via the low order byte
; of wValue.  The pointers are set up and the data is copied to the 
; buffer, then the flags are set.
; ******************************************************************
Get_String_Descriptor  ; starts in bank2
	movlw	GET_STRING_DESCRIPTOR
	movwf	USB_dev_req	; currently processing a get descriptor request

	movf	BufferData+wIndex,w
	pagesel	not_string0
	btfss	STATUS,Z
	goto	not_string0
	movf	BufferData+(wIndex+1),w
	btfss	STATUS,Z
	goto	not_string0
	movlw	low String0
	movwf	EP0_start
	movlw	high String0
	movwf	EP0_start+1
	pagesel	found_string
	goto	found_string

not_string0
	movlw	high (String0+2)
	movwf	EP0_start+1
	movlw	low (String0+2)
	movwf	EP0_start
	clrf	inner

check_langid
	pagesel	StringDescriptions
	call	StringDescriptions
	incf	EP0_start,f
	subwf	BufferData+wIndex, w
	pagesel	wrong_langid 
	btfss	STATUS, Z
	goto	wrong_langid
	pagesel	StringDescriptions
	call	StringDescriptions
	subwf	BufferData+(wIndex+1), w
	pagesel	right_langid 
	btfsc	STATUS, Z
	goto	right_langid

wrong_langid
	incf	EP0_start,f
	incf	inner,f
	movlw	low String0_end	; compare EP0_start to the addr of
	subwf	EP0_start,w	; the last langid
	pagesel	check_langid
	btfss	STATUS,C	; if EP0_start is equal or lager,
	goto	check_langid	; we've checked all langid and didn't find it
	clrf	USB_dev_req	; clear USB_dev_req, since GET_descriptor is over
	pagesel	wrongstate
	goto	wrongstate

right_langid
	movlw	6		; number of strings we have per language + 1
	subwf	BufferData+wValue,w
	pagesel	right_string
	btfss	STATUS,C
	goto	right_string
	clrf	USB_dev_req
	pagesel	wrongstate
	goto	wrongstate

right_string
	rlf 	BufferData+wValue,w
	movwf	EP0_start+1
	movf	inner,w
	pagesel	string_index
	call	string_index
	movwf	EP0_start
	incf	EP0_start+1,f
	movf	inner,w
	call	string_index
	movwf	EP0_start+1

found_string
	pagesel	StringDescriptions
	call	StringDescriptions ; get length of the string descriptor
	movwf	EP0_end		; save length
	
	subwf	BufferData+wLength,w ; compare against requested length
	movf	BufferData+wLength,w ; if requested length is shorter..
	btfss	STATUS,C
	movwf	EP0_end		; save it.

	movlw	8		; each transfer may be 8 bytes long
	movwf	EP0_maxLength

	incf	EP0_end,f
	pagesel	copy_descriptor_to_EP0
	call	copy_descriptor_to_EP0
	return

; ******************************************************************
; Stalls the EP0 endpoint to signal that the command was not recognised.
; This gets reset as the result of a Setup Transaction.
; ******************************************************************
wrongstate
	global	wrongstate

	banksel	UEP0
	bsf	UEP0,EP_STALL
	bcf	STATUS,RP0	; back to page 2

	return

; ******************************************************************
; Loads the device status byte into the EP0 In Buffer.
; ******************************************************************
Get_Device_Status  ; starts in bank2
	bsf 	STATUS,RP0
	movf	BD0IAL,w	; get buffer pointer
	movwf	FSR
	bcf 	STATUS,RP0	; bank 2
	bsf 	STATUS,IRP	; select indirectly banks 2-3
	movf	USB_status_device,w ; get device status byte
	movwf	INDF
	incf	FSR,f
	clrf	INDF

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

; ******************************************************************
; A do nothing response.  Always returns a two byte record, with all
; bits zero.
; ******************************************************************
Get_Interface_Status ; starts in bank 2
	bsf 	STATUS, RP0	; bank 3
	movf	USWSTAT,w
	xorlw	ADDRESS_STATE
	pagesel	Get_Interface_Status2
	btfss	STATUS, Z
	goto	Get_Interface_Status2
	
	bcf 	STATUS, RP0	; bank 2
	movf	BufferData+wIndex, w
	pagesel	Get_Interface_Status2
	btfss	STATUS, Z
	goto	Get_Interface_Status2

Get_Interface_Status2
	bsf 	STATUS, RP0	; bank3
	movf	USWSTAT,w
	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

Get_Interface_Status_end
	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	; bank3
	movf	BD0IAL,w	; get address of buffer
	movwf	FSR
	movf	temp,w		; load temp
	movwf	INDF		; write byte to buffer
	
	movlw	0x02
	movwf	BD0IBC		; set byte count to 2
	movlw	0xc8		; DATA1 packet, DTS enabled
	movwf	BD0IST		; give buffer back to SIE
	return	

; ******************************************************************
; Returns the Endpoint stall bit via a 2 byte in buffer
; ******************************************************************
Get_Endpoint_Status  ; starts in bank 2
	movlw	0x0f
	andwf	BufferData+wIndex,w ; get endpoint, strip off direction bit
	xorlw	0x01		; is it EP1?
	pagesel	get_EP1_status
	btfsc	STATUS,Z
	goto	get_EP1_status

	movlw	0x0f
	andwf	BufferData+wIndex,w ; get endpoint, strip off direction bit
	xorlw	0x02		; is it EP2?

⌨️ 快捷键说明

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