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

📄 637mouse.asm

📁 这是使用CYPRESS的7C637xx芯片完成USB鼠标的例子。
💻 ASM
📖 第 1 页 / 共 5 页
字号:

ps2Error:
    halt
    jmp    ps2Error

;********************************************************************
;
;    Interrupt handler: dualMain
;    Purpose: The program jumps to this routine when the microcontroller
;    has a power on reset.
;
;********************************************************************
dualMain:
    ;
    ; General Setup
    ;

    di                                  ; disable interrupts

    mov    A, DUAL_DSP_DATA             ; set DSP stack pointer
    swap   A, DSP                       ;

    mov    A, 00h                       ; set up program stack pointer            
    mov    psp, A                       ;

    ;
    ; clear dual interface variables
    ;
    mov    [delayCounter], A
    mov    [dualInterface1ms], A

    ;
    ; Initialize button/optics variables
    ;
    mov    [debounceCount], A
    mov    [xCount], A
    mov    [yCount], A
    mov    [zCount], A
    mov    [buttonValue], A
    mov    [buttonMachine], A
    mov    [lastHorzState], A
    mov    [lastVertState], A
    mov    [lastZstate], A
    mov    [eventMachine], A

    mov    A, (LEFT_BUTTON_MASK | RIGHT_BUTTON_MASK | MIDDLE_BUTTON_MASK)
    mov    [currentButtonState], A
    mov    [lastButtonState], A

    mov    A, PS2_MOUSE                 ; default is PS2 interface
    mov    [dualInterfaceMouse], A      ;

    mov    A, FORCE_HIZ                 ; set D+, D- to HI-Z
    iowr   USB_STATUS_CONTROL_REG       ;

    ;
    ; Set buttons in resistive/CMOS, LED in medium sink/CMOS 
    ; and optics in HI-Z/CMOS
    ;

    mov    A, PORT0_NORMAL
    iowr   PORT0
    mov    A, PORT0_MODE1_NORMAL
    iowr   PORT0_MODE1
    mov    A, PORT0_MODE0_NORMAL
    iowr   PORT0_MODE0

    mov    A, PORT1_NORMAL
    iowr   PORT1
    mov    A, PORT1_MODE1_NORMAL
    iowr   PORT1_MODE1       
    mov    A, PORT1_MODE0_NORMAL
    iowr   PORT1_MODE0       
     
    ;
    ; set up interrupts
    ;
    mov    A, 00h                       ; clear all endpoint interrupts
    iowr   ENDPOINT_INT                 ;

    mov    A, 1MS_INT                   ; enable 1 ms interrupt
    iowr   GLOBAL_INTERRUPT_REG         ; 

    ei                                  ; enable interrupts

    call   getMouseType                 ; get mouse type in (A)
    mov    [dualInterfaceMouse], A      ; and save it for later use

    cmp    A, USB_MOUSE
    jz     usbMain                      ; go if USB interface
    jmp    ps2Main                      ; go if PS/2 interface

;********************************************************************
;
;         Main Entry for PS/2 Interface
;
;********************************************************************
ps2Main:
    di                                     ; disable interrupts

    ;
    ; Initialize PS2 Variables
    ;
    mov    A, 00h
    mov    [ps2Temp0], A
    mov    [ps2LastValidCmd], A
    mov    [ps2XmitBufferLen], A
    mov    [ps2XmitLen], A
    mov    A, 10                        ; set for 10 reports/sec
    mov    [ps2IntervalCount], A        ;
    call   ps2SetDefault                ; set default parameters

    ei                                  ; enable interrupts
    call   ps2BAT                       ; load BAT code onto transmit
                                        ; buffer (AAh followed by 00h)

;********************************************************************
;
;         Main PS/2 Task Loop
;
;********************************************************************
ps2TaskLoop:
    iowr   WATCHDOG_REG                 ; clear watchdog timer
    call   processButtons               ; determine button value
    call   readProcessOptics            ; compute (x,y,z) of optics
    call   ps2GetHostByte               ; get data from host, if any,
                                        ; but does not save it in buffer
    jnc    doCommand                    ; go & process data received from host
    
    ;
    ; At here, we either have an error in receiving data or 
    ; host does not send any data
    ;
    mov    A, [ps2XmitLen]              ; get remaining bytes to be sent to host
    cmp    A, 00h
    jz     mouseTask                    ; go if no byte to send
    call   ps2SendNextByte              ; send next remaining byte to host
                                        ; from xmit buffer
    jmp    ps2TaskLoop                  ; go back for next transaction

mouseTask:
    dec    [ps2IntervalCount]
    mov    A, [ps2IntervalCount]
    cmp    A, 00h
    jnz    ps2TaskLoop                  ; go if report interval not expired

    call   ps2ResetMouseReportInterval
    mov    A, [ps2StreamMode]
    cmp    A, 01h
    jnz    ps2TaskLoop                  ; go if not in stream mode

    mov    A, [ps2MouseEnabled]
    cmp    A, 01h
    jnz    ps2TaskLoop                  ; go if mouse not enabled

    ;
    ; At here, stream mode is on, mouse is enabled and report interval
    ; has expired
    ;

    call   loadMousePacket              ; load mouse packet into xmit buffer
    jmp    ps2TaskLoop                  ; ready to send packet out

doCommand:
    call   ps2DoCommand                 ; process host commands
    jmp    ps2TaskLoop                  ; next transaction


;********************************************************************
;
;         Processing of Host PS2 Commands 
;
;********************************************************************
    ORG    100h

;========================================================================
; FUNCTION: ps2DoCommand
;
;    Decodes commands and process them thru appropriate functions defined
; in the dispatch table below.
;
;    On Entry: (A) = command byte received from host
;
;========================================================================

    XPAGEOFF

ps2CmdTable:                            ; dispatch table for ps2 host commands
    jmp    ps2ResetScaling              ; (command byte = 0E6h)
    jmp    ps2SetScaling2_1             ; (0E7h)
    jmp    ps2SetResolution             ; (0E8h)
    jmp    ps2StatusRequest             ; (0E9h)
    jmp    ps2SetStreamMode             ; (0EAh)
    jmp    ps2ReadData                  ; (0EBh)
    jmp    ps2ResetWrapMode             ; (0ECh)
    jmp    ps2DoCmdError                ; Not defined
    jmp    ps2SetWrapMode               ; (0EEh)
    jmp    ps2DoCmdError                ; Not defined
    jmp    ps2SetRemoteMode             ; (0F0h)
    jmp    ps2DoCmdError                ; Not defined
    jmp    ps2ReadDeviceType            ; (0F2h)
    jmp    ps2SetSampleRate             ; (0F3h)
    jmp    ps2EnableMouse               ; (0F4h)
    jmp    ps2DisableMouse              ; (0F5h)
    jmp    ps2SetDefault                ; (0F6h)
    jmp    ps2DoCmdError                ; Not defined (0F7h)
    jmp    ps2DoCmdError                ; Not defined (0F8h)
    jmp    ps2DoCmdError                ; Not defined (0F9h)
    jmp    ps2DoCmdError                ; Not defined (0FAh)
    jmp    ps2DoCmdError                ; Not defined (0FBh)
    jmp    ps2DoCmdError                ; Not defined (0FCh)
    jmp    ps2DoCmdError                ; Not defined (0FDh)
    jmp    ps2Resend                    ; (0FEh)
    jmp    ps2Reset                     ; (0FFh)

    XPAGEON

ps2DoCommand:
    mov    [saveCmd], A                 ; save command byte for later use
    mov    A, [ps2WrapMode]
    cmp    A, 01h
    jnz    checkLastValidCmd            ; go if not in echo mode

    mov    A, 00h                       ; clear last valid command
    mov    [ps2LastValidCmd], A         ; 
    mov    A, [saveCmd]                 ; get host command/data byte back
    cmp    A, PS2_RESET_CMD    
    jz     checkLastValidCmd            ; "reset" gets us out of echo mode
    cmp    A, PS2_RESET_WRAP_MODE_CMD
    jz     checkLastValidCmd            ; "reset wrap" gets us out of echo mode
    call   ps2SendResponseByte          ; echo byte in (A) back to host
    jmp    doCmdExit                    ; exit

    ;
    ; Check for commands that have 2 bytes, namely, ps2SetSampleRate
    ; and ps2SetResolution
    ;

checkLastValidCmd:
    mov    A, [ps2LastValidCmd]
    cmp    A, PS2_SET_SAMPLE_RATE_CMD   ; is last command set sample rate?
    jnz    doCmd1                       ; no, go and continue

    mov    A, [saveCmd]                 ; get back sample rate
    call   ps2SetSampleRate             ; and set it

    ;
    ; on exit from ps2SetSampleRate:
    ;    (A) = PS2_ACK if the rate is valid
    ;     Else, (A) = PS2_RESEND 
    ;

    cmp    A, PS2_ACK
    jnz    ps2DoCmdError                ; go if sample rate setting has error

    mov    A, PS2_ACK                   ; send back ACK byte as required
    call   ps2SendResponseByte          ; by PS/2 protocol

    mov    A, 00h                       ; clear the error count
    mov    [ps2InvalidCmdCount], A      ;
    mov    [ps2LastValidCmd], A         ; reset last valid command

    mov    A, [saveCmd]                 ; get back command byte (in this 
                                        ; case, command byte = sample rate)
    call    checkWheel                  ; check whether wheel has been enabled
    jmp    doCmdExit                    ; exit

doCmd1:
    mov    A, [ps2LastValidCmd]         ; get last valid command
    cmp    A, PS2_SET_RESOLUTION_CMD
    jnz    decodeCmd                    ; go if not SetResolution command
    mov    A, [saveCmd]                 ; else (A) = resolution factor
    call   ps2SetResolution             ; set it

    ;
    ; on exit from ps2SetResolution:
    ;    (A) = PS2_ACK if the resolution is valid
    ;     Else, (A) = PS2_RESEND 
    ;

    cmp    A, PS2_ACK
    jnz    ps2DoCmdError                ; go if set resolution failed

    mov    A, PS2_ACK                   ; send back ACK byte as required    
    call   ps2SendResponseByte          ; by PS/2 protocol

    mov    A, 00h                       ; reset variables for next transaction
    mov    [ps2InvalidCmdCount], A      ;
    mov    [ps2LastValidCmd], A         ;
    jmp    doCmdExit                    ; exit

decodeCmd:          
    mov    A, 00h                       ; abort transmission when receiving
    mov    [ps2XmitLen], A              ; a new command

    mov    A, [saveCmd]
    cmp    A, PS2_SET_SAMPLE_RATE_CMD
    jz    doCmd2

    mov    A, 00h                       ; reset count of consecutive sample
    mov    [sequence], A                ; rate settings - this is to keep
                                        ; track of wheel enabling 
doCmd2:
    mov    A, [saveCmd]
    sub    A, 0E6h                      ; adjust for base of command table
    jc     ps2DoCmdError                ; go if invalid command

validCommand:
    push   A
    mov    A, PS2_ACK                   ; send back ACK byte on receiving
    call   ps2SendResponseByte          ; host command (PS/2 protocol)

    mov    A, [saveCmd]                 ; update last valid command
    mov    [ps2LastValidCmd], A         ;
    mov    A, 00h                       ; reset counter for invalid command
    mov    [ps2InvalidCmdCount], A      ;
    pop    A

    asl    A                            ; get offset into table
    jacc    ps2CmdTable                 ; do the function
    halt                                ; should never get here    !!

ps2DoCmdError:
    inc    [ps2InvalidCmdCount]         ; keep track of invalid commands 
    mov    A, [ps2InvalidCmdCount]      ;
    cmp    A, 02h
    jnz    ps2DoCmdError1        
                    
    mov    A, PS2_ERROR                 ; return an "error" response to host
    call   ps2SendResponseByte          ; in case of 2 errors

    mov    A, 00h                       ; reinitialize variables
    mov    [ps2InvalidCmdCount], A      ;
    mov    [ps2LastValidCmd], A         ;
    ret

ps2DoCmdError1:
    mov    A, PS2_RESEND                ; go if one error - return a "resend"
    call   ps2SendResponseByte          ; response to host

doCmdExit:
    ret

;========================================================================
; FUNCTION: ps2ResetScaling
;    Sets scaling to 1-1
;
;========================================================================
ps2ResetScaling:
    mov    A, SCALE1_1
    mov    [ps2Scale], A
    ret

;========================================================================
; FUNCTION: ps2SetScaling2_1
;    Sets scaling to 2-1
;
;========================================================================
ps2SetScaling2_1:
    mov    A, SCALE2_1
    mov    [ps2Scale], A
    ret

;========================================================================
; FUNCTION: ps2SetResolution
;    Sets the resolution. Only 4 resolutions are supported
;
;    On Entry: (A) = resolution factor
;    On Exit: (A) = PS2_ACK if valid resolution factor. 
;             = PS2_RESEND if invalid resolution factor

⌨️ 快捷键说明

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