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

📄 ax_firm.asm

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

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





;-----------------------------------------------------------------
;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
;--------------------------------------------------------------------*

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
        sjmp    LoadBuffer

CheckConfigDescriptor:
        cjne    A,     #CONFIG_DESCR, CheckStringDescriptor

        ; ********************** GET DESCRIPTOR,  CONFIGURATION ************
        mov     gbFControlBufferLocation,   #LOW HIGH16(BEGIN_CONFIG_DESCRIPTOR_1)
        mov     gbFControlBufferLocation+1, #HIGH LOW16(BEGIN_CONFIG_DESCRIPTOR_1)
        mov     gbFControlBufferLocation+2, #LOW  LOW16(BEGIN_CONFIG_DESCRIPTOR_1)
        mov     A,  #LOW  (END_CONFIG_DESCRIPTOR_1 - BEGIN_CONFIG_DESCRIPTOR_1)
        mov     B,  #HIGH (END_CONFIG_DESCRIPTOR_1 - BEGIN_CONFIG_DESCRIPTOR_1)
        sjmp    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)
        sjmp    LoadBuffer



LoadBuffer:                                      ; Compare to see which is shorter.

⌨️ 快捷键说明

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