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

📄 usb_ch9.asm

📁 pic16c745 的 firmware的一个usb样例,供大家参考
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	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

	pagesel	wrongstate
	goto	wrongstate

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

	pagesel	wrongstate
	goto	wrongstate

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

	pagesel	wrongstate
	goto	wrongstate

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
	goto	wrongstate

; ******************************************************************
; 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

	pagesel	GetStringIndex
	bcf	STATUS,C		; clear the carry
	rlf	BufferData+wValue,w	; Multiply the String number by 2
	call	GetStringIndex		; Find the starting address of the specified string
	movwf	EP0_start
	bcf	STATUS,C		; clear the carry
	rlf	BufferData+wValue,w	; multiply string number by 2
	addlw	1			; add one to point to high byte
	call	GetStringIndex		; Find the starting address of the specified string
	movwf	EP0_start+1

	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	; Set the Protocol Stall bit
	clrf	STATUS		; bank 0
	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?
	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 ; Make sure address is legal (0x7F or less)
	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
	banksel	UIR
	bsf	UIE,TOK_DNE	; enable token done interrupt

⌨️ 快捷键说明

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