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

📄 ax_enum.asm

📁 mcs51,2051,x86系列MCU
💻 ASM
📖 第 1 页 / 共 5 页
字号:
        pop     PSW

        reti
$$END$


;COMMENT *------------------------------------------------------------
;Function name     : ProcessOutToken
;Brief Description : Services all OUTs on EP0.
;                  : This routine checks to see if this is an OUT token oor
;                  : SETUP token.  If a SETUP token then the Control COmmand
;                  : State machine is initilized to SETUP STAGE
;Regs preserved    : No reg. is saved
;--------------------------------------------------------------------*

ProcessOutToken:

        anl     FIFLG,   #EP0_RX_CLR        ; Clear the interrupt bit.
;        jmp     ProcCommand

ProcCommand:
        mov     A,     RXSTAT
        jnb     ACC.6, CheckOutStatusPhase  ; Is this a setup packet??



                                            ; Now Check for Data still in FIFO.
                                            ; If this is true then the function
                                            ; did not see the ACK form the host.
        mov     A,      TXFLG
        anl     A,      #0C0h
        jZ      NoEP0Error

        setb    TXCLR                       ; Flush the Transmit FIFOS in case
                                            ; a null packet is still left.

NoEP0Error:
                                            ; Check to see if the stall bit is set.
        mov     A, EPCON
        anl     A, #0C0h
        jz      NoEp0Stall
        anl     EPCON, #03Fh                ; Clear the stalls
        orl     TXSTAT, #88h                ; Set data toggle on TX ep0.
NoEp0Stall:
        lCall   SetupReceived


        sjmp    ReturnProcessOutToken

CheckOutStatusPhase:
        mov     A,     gbSetupSeqRX
        cjne    A,     #STATUS_PHASE, CheckDataPhase     ; Is this the status phase of a "GET"
                                                         ; command?

        setb    RXFFRC                      ; Update receive FIFO state
        mov     A,     #SETUP_PHASE         ; Update the state machine to
                                            ; expect a setup packet
        mov     gbSetupSeqRX, A
        mov     gbSetupSeqTX, A
        sjmp    ReturnProcessOutToken

            ;---------------------------------------------------------------
            ; -   Control Write Data Stage
            ;---------------------------------------------------------------

                ; If this is a control write command with a datastage then this
                ; routine will be called on all data stages of the control write.
                ; When all the data has been collected(Bytes received=wLength)
                ; the actual routine is called.  The size of data is limited to this
                ; buffer length.
                ; THE CALLING CODE MUST THEN CALL SetUpControlWriteStatusStage to allow
                ; the status stage to continue.  The user must NOT do this themselves.
                ; Later in the life of this code, other features will be added here.

CheckDataPhase:
        cjne    A,     #DATA_PHASE, BadOutToken
                                       ; Are we processing a Control Write,
                                       ; i.e. Set Descr...
                                       ; Added to handle control writes with data stages.
                                       ; When a control Write with a data stage is detected
                                       ; the data is placed in the buffer 'CntlWriteDataBuffer'
                                       ; When all the data
                                       ; has been collected(Bytes received=wLength) the actual routine is
                                       ; called.  The size of data is limited to this buffer length.
                                       ;---------------------------------------------------------
                                       ;------------------- NOTE --------------------------------
                                       ;---------------------------------------------------------
                                       ; For this routine to work all the data must be stored below
                                       ; 100h as I am using byte addressing.  Also, since 80-FF is used
                                       ; as SFRs and I don't want to for the user to use indirect
                                       ; addressing, the data must ne stored between 20h-7Fh.
                                       ; Also, these routines will only work for data sets of less than
                                       ; 256.  But the above limitations put this the max much ower than
                                       ; this. MaxBuffer = (7F-20h-Other varaibles in this region)


         push    R0
         mov     A,     #CntlWriteDataBuffer         ; Get location of buffer

         add     A,     CntlWriteDataPntr   ; Add the offset
         mov     R0,    A                   ; R0 now contains the location to start storing the
                                            ; data.

                                            ; Update the data stored in memory
         mov     A,     RXCNTL              ; Get number of bytes to move
         add     A,     CntlWriteDataPntr   ; Add number received
         mov     CntlWriteDataPntr,  A      ; update memory variable

         mov     A,     RXCNTL
         JZ      RdDone                     ; If no data in the buffer, then exit.

