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

📄 kbm_task.asm

📁 Cypress 的(鼠标+键盘)复合设备汇编源程序
💻 ASM
字号:
;========================================================================
; MouseConnectTask
; This Task was invented to clean up and consolidate the code that deals
; with the plugging and unplugging of the mouse.  To facilitate matters,
; no attempt is made to "catch" the mouse's initial power-on string when
; it is plugged in.  Rather, the mouse is sent a reset command periodically
; and is determined to be connected if
; a valid power-up response is received.  Once determined to be connected, 
; the mouse state will
; move to "unconnected" if for some reason the mouse state machine loses
; contact with the mouse (as indicated by mouse_conx_flagC).
;
; note that the mouse's operation is driven by repeated calls to mouse_machine.
; In turn, mouse_machine depends upon the 1 msec ISR to detect if it is "stuck"
; due to a mouse being plugged/unplugged in the middle of a transaction.
; The 1 msec ISR will force mouse_machine back to the idle state if it detects
; no state transitions within the timeout period.
;
; To implement this idea, a state variable for the mouse connect state
; is maintained as follows
;
;
;  MOUSE_UNCONNECTED: in this state, the keyboard is powered up and has been reset
;  by the host.  The mouse interface is now available because the GPIO and
;  1msec interrupts are enabled.  In this state,
;  ps2_init and mouse_reset are invoked to initiate a reset command to the mouse.
;  The state is advanced to MOUSE_IN_RESET to indicate that a reset command has
;  been sent to the mouse, and a response is being awaited.
;
;  MOUSE_IN_RESET: in this state, the mouse has been issued a reset command.
;  The mouse can take up to 1 second to respond to this command.
;  The reset command can either result in a timeout, indicating that the
;  reset response was not properly received, or the response to the reset
;  command can be found in the mouse buffer.  If the response is valid,
;  the state is advanced to MOUSE_CONNECTED. If the response resulted in a
;  timeout or was improper, the mouse is assumed to be disconnected and
;  the state is returned to MOUSE_UNCONNECTED.
;
;  MOUSE_CONNECTED: in this state, the mouse is connected.  A call to
;  mouse_machine is made to update the status of the connect flag. 
;
;
;  REVISION HISTORY:    3/26/99 Fixed to send a mouse packet only on change
;                       02/9/99 Added 3D mouse support
;                       02/2/99 Added boot/report protocol packet switching
;                       11/9/98 Added report ID to endpoint 2 packet

;========================================================================
MOUSE_UNCONNECTED:	equ 0h
MOUSE_IN_RESET:		equ 1
MOUSE_CONNECTED:		equ 2

MouseConnectTask:
    push    A 
    mov     A,[mouse_connect_stateV]                            
    cmp     A,MOUSE_UNCONNECTED
    jnz     .in_reset
                                          ;if the state is unconnected, send a reset command
    call    ps2_init                                                                          
    call    mouse_reset                                                                       
    mov     A,MOUSE_IN_RESET                                                                  
    jmp     .nextstate                                                                        
.in_reset:                                                                                    
    cmp     A,MOUSE_IN_RESET             ;if we've issued a reset to the mouse                 
    jnz     .connected
    call    mouse_machine                ; call mouse_machine to process the reset com 
    jc      .mend                        ;if the state machine returns idle,
    CHKFLAG mouse_conx_flagC             ;if not connected
    jz      .unconnect                   ; go to unconnect state
    mov     A,[mouse_packetV]            ;if init string[0] <> aah
    cmp     A,0aah                      
    jnz      .unconnect                  ; go to unconnect state
    mov     A,[mouse_packetV+1]          ;if init string[1] <> 00h
    cmp     A,00h                       
    jnz      .unconnect                  ; go to unconnect state
    call    mouse_init                   ;mouse must be there, so init it and
    CHKFLAG mouse_conx_flagC             ;if not connected
    jz      .unconnect                   ; go to unconnect state
    mov     A,MOUSE_CONNECTED            ;go to connect state
    jmp     .nextstate
.connected:
    call    mouse_machine                ;call mouse machine to verify connection
    CHKFLAG mouse_conx_flagC             ;if we lost the connection
    jz      .unconnect                   ; go to unconnect state
    jmp     .mend
.unconnect:
    mov     A,MOUSE_UNCONNECTED
.nextstate:
    mov     [mouse_connect_stateV],A
.mend:
    pop     A
    ret


;========================================================================
;			MOUSE POLLING TASK
;========================================================================
MouseTask:
	
	push	A
    mov A,[mouse_connect_stateV]
    cmp A,MOUSE_CONNECTED
    jnz  MouseTask_end
	CHKFLAG	mouse_conx_flagC	; check to see if the mouse is there
	jz MouseTask_end			; because we may get here after a timeout
 
.idle1_period_check:
	mov	A, [mouse_idle_period_ctr]       ; if idle_period is zero, then we only send
	cmp	A, 0                             ; reports on change
	jz	.no_idle		  
    dec   A
    mov   [mouse_idle_period_ctr],A      ;  else decrement idle period
    jnz   .no_idle                       ;  exit if idle period not expired
.xmit:
    mov   A,[mouse_idle_period]          ;  reset idle period
    mov   [mouse_idle_period_ctr],A
    mov   A,1
    mov   [mouse_send_flagV],A	         ; indicate that we need to send a report

.no_idle:

    dec [mouse_poll_intervalV]           ;gear down mouse polling to every 6*4 = 24 msec
    jnc  .skip_poll

.poll:
    mov A,5
    mov [mouse_poll_intervalV],A
	call mouse_poll			            ; poll for data
.tw3:call mouse_machine		            ; wait for done
	jc .tw3

	CHKFLAG	mouse_conx_flagC	        ; check to see if the mouse is there
	jz MouseTask_end			        ; because we may get here after a timeout

.check_change:
	mov	A, [mouse_packetV]		        ; has 1st byte changed?
	cmp	A, [last_mouse_packetV]
	jnz	.change				
	mov	A, [mouse_packetV+1]		    ; x , y, or z bytes non-zero?
    or  A, [mouse_packetV+2]
	or	A, [mouse_packetV+3]		    ; (if this is only an x-y mouse, z byte is always zero)
	cmp	A, 0
	jz	.no_change	
.change:
    mov A,1
    mov [mouse_send_flagV],A            ; flag we need to send a packet
    mov A, [mouse_packetV]		        ; load first PS/2 data byte
    mov [last_mouse_packetV], A         ; save it for future comparison

.no_change:
.skip_poll:                             ;always check to see if we need to send
                                        ;data
    call SendMouseData		            ; send mouse data to host


MouseTask_end:
	pop	A
	ret
;========================================================================
; copy mouse data from buffer mouse_packetV to EP2 fifo and enable tx
;========================================================================
; The PS/2 mouse data packet consists of 3 bytes starting at mouse_packetV
; Byte 1: bit[0] = left button, bit[1] = right button
; Byte 2: X displacement
; Byte 3: Y displacement
; Note: positive Y values delivered by PS/2 mouse means moving toward to
;       the bottom, so its sign need to be changed before sending to host 
;
;***JK Check to see if the mouse is connected before we send anything

SendMouseData:
	push A				            ; save A as CHKFLAG destroys it
	mov		A,[mouse_send_flagV]		; if we need to send mouse data
	cmp		A,00					; 
    jz		SMD_Done               ; 

	iord EP_A2_Mode				    ; are we currently transmitting a report?
	and A, USB_MODE_MASK
	cmp A, ACKIN
	jz SMD_Done				        ; yes, then exit (so we don't mess up current xact)
    push  X
    mov   A,endpoint_2              ;point X at endpoint 2's buffer
    mov   X,A
    mov   A,[protocol_status]       ;if not boot protocol
    cmp   A,BOOT_PROTOCOL
    jz    .skipID
    mov   A,[mouse_idV]                       ;
    mov   [X+0],A		                ; load report ID first
    inc   X

.skipID:
    mov A, [mouse_packetV]		    ; load first PS/2 data byte
    and A, 07h			    	    ; mask out bit 3 to bit 7
    mov [X+0], A		            ; load button data to fifo
    mov A, [mouse_packetV+1]	    ; load x displacement to fifo
    mov [X+1], A
    mov A, [mouse_packetV+2]	    ; load y displacement to fifo
    cpl A					        ; invert the sign in 2's complement
    add A, 01h
    mov [X+2], A
    mov A,[mouse_packet_lenV]       ; check to see if we are xmitting 3d packets
    cmp A,MOUSE_3D_PACKET_LEN
    mov A,0
    jnz  .skipz                     ; no, zero the wheel displacement, else
    mov A, [mouse_packetV+3]	    ; load z displacement to fifo
    cpl A
    add A,1
.skipz:
	mov [X+3], A
    pop   X

	iord EP_A2_Counter		
	and A, DATATOGGLE       	    ; keep data toggle setting
    push A          
    mov   A,[protocol_status]       ;if not boot protocol
    cmp   A,BOOT_PROTOCOL
    pop A
    jz    .report
	or A, (MOUSE_REPORT_LEN)	    ; use report packet size
    jmp   .enable
.report:
	or A, (MOUSE_REPORT_LEN-2)		; else use boot packet size
.enable:
	iowr EP_A2_Counter
	mov A, ACKIN			        ; enable packet transmission 
	iowr EP_A2_Mode
    mov A,0
    mov [mouse_send_flagV],A        ;clear send flag
SMD_Done:
	pop A
	ret

⌨️ 快捷键说明

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