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

📄 usb_ch9.asm

📁 pic16c745 的 firmware的一个usb样例,供大家参考
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	return

 
; ******************************************************************
; The SIE detected an error.  This code increments the appropriate 
; error counter and clears the flag.
; ******************************************************************
USBError
	global	USBError
	banksel UIR
	bcf 	UIR,UERR
	movf	UEIR,w		; get the error register
	andwf	UEIE,w		; mask with the enables
	clrf	UEIR
	banksel	USBMaskedErrors ; switch to bank 2
	movwf	USBMaskedErrors	; save the masked errors	
#ifdef COUNTERRORS
	pagesel CRC5Error
	btfss	USBMaskedErrors,PID_ERR
	goto	CRC5Error
	INCREMENT16 USB_PID_ERR
CRC5Error
	pagesel CRC16Error
	btfss	USBMaskedErrors,CRC5
	goto	CRC16Error
	INCREMENT16 USB_CRC5_ERR
CRC16Error
	pagesel DFN8Error
	btfss	USBMaskedErrors,CRC16
	goto	DFN8Error
	INCREMENT16 USB_CRC16_ERR
DFN8Error
	pagesel BTOError
	btfss	USBMaskedErrors,DFN8
	goto	BTOError
	INCREMENT16 USB_DFN8_ERR
BTOError
	pagesel WRTError
	btfss	USBMaskedErrors,BTO_ERR
	goto	WRTError
	INCREMENT16 USB_BTO_ERR
WRTError
	pagesel OWNError
	btfss	USBMaskedErrors,WRT_ERR
	goto	OWNError
	INCREMENT16 USB_WRT_ERR
OWNError
	pagesel BTSError
	btfss	USBMaskedErrors,OWN_ERR
	goto	BTSError
	INCREMENT16 USB_OWN_ERR
BTSError
	pagesel	EndError
	btfss	USBMaskedErrors,BTS_ERR
	goto	EndError
	INCREMENT16 USB_BTS_ERR
EndError
#endif
	bcf	STATUS,RP1	; Bank 0
	return

; ******************************************************************
; Process token done interrupt...  Most of the work gets done through
; this interrupt.  Token Done is signaled in response to an In, Out,
; or Setup transaction.
; ******************************************************************
TokenDone
	global	TokenDone
	COPYBUFFERDESCRIPTOR	; copy BD from dual port to unbanked RAM
	banksel	USTAT
	movf	USTAT,w		; get the status register
	bcf 	UIR,TOK_DNE	; clearing the token done interrupt.
	bcf 	STATUS,RP0	; switch to bank 2
	movwf	USB_USTAT	; Save USTAT in bank 2

#ifdef SHOW_ENUM_STATUS
; This toggles the activity bits on portB  (EP0 -> Bit 5; EP1 -> bit 6; EP2 -> bit 7)
	bcf 	STATUS,RP1	; bank 0
	andlw	0x18		; save endpoint bits
	pagesel tryEP1activity
	btfss	STATUS,Z	; is it EP0?
	goto	tryEP1activity
	movlw	0x20
	pagesel maskport
	goto	maskport
tryEP1activity
	xorlw	0x08		; is it bit one?
	btfss	STATUS,Z
	movlw	0x80		; No, It's not EP0, nor 1 so it must be EP2.  toggle bit 7
	btfsc	STATUS,Z
	movlw	0x40		; Yes, toggle bit 6 to Show EP1 activity
maskport
	xorwf	PORTB,f
#endif

; check UOWN bit here if desired
	banksel	BufferDescriptor
	movf	BufferDescriptor,w  ; get the first byte of the BD
	andlw	0x3c		; save the PIDs
	movwf	PIDs

	xorlw	TOKEN_IN
	pagesel	TokenInPID
	btfsc	STATUS,Z
	goto	TokenInPID

	movf	PIDs,w
	xorlw	TOKEN_OUT
	pagesel TokenOutPID
	btfsc	STATUS,Z
	goto	TokenOutPID

	movf	PIDs,w
	xorlw	TOKEN_SETUP
	pagesel TokenSetupPID
	btfsc	STATUS,Z
	goto	TokenSetupPID

	return  		; should never get here...

; ******************************************************************
; Process out tokens
; For EP0, just turn the buffer around.  There should be no EP0 
; tokens to deal with.
; EP1 and EP2 have live data destined for the application
; ******************************************************************
TokenOutPID  ; STARTS IN BANK2
	movf	USB_USTAT,w	; get the status register
	pagesel	tryEP1
	btfss	STATUS,Z	; was it EP0?
	goto	tryEP1 		; no, try EP1
	movf	USB_dev_req,w
	xorlw	HID_SET_REPORT
	pagesel	ResetEP0OutBuffer
	btfss	STATUS,Z
	goto	ResetEP0OutBuffer

HIDSetReport

; ******************************************************************
; You must write your own SET_REPORT routine.  The following 
; commented out code is provided if you desire to make a SET_REPORT
; look like a EP1 OUT Interrupt transfer.  Uncomment it and use it
; if you desire this functionality.
; ******************************************************************
;	movlw	0xFF
;	movwf	USB_dev_req	; clear the request type
;	banksel	BD1IST
;	movf	BD0OST,w
;	movwf	BD1OST		; Copy status register to EP1 Out
;	movf	BD0OAL,w	; get EP0 Out buffer address
;	bcf 	STATUS,RP0	; bank 2
;	movwf	hid_source_ptr
;	bsf 	STATUS,RP0	; bank 3
;	movf	BD1OAL,w	; get EP1 Out Buffer Address
;	bcf 	STATUS,RP0	; bank 2
;	movwf	hid_dest_ptr
;	bsf 	STATUS,RP0	; bank 3
;	movf	BD0OBC,w	; Get byte count
;	movwf	BD1OBC		; copy to EP1 Byte count
;	bcf 	STATUS,RP0	; bank 2
;	movwf	counter
;	bankisel BD1IST		; indirectly to bank 3
;HIDSRCopyLoop
;	movf	hid_source_ptr,w
;	movwf	FSR
;	movf	INDF,w
;	movwf	temp
;	movf	hid_dest_ptr,w
;	movwf	FSR
;	movf	temp,w
;	movwf	INDF
;	incf	hid_source_ptr,f
;	incf	hid_dest_ptr,f
;	decfsz	counter,f
;	goto	HIDSRCopyLoop
;
;	bsf 	STATUS,RP0	; bank 3
;	movlw	0x08
;	movwf	BD0OST		; REset EP0 Status back to SIE

ResetEP0OutBuffer
	bsf 	STATUS,RP0	; no, just reset buffer and move on.
	movlw	0x08		; it's EP0.. buffer already copied,
	movwf	BD0OBC		; just reset the buffer
	movlw	0x88
	movwf	BD0OST		; set OWN and DTS Bit
	pagesel	Send_0Len_pkt
	goto	Send_0Len_pkt

tryEP1  ; bank 2
	xorlw	0x08		; was it EP1?
	pagesel	tryEP2
	btfss	STATUS,Z
	goto	tryEP2

; **** Add Callout here to service EP1 in transactions.  ****
	return

tryEP2  ; bank 2
	movf	USB_USTAT,w
	xorlw	0x10		; was it EP2?
	btfsc	STATUS,Z
	return  		; unrecognized EP (Should never take this exit)

; **** Add Callout here to service EP2 in transactions.  ****
	return

; ******************************************************************
; Process in tokens
; ******************************************************************
TokenInPID  ; starts in bank2
; Assumes EP0 vars are setup in a previous call to setup.  
EP0_in
	movf	USB_USTAT,w	; get the status register
	andlw	0x18		; save only EP bits (we already know it's an IN)
	pagesel	tryEP1in
	btfss	STATUS,Z	; was it EP0?
	goto	tryEP1in	; no, try EP1

	movf	USB_dev_req,w
	xorlw	GET_DESCRIPTOR
	pagesel	check_GSD
	btfss	STATUS,Z
	goto	check_GSD
	pagesel	copy_descriptor_to_EP0
	call	copy_descriptor_to_EP0
	pagesel exitEP0in
	goto	exitEP0in

; Check for Get String Descriptor
check_GSD
	movf	USB_dev_req,w
	xorlw	GET_STRING_DESCRIPTOR
	pagesel	check_SF
	btfss	STATUS,Z
	goto	check_SF
	pagesel	copy_descriptor_to_EP0
	call	copy_descriptor_to_EP0
	pagesel	exitEP0in
	goto	exitEP0in

check_SF
	movf	USB_dev_req,w
	xorlw	SET_FEATURE
	pagesel	check_CF
	btfss	STATUS,Z
	goto	check_CF
	pagesel	exitEP0in
	goto	exitEP0in

check_CF
	movf	USB_dev_req,w
	xorlw	CLEAR_FEATURE
	pagesel	Class_Specific
	btfss	STATUS,Z
	goto	Class_Specific
	movf	BufferData+4, w	; clear endpoint 1 stall bit
	xorlw	1			
	pagesel	clear_EP2	
	btfss	STATUS,Z
	goto	clear_EP2
	bsf 	STATUS, RP0	; bank 3
	bsf 	UEP1, EP_STALL
	pagesel	exitEP0in
	goto	exitEP0in
clear_EP2
	movf	BufferData+wIndex, w	; clear endpoint 2 stall bit
	xorlw	2
	pagesel	exitEP0in
	btfss	STATUS,Z
	goto	exitEP0in
	bsf 	STATUS, RP0	; bank 3
	bsf 	UEP2, EP_STALL
	pagesel	exitEP0in
	goto	exitEP0in

Class_Specific
	pagesel	Check_Class_Specific_IN
	goto	Check_Class_Specific_IN

exitEP0in
	return


; ******************************************************************
; though not required, it might be nice to have a callback function here
; that would take some action like setting up the next buffer when the
; previous one is complete.  Not necessary because the same functionality
; can be provided through the PutUSB call.  
; ******************************************************************
tryEP1in  ; starts in bank 2
	xorlw	0x08		; was it EP1?
	pagesel	tryEP1in
	btfss	STATUS,Z
	goto	tryEP2in
; **** Add Callout here to service EP1 in transactions.  ****
	return

tryEP2in  ; starts in bank 2
; **** Add Callout here to service EP2 in transactions.  ****
	return
; ******************************************************************
; Return a zero length packet on EP0 In
; ******************************************************************
Send_0Len_pkt
	global	Send_0Len_pkt

	banksel	BD0IBC
	clrf	BD0IBC		; set byte count to 0
	movlw	0xc8
	movwf	BD0IST		; set owns bit
	bcf	STATUS,RP0	; back to bank 2
	clrf	USB_dev_req
	return

; ********************************************************************
; process setup tokens
; ******************************************************************
TokenSetupPID  ; starts in bank 2
	bsf 	STATUS,IRP	; indirectly to pages 2/3
	movf	BufferDescriptor+ADDRESS,w ; get the status register
	movwf	FSR ; save in the FSR.
	movf	INDF,w
	movwf	BufferData	; in shared RAM
	incf	FSR,f
	movf	INDF,w
	movwf	BufferData+1
	incf	FSR,f
	movf	INDF,w
	movwf	BufferData+2
	incf	FSR,f
	movf	INDF,w
	movwf	BufferData+3
	incf	FSR,f
	movf	INDF,w
	movwf	BufferData+4
	incf	FSR,f
	movf	INDF,w
	movwf	BufferData+5
	incf	FSR,f
	movf	INDF,w
	movwf	BufferData+6
	incf	FSR,f
	movf	INDF,w
	movwf	BufferData+7
	bsf 	STATUS, RP0	; bank 3
	movlw	0x08
	movwf	BD0OBC		; reset the byte count too.
	movwf	BD0IST		; return the in buffer to us (dequeue any pending requests)
	bcf 	STATUS, RP0	; bank 2
	movf	BufferData+bmRequestType, w
	xorlw	0x21		; set EP0 OUT UOWNs back to SIE
	movlw	0x88		; set DATA0/DATA1 packet according to request type
	btfsc	STATUS, Z
	movlw	0xC8
	bsf 	STATUS, RP0	; bank 3
	movwf	BD0OST		

	bcf 	UCTRL,PKT_DIS	; Assuming there is nothing to dequeue, clear the packet disable bit

	bcf 	STATUS,RP0	; bank 2
	clrf	USB_dev_req	; clear the device request..
	movf	BufferData+bmRequestType,w
	pagesel	HostToDevice
	btfsc	STATUS,Z
	goto	HostToDevice

	movf	BufferData+bmRequestType,w
	xorlw	0x01		; test for host to Interface tokens
	pagesel	HostToInterface
	btfsc	STATUS,Z
	goto	HostToInterface

	movf	BufferData+bmRequestType,w
	xorlw	0x02		; test for host to Endpoint tokens
	pagesel	HostToEndpoint
	btfsc	STATUS,Z
	goto	HostToEndpoint

	movf	BufferData+bmRequestType,w
	xorlw	0x80		; test for device to Host tokens
	pagesel	DeviceToHost
	btfsc	STATUS,Z
	goto	DeviceToHost
 
	movf	BufferData+bmRequestType,w
	xorlw	0x81		; test for device to Interface tokens
	pagesel	InterfaceToHost
	btfsc	STATUS,Z
	goto	InterfaceToHost

	movf	BufferData+bmRequestType,w
	xorlw	0x82		; test for device to Endpoint tokens
	pagesel	EndpointToHost
	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

; 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

⌨️ 快捷键说明

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