ReadData:
         mov     @R0,   RXDAT               ; Get the data and store it.
         inc     R0
         djnz    ACC,   ReadData
         pop     R0
RdDone:
         setb    RXFFRC                     ; Update receive FIFO state

                                            ; Now check to see if this was the last
                                            ; read by checking if (Bytes received=wLength)
         mov     A,    CntlWriteDataPntr
         cjne    A,    wLength+1, NeedMoreData       ; If this is not equal to the expected, then jmp around.

                                            ; When all the data has been received, the
                                            ; other routines in this program will
                                            ; be called to process it.
ProcessControlWriteData:

        push     DPX                        ; Processing the jump table will
                                            ; corrupt DPX.  Save it here
        lcall    DoJumpTable                ; At this point all data has been
                                            ; stored and all we need to do now is to
                                            ; process it.
        pop      DPX                        ; Restore DPX
        sjmp     ReturnProcessOutToken

NeedMoreData:

CheckCommand2:

BadOutToken:
        orl      EPCON, #0C0h               ; Who knows what this was.  Stall the EP.
ReturnProcessOutToken:
        Ret


;COMMENT *------------------------------------------------------------
;Function name     : SetupReceived
;Brief Description : Service all Setup Tokens recd. on EP0
;Regs preserved    : No reg. is saved
;--------------------------------------------------------------------*


SetupReceived:
         mov     A,     RXCNTL              ; Get the no. of bytes
         clr     CY

         subb    A,     #8                  ; 8 is length of all setup packets.
         JNZ     ReturnSetup                ; If less than 8 bytes recd.
                                            ; Return

                                            ; Since buffer will reside within the
                                            ; the first 255 bytes, I can use
                                            ; register indirect addressing
        ; Move FIFO to command buffer.
        ; Notice byte swapping of word fields
        ; For Word Fields make USB Little Endian words->'251 Big Endian words
        clr      EDOVW
        mov      COMMAND_BUFFER,   RXDAT    ; bmRequestType
        mov      COMMAND_BUFFER+1, RXDAT    ; bRequest
        mov      COMMAND_BUFFER+3, RXDAT    ; wValue LSB
        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

        push     DPX                        ; Processing the jump table will
                                            ; corrupt DPX.  Save it here
;(KLS)
        setb    RXFFRC
        clr     RXSETUP
        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
;--------------------------------------------------------------------*

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
        mov     CntlWriteDataPntr, #0            ; Initilize the data pointer for future control write
                                                 ; data stages.
        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.
        sjmp    GoodCommand

ReservedCommand:

        orl     EPCON,  #0C0h                    ; Stall EP0.
        ret


                                                 ; THis code will branch to the correct jump statement
                                                 ; in the bmRequestJumpTable below.
GoodCommand:                                     ; Code added to convert AJMP table to LJMP table.
        anl     A, #3Eh                          ; Multiply SJMP offset by 3/2 to get LJMP offsett.
        mov     B, A                             ; Save the original
        rr      A                                ; Divide origianl by two
        anl     A, #1fH                          ;
        clr     CY                               ;
        ADD     A, B                             ; 2/2 + 1/2 = 3/2

        mov     DPTR,   #bmRequestJumpTable
        mov     DPXL,   #LOW HIGH16(GoodCommand) ; Get Page of Jump Table.
                                                 ; Is this code in RAM or ROM?
                                                 ; Low byte of the upper 16 bits of the 32 bit address of the
                                                 ; jump table.
                                                 ; Used because I use RISM sometimes
                                                 ; which places code in RAM
        jmp     @A+DPTR

;---------------------------------------
;-- 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 LJMP to AJMP as the algorytm depends on the
;-- 3 byte length of LJMP.  AJMP is 2 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

⌨️ 快捷键说明

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