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

📄 hub_ep0.asm

📁 mcs51,2051,x86系列MCU
💻 ASM
📖 第 1 页 / 共 5 页
字号:
        mov      COMMAND_BUFFER+2, RXDAT         ; wValue MSB
        mov      COMMAND_BUFFER+5, RXDAT         ; wIndex LSB
        mov      COMMAND_BUFFER+4, RXDAT         ; wIndex MSB
        mov      COMMAND_BUFFER+7, RXDAT         ; wLength LSB
        mov      COMMAND_BUFFER+6, RXDAT         ; wLength MSB

        setb    RXFFRC                                  ; Update receive FIFO state
        clr     RXSETUP

        push     DPX                              ; Processing the jump table will
                                                  ; corrupt DPX.  Save it here
        lCall    ProcessSetup
        pop      DPX                              ; Restore DPX
ReturnSetup:
        Ret

;COMMENT *------------------------------------------------------------
;Function name     : ProcessSetup
;Brief Description : Process a Setup token recd. on EP0. Thile some of the
;                  : code may look sifficult to understand the end result is not.
;                  : The following simply prepares a byte of data for use in a jump table.
;                  : The code compresses the 8 byte bmRequestValue into 4 1/2
;                  : bits by removing bits 2,3 & 4.  These bits are never used
;                  : and it allows the jump table to be signfigantly smaller.
;                  : By using this jump table, the code size reduces by several
;                  : hundred bytes over the entire code!
;                  : THIS FIRMWARE IS ASSUMES BITS 2,3 & 4 are zero!!!!
;                  : By compressing the byte down, we limit the size
;                  : of the jump table.
;Regs preserved    : No reg. is saved
;--------------------------------------------------------------------*
;SCOPE
ProcessSetup:

        ; The First step is setting up the Stage tracing variable by examing the
        ; bmRequest value.  This will tell us if this is a control Write
        ; or control read command.  For right now we will assume that this
        ; is a no data command and will therefore pre-initilize the data
        ; byte counters used to send data back, to zero.

        mov     gbFControlBufferBytesLeft,     #00h
        mov     gbFControlBufferBytesLeft + 1, #00h
        mov     A,            bmRequestType
        jb      ACC.7,        SetupGetCommand

SetupSetCommand:
        mov     gbSetupSeqRX, #DATA_PHASE        ; Advance State Machine to next state
        mov     gbSetupSeqTX, #STATUS_PHASE
                                                 ; Now check to see if this is a control write with a data stage.
        mov     A,            wLength
        orl     A,            wLength+1
        jz      DoJumpTable                      ; If this is a no data command then process it
        ret                                      ; If we are expecting data then don't
                                                 ; process the command yet.  Exit and wait
                                                 ; for the rest of the data to come in.



SetupGetCommand:
        mov     gbSetupSeqRX, #STATUS_PHASE      ; Advance State Machine to next state
        mov     gbSetupSeqTX, #DATA_PHASE

DoJumpTable:
        ; This table will jump to the correct subroutine
        ; to handle the type of command contained in bmRequestType
        ; The new jmp table will be compressed by shifting and rotating
        ; out bits, 2,3 & 4.
        ; Place bmRequestType in the following order and then do the jump table
        ; on it.
        ; xx65107x
        ; if bits 65 == 11, Reserved = Error
        ; Unless you have time, don't spend a lot of time tracing the algorythm
        ; It's fancy and it works.  If you don't understand it go ask someone for a quarter.


        mov     A,      bmRequestType            ; Get the value.

        anl     A,      #0E3h                    ; Clear out bits 2,3,4 since
                                                 ; we don't need these
                                                 ; Reg A now looks like 765xxx10
        RL      A                                ; Put bits 1,0,& 7 in new placement
        RL      A                                ; Leave LSB cleared so jump is the number of words.
                                                 ; xxxx1076
CheckBit6:                                       ; 6 is currently in bit 0 position,
        jnb     ACC.0,  CheckBit5                ; Convert it to bit 5 position
        setb    ACC.5                            ; xx6x107x
 CheckBit5:                                      ; Bit 5 is currently at 7 position
        jnb     ACC.7,  CheckValidType           ; Convert it to bit 4 position
        setb    ACC.4                            ; xx65107x

CheckValidType:                                  ;
        jnb     ACC.5,  GoodCommand              ; If this bit (6) is clear we know
                                                 ; it's a valid value
        jb      ACC.4,  ReservedCommand          ; Bit (6) was set, if bit 5 is set it's
                                                 ; a reserved command.
        ljmp     GoodCommand

ReservedCommand:

        orl     EPCON, #0C0h                     ; Stall EP0.
        ret


                                                     ; THis code will branch to the correct jump statement
                                                     ; in the bmRequestJumpTable below.
GoodCommand:
        anl     A, #3Eh
        mov     B, A
        rr      A
        anl     A, #1fH
        clr     CY
        ADD     A, B
        mov     DPTR,   #bmRequestJumpTable
        mov     DPXL,   #LOW HIGH16(GoodCommand)     ; Get Page of Jump Table.
                                                     ; Low byte of the upper 16 bits of the 32 bit address of the
                                                     ; jump table.
                                                     ; Is this code in RAM or ROM
        jmp     @A+DPTR                              ; Used because I use RISM sometimes
                                                     ; which places code in RAM

;---------------------------------------
;-- bmRequest Jump Table ---------------
;-- The order of these are based on the
;-- compresion algorythm used above.
;-- Each of these instructions occupy two bytes of
;-- ROM.  Do not change AJMP to LJMP as the algorytm depends on the
;-- 2 byte length of AJMP.  LJMP is 3 bytes long
;-- ------------------------------------
bmRequestJumpTable:
        LJMP    StandardSetDeviceCommand
        LJMP    StandardGetDeviceCommand
        LJMP    StandardSetInterfaceCommand
        LJMP    StandardGetInterfaceCommand
        LJMP    StandardSetEndpointCommand
        LJMP    StandardGetEndpointCommand
        LJMP    StandardSetOtherCommand
        LJMP    StandardGetOtherCommand

        LJMP    ClassSetDeviceCommand
        LJMP    ClassGetDeviceCommand
        LJMP    ClassSetInterfaceCommand
        LJMP    ClassGetInterfaceCommand
        LJMP    ClassSetEndpointCommand
        LJMP    ClassGetEndpointCommand
        LJMP    ClassSetOtherCommand
        LJMP    ClassGetOtherCommand

        LJMP    VendorSetDeviceCommand
        LJMP    VendorGetDeviceCommand
        LJMP    VendorSetInterfaceCommand
        LJMP    VendorGetInterfaceCommand
        LJMP    VendorSetEndpointCommand
        LJMP    VendorGetEndpointCommand
        LJMP    VendorSetOtherCommand
        LJMP    VendorGetOtherCommand





;-----------------------------------------------------------------
;SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSs
;S
;S          STANDARD TYPE COMMANDS FIRST
;S
;SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSs
;-----------------------------------------------------------------

;COMMENT *------------------------------------------------------------
;Function name     : GetStandardDeviceCommand:
;Brief Description : Process a Get Standard Device Command Setup Token
;                  : This can only be a Get (Device or Configuration) Descriptor,
;                  : or Get Device Status, Get Configuration.
;Regs preserved    : No reg. is saved
;--------------------------------------------------------------------*
;SCOPE
StandardGetDeviceCommand:
        mov     A,     bRequest
        cjne    A,     #GET_DESCRIPTOR, CheckGetConfiguration

        mov     A,     bDescriptorType
        cjne    A,     #DEVICE_DESCR, CheckConfigDescriptor

        ; ********************** GET DESCRIPTOR,  DEVICE *******************
        mov     gbFControlBufferLocation,   #LOW HIGH16(BEGIN_DEVICE_DESCRIPTOR)
        mov     gbFControlBufferLocation+1, #HIGH LOW16(BEGIN_DEVICE_DESCRIPTOR)
        mov     gbFControlBufferLocation+2, #LOW  LOW16(BEGIN_DEVICE_DESCRIPTOR)
        mov     A,  #12h
        mov     B,  #00h
        ljmp     LoadBuffer

CheckConfigDescriptor:
        cjne    A,     #CONFIG_DESCR, CheckStringDescriptor

        ; ********************** GET DESCRIPTOR,  CONFIGURATION ************
        mov     gbFControlBufferLocation,   #LOW HIGH16(BEGIN_CONFIG_DESCRIPTOR)
        mov     gbFControlBufferLocation+1, #HIGH LOW16(BEGIN_CONFIG_DESCRIPTOR)
        mov     gbFControlBufferLocation+2, #LOW  LOW16(BEGIN_CONFIG_DESCRIPTOR)
        mov     A,  #LOW  (END_CONFIG_DESCRIPTOR - BEGIN_CONFIG_DESCRIPTOR)
        mov     B,  #HIGH (END_CONFIG_DESCRIPTOR - BEGIN_CONFIG_DESCRIPTOR)
        ljmp     LoadBuffer

CheckStringDescriptor:
        cjne    A,     #STRING_DESCR, ReturnBADSTDGetDeviceCommand
        ; ********************** GET DESCRIPTOR,  CONFIGURATION ************
        mov     gbFControlBufferLocation,   #LOW HIGH16(STRING_1)
        mov     gbFControlBufferLocation+1, #HIGH LOW16(STRING_1)
        mov     gbFControlBufferLocation+2, #LOW  LOW16(STRING_1)

        mov     A,     #LOW (STRING_2-STRING_1)
        mov     B,     #HIGH(STRING_2-STRING_1)
        ljmp     LoadBuffer



LoadBuffer:                                 ; Compare to see which is shorter.
                                            ; The amount asked for or the amount
                                            ; availible.

        push    ACC
        push    B
        clr     CY                          ; A=Actual-wLength=AskedFor
        subb    A,  wLength+1
        mov     A,  B
        subb    A,  wLength
        jc      AskedFor_IsLarger

LengthsMatch:
wLengthIsSmaller:                           ; If Asked for is smaller, replace
                                            ; actual with asked for.
        pop     B
        pop     ACC
        mov     B,  wLength
        mov     A,  wLength+1
       sjmp     LoadIt

AskedFor_IsLarger:
        pop     B
        pop     ACC
LoadIt:                                     ; From now on, wLength = bytes remaining.
        mov     gbFControlBufferBytesLeft,   B
        mov     gbFControlBufferBytesLeft+1, A
       lcall    LoadControlTXFifo
        ljmp     ReturnSTDGetDeviceCommand





CheckGetConfiguration:
        cjne    A,     #GET_CONFIGURATION, CheckGetStatus
                   ;------------------------------------------------
                   ;- GET CONFIGURATION
                   ;------------------------------------------------
        mov     R11, CurrentConfiguration
        mov     TXDAT, A
        mov     TXCNTL,#01h
        ljmp     ReturnSTDGetDeviceCommand
CheckGetStatus:
        cjne    A,     #GET_STATUS, ReturnSTDGetDeviceCommand
                   ;------------------------------------------------
                   ;- GET DEVICE STATUS
                   ;------------------------------------------------

        jnb     HRWUPE, NotRWUEnabled
        mov     A, #03h             ; RWU Enabled and self powered
       sjmp     DoneGetDeviceStatus
NotRWUEnabled:
        mov     A, #01h             ; RWU Not Enabled and self powered
DoneGetDeviceStatus:
        mov     TXDAT, A
        mov     TXDAT, #00h
        mov     TXCNTL,#02h
        ljmp     ReturnSTDGetDeviceCommand
ReturnBADSTDGetDeviceCommand:

        orl     EPCON, #0C0h                   ; Stall EP0

ReturnSTDGetDeviceCommand:
        ret


;COMMENT *------------------------------------------------------------
;Function name     : StandardGetEndpointCommand:
;Brief Description : Process a Standard Set Endpoint Command Setup Token
;                  : This can only be a Set,Clear Feature - Endpoint Stall
;                  :
;Regs preserved    : No reg. is saved
;--------------------------------------------------------------------*
;SCOPE
StandardGetEndpointCommand:

        mov     A,     bRequest
        cjne    A,     #GET_STATUS,    ReturnBadSTDGetEPCommand
                   ;------------------------------------------------
                   ;- GET ENDPOINT STATUS
                   ;------------------------------------------------
        mov     A,      wIndex + 1
        anl     A,      #0Fh                     ; Mask off all but the endpoint value
        orl     EPINDEX,A                        ; Point the Index register at the

        mov     A,      wIndex + 1               ; Start by clearing out R0
        jb      ACC.7,  GetInStallStatus

GetOutStallStatus:
        mov     A,      EPCON
        jnb     ACC.6,  NotStalled
        mov     A,      #01                      ; Return Stalled
        ljmp    DoneWithCommand

GetInStallStatus:
        mov     A,      wIndex +1
        anl     A,      #0Fh
        cjne    A,      #00, GetEp1InStall

        mov     A,      EPCON
        jnb     ACC.7,  NotStalled
        mov     A,      #01
        sjmp    DoneWithCommand

GetEp1InStall:
        mov     A,      HSTAT                    ; GET EP1 Stall Information
        anl     A,      #020h                    ; Mask off all but stall bit.
        jz      NotStalled
        mov     A,      #01h
        sjmp    DoneWithCommand


NotStalled:
        mov     A,      #00h
DoneWithCommand:
        anl     EPINDEX,#80h                     ; Point the index back to EP0
        mov     TXDAT, A

⌨️ 快捷键说明

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