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

📄 usb_ch9.asm

📁 This firmware translates a PS/2 mouse to a USB mouse. The translator firmware is entirely interrup
💻 ASM
📖 第 1 页 / 共 4 页
字号:
    movwf   BufferData+5
    incf    FSR,f
    movf    INDF,w
    movwf   BufferData+6
    incf    FSR,f
    movf    INDF,w
    movwf   BufferData+7

    bsf     STATUS, RP0
    movlw   0x88            ; set UOWNs bit back to SIE
    movwf   BD0OST
    movlw   0x08
    movwf   BD0OBC          ; reset the byte count too.
    movwf   BD0IST          ; return the in buffer to us (dequeue any pending requests)

    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
    btfsc   STATUS,Z
    goto    HostToDevice

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

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

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

    movf    BufferData+bmRequestType,w
    xorlw   0x82            ; test for device to Endpoint tokens
    btfsc   STATUS,Z
    goto    EndpointToHost

    pagesel ClassSpecificRequest
    movf    BufferData+bmRequestType,w
    andlw   0x60            ; mask off type bits
    xorlw   0x20            ; test for class specific
    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
    btfss   STATUS,Z        ; was it a standard request?
    pagesel wrongstate
    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
    btfsc   STATUS,Z
    goto    Clear_Device_Feature

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

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

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

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

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

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

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

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

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

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

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

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

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

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

EndpointToHost  ; starts in bank2
    movf    BufferData+bRequest,w   ; was our request Get Status?
    xorlw   GET_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
    pagesel Get_Report_Descriptor
    movf    BufferData+(wValue+1),w ; request, which seems to be undefined,
    xorlw   0x22                    ; but it won't enumerate without it
    btfsc   STATUS,Z
    goto    Get_Report_Descriptor

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

GetCh9Descriptor
    movlw   high StartGDIndex       ; set up PCLATH with the current address
    movwf   PCLATH                  ; set up pclath for the computed goto
    movf    BufferData+(wValue+1),w ; get descriptor type
    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
;    goto    Get_Interface_Descriptor ; 4 - not used
;    goto    Get_EndPoint_Descriptor  ; 5 - not used
;    goto    wrongstate               ; 6
;    goto    wrongstate               ; 7


; *********************************************************************
; 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
    pagesel Descriptions        ; set up PCLATH for call below
    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
    call    Descriptions        ; get length of device descriptor
    movwf   EP0_end             ; save length
    pagesel DeviceEndPtr

    movf    BufferData+(wLength+1),f ; move it to itself, check for non zero.
    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
    pagesel Descriptions        ; set up PCLATH for call below
    movlw   GET_DESCRIPTOR
    movwf   USB_dev_req         ; currently processing a get descriptor request

    bcf     STATUS,C
    rlf     BufferData+wValue,w
    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
    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
    btfsc   STATUS,Z
    pagesel CmpLowerByte
    goto    CmpLowerByte
    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
    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
    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
    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
    pagesel wrong_langid 
    incf    EP0_start,f
    subwf   BufferData+wIndex, w
    btfss   STATUS, Z
    goto    wrong_langid
    pagesel StringDescriptions
    call    StringDescriptions
    pagesel right_langid 
    subwf   BufferData+(wIndex+1), w
    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
    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
    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.

⌨️ 快捷键说明

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