?? usb_ch9.asm
字號(hào):
; ******************************************************************
Get_Interface_Status ; starts in bank 2
bsf STATUS, RP0 ; bank 3
movf BD0IAL,w ; get buffer pointer
movwf FSR
clrf INDF
incf FSR,f
clrf INDF
movlw 0x02
movwf BD0IBC ; set byte count to 2
movlw 0xC8
movwf BD0IST ; Data 1 packet, set owns bit
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?
btfsc STATUS,Z
goto get_EP1_status
movlw 0x0f
andwf BufferData+wIndex,w ; get endpoint, strip off direction bit
xorlw 0x02 ; is it EP2?
btfss STATUS,Z
goto wrongstate
get_EP2_status
bcf STATUS,C
bsf STATUS,RP0
btfsc UEP2,EP_STALL
bsf STATUS,C
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
movlw SET_ADDRESS
movwf USB_dev_req ; currently processing a get descriptor request
movf BufferData+wValue,w ; new address in low order byte of wValue
movwf USB_address_pending
bsf STATUS, RP0
clrf BD0IBC
movlw 0xc8
movwf BD0IST ; write the whole mess back
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
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,
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
call Send_0Len_pkt
return
; ******************************************************************
; Only endpoint feature is Endpoint halt.
; ******************************************************************
Clear_Endpoint_Feature ; starts in bank 2
movlw 0x0f
andwf BufferData+wIndex,w ; mask off the EP number bits
xorlw 0x01 ; is it EP1?
btfsc STATUS,Z
goto ClearEP1
movlw 0x0f
andwf BufferData+wIndex,w ; mask off the EP number bits
xorlw 0x02 ; is it EP2?
btfss STATUS,Z
goto wrongstate
ClearEP2
bsf STATUS, RP0
bcf UEP2,EP_STALL ; set the stall bit
goto clear_endpoint_end ; skip the second stall
ClearEP1
bsf STATUS, RP0
bcf UEP1,EP_STALL ; set the stall bit
clear_endpoint_end
call Send_0Len_pkt
return
Clear_Interface_Feature ; starts in bank2
return
; ******************************************************************
; 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?
btfss STATUS,Z
goto wrongstate ; request error
bsf USB_status_device,1 ; set device remote wakeup
call Send_0Len_pkt
return
; ******************************************************************
; Only endpoint feature is Endpoint halt.
; ******************************************************************
Set_Endpoint_Feature ; starts in bank 2
movlw 0x0f
andwf BufferData+wIndex,w ; mask off the EP number bits
xorlw 0x01 ; is it EP1?
btfsc STATUS,Z
goto StallEP1
movlw 0x0f
andwf BufferData+wIndex,w ; mask off the EP number bits
xorlw 0x02 ; is it EP2?
btfss STATUS,Z
goto wrongstate
StallEP2
bsf STATUS, RP0
bsf UEP2,EP_STALL ; set the stall bit
goto StallEnd ; skip the second stall
StallEP1
bsf STATUS, RP0
bsf UEP1,EP_STALL ; set the stall bit
StallEnd
call Send_0Len_pkt
return
Set_Interface_Feature ; starts in bank 2
goto wrongstate ; invalid request
return
; ********************************************************************
; 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
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
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
; banksel USWSTAT ; not necessary, Send_0LenPkt resets bank bits
#endif
AckSetConfigCmd
call Send_0Len_pkt
; These configure the EP1 and EP2 endpoints. Change these as necessary
; for your application.
banksel BD1OST
movlw 0x88 ; set own bit of EP1 (SIE can write)
movwf BD1OST
movlw USB_Buffer+0x10 ; Endpoint 1 OUT gets a buffer
movwf BD1OAL ; set up buffer address
movlw 8
movwf BD1OBC ; set byte count
movlw 0x48 ; set own bit of EP1 (PIC can write)
movwf BD1IST
movlw USB_Buffer+0x18 ; Endpoint 1 IN gets a buffer
movwf BD1IAL ; set up buffer address
movlw 0x88 ; set own bit of EP2 (SIE can write)
movwf BD2OST
movlw USB_Buffer+0x20 ; Endpoint 2 OUT gets a buffer
movwf BD2OAL ; set up buffer address
movlw 8
movwf BD2OBC ; set byte count
movlw 0x48 ; set own bit of EP2 (PIC can write)
movwf BD2IST
movlw USB_Buffer+0x20 ; EP1 In and EP2 In share a buffer
movwf BD2IAL ; set up buffer address
; 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
; movf USB_Curr_Config,w ; if you have multiple configurations
; call SetConfiguration
; 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 ; Not valid in the addressed state
bcf STATUS,RP0 ; bank 2
andlw 0x03
xorlw ADDRESS_STATE
btfsc STATUS,Z
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
movf USWSTAT,w ; test to make sure we're configured
bcf STATUS,RP0 ; bank2
andlw 0x03
xorlw CONFIG_STATE
btfss STATUS,Z
goto wrongstate
bcf STATUS, RP0
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.
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)
btfsc STATUS,Z
goto end_gdd_loop
decfsz EP0_end, f
goto gdd_copy_loop
goto end_gdd_loop_short_packet
gdd_copy_loop
pagesel Descriptions
call Descriptions
pagesel gdd_copy_loop
movwf INDF
incf bufindex,f
incf FSR,f
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
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -