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

📄 usbmain.asm

📁 CY7C63743 usb键盘的源码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;========================================================================
; This is the Cypress USB Keyboard + PS2 Mouse demonstration firmware.  
; It supports the following features:
;       - Ch. 9 and HIDView compliance
;       - String Descriptors
;       - Suspend / Resume / Remote Wakeup
;       - Send keys on change
;       - N-Key rollover
;       - Debounce
;       - Phantom keys
;       - Boot protocol
;       - Plug and Play PS/2 Mouse Port
;
;REVISIONS:
;08/17/99 bth rewrote endpoint 0 ISR
;02/02/99
;	     bth added set idle, get idle for mouse/power keys
;            added boot protocol switching on 2nd endpoint (mouse/power)
;            added get_report for mouse and power key packets
;            altered mechanism for maintaining idle period
;            by removing it from ISR and placing it in SendKeyboardReport
;11/09/98  bth added power management support
		CPU 63413
;label:	XPAGEON

		       
;========================================================================
; data variable assignments
;========================================================================

; control endpoint 0 fifo
endpoint_0:             equ  F8h	; control endpoint

; definitions for SETUP packets
bmRequestType:          equ  F8h
bRequest:               equ  F9h
wValue:                 equ  FAh    ; default wValue (8-bits)
wValueHi:               equ  FBh
wIndex:                 equ  FCh    ; default wIndex (8-bits)
wIndexHi:               equ  FDh
wLength:                equ  FEh    ; default wLength (8-bits)
wLengthHi:              equ  FFh

; definition for OUT packets
outbyte:				equ  F8h	

; interrupt endpoint 1 fifo
endpoint_1:				equ  F0h	; keyboard endpoint
modifiers:				equ  F0h

; interrupt endpoint 2 fifo
endpoint_2:				equ  E8h	; power/media keys endpoint

datastack_start:		equ  E0h	; start of data stack

; data memory variables
;------------------------------------------------------------------------
; To support the USB specification.
remote_wakeup_status:   equ  usbmain_ram_base 
															; remote wakeup request
															; zero is disabled
															; two is enabled
configuration_status:	equ  (usbmain_ram_base+1)
															; configuration status
															; zero is unconfigured
															; one is configured
ep1_stall_status:		equ  (usbmain_ram_base+2)			    ; zero is not stalled
ep2_stall_status:		equ  (usbmain_ram_base+3)															; one is stalled

protocol_status:		equ  (usbmain_ram_base+4)			; zero is boot protocol
							; one is report protocol
; support SetIdle and GetIdle
kbd_idle_period:		equ  (usbmain_ram_base+5)			; keyboard idle period
kbd_idle_period_ctr:	equ  (usbmain_ram_base+6)			; keyboard idle period
mouse_idle_period:      equ  (usbmain_ram_base+7)                ; mouse idle period
mouse_idle_period_ctr:  equ  (usbmain_ram_base+8)                ; mouse idle period
consumer_idle_period:	equ  (usbmain_ram_base+9)			; consumer keys idle period
consumer_idle_period_ctr:equ  (usbmain_ram_base+10)			; consumer keys idle period
power_idle_period:		equ  (usbmain_ram_base+11)			; power idle period
power_idle_period_ctr:  equ  (usbmain_ram_base+12)			; power idle period

1ms_counter:            equ  (usbmain_ram_base+13)			; 4ms counter
data_start:             equ  (usbmain_ram_base+14)			; points to start of descriptor
data_count:             equ  (usbmain_ram_base+15)			; current length of descriptor
byte_count:             equ  (usbmain_ram_base+16)			; current size of transmission
temp:                   equ  (usbmain_ram_base+17)

;--------------------------------------------------------------------------
suspend_counter:        equ  (usbmain_ram_base+18)			; contains number of idle bus msecs


;------------------------------------------------------------------------
; application support
;------------------------------------------------------------------------


page:					equ  (usbmain_ram_base+19)			; page location of descriptor(RAM,
															; ROM page 1, ROM page 2
EP0_mode_shadow:        equ  (usbmain_ram_base+20)			; variable to store ep0 mode
															; used by set_ep0_mode

ps2_tmp:				equ  (usbmain_ram_base+21)			; temporary variable for port 3 write by PS/2
background_flags:		equ  (usbmain_ram_base+22) 			; signal flags for background 
usb_leds:	            equ  (usbmain_ram_base+23) 			; overcurrent debounce counter
last_key_report:        equ  (usbmain_ram_base+24)
EP0_fifo_shadow:        equ  (usbmain_ram_base+25)
EP_A0_counter_shadow:   equ  (usbmain_ram_base+26)
EP0_Next_Mode:          equ  (usbmain_ram_base+27)
EP0_FLAG:               equ  (usbmain_ram_base+28)
USBMAIN_RAM_SIZE:		equ  29
 
SUSPEND_FLAG:			        equ 1
SCAN_FLAG:				        equ 2
;========================================================================
;			program listing
;======================================================================== 


;========================================================================
; The 128 uSec interrupt is not used by the keyboard code.  The keyboard
; only does not require the DAC or GPIO port in this version of
; firmware.  It may be necessary to enable GPIO interrupts when the
; keyboard enters a power down suspend mode.
DoNothing_ISR:
        reti			; return from interrupt

;========================================================================
; Suspend
;
; This routine is invoked from the main loop when bus activity has ceased for
; 3 msec or more. This routine prepares the keyboard for suspension, suspends
; the part, and restores the keyboard upon a subsequent resume.
;========================================================================
; Suspend
;
; This routine is invoked from the main loop when bus activity has ceased for
; 3 msec or more. This routine prepares the keyboard for suspension, suspends
; the part, and restores the keyboard upon a subsequent resume.

Suspend:

	push A
						; (since all pins are guaranteed to not float)

	call mouse_suspend		; put PS/2 mouse in stream mode
	di					; disable interrupts
	mov A, RESISTIVE_NEG          ; all ports resistive neg so that
	iowr GPIO_Config              ; we stay within suspend current budget (500uA)
	mov A, 0                      ; pull down the column lines
	iowr Port0_Data
	iowr Port1_Data
	mov A, [ksc_p3out]
	or A, P3_LED_MASK             ; turn LEDs off
	and A, ~P3_KEY_MASK		; don't touch bit 6 & 7 (PS/2 mouse interface)
	iowr Port3_Data                 
	mov A, FFh
	iowr Port2_Interrupt		; enable port 2 GPIO interrupt for keyboard
	mov A, GPIO_ONLY_MASK         ; enable GPIO interrupt only
	iowr Global_Interrupt
	mov A, [remote_wakeup_status] ; is remote wakeup feature enabled?
	cmp A, ENABLE_REMOTE_WAKEUP
	jnz  Suspend_controller
	ei
Suspend_controller:

	iord Status_Control           ; set the suspend bit causing suspend
	or A, 08h
	iowr Status_Control           ; we are suspended here

; resume !!!!!!                                 
	nop                           ; execute a nop after resuming
    
	di
    iowr Watchdog
	iord USB_Status_Control		; check if there is no bus activity
	and A, 08h
	cmp A, 00h
	jnz GPIO_disable_interrupts   ; if there is bus activity, 
						; disable interrupts and exit


	mov A, TIMER_ONLY_MASK		; enable 1ms interrupt
	iowr Global_Interrupt
	ei
	mov A, [1ms_counter]		; clear wakeup counter
	add A,5

wakeup_delay:				; wait 5ms before we send the wakeup signal
    iowr Watchdog
	cmp A, [1ms_counter]
	jnz wakeup_delay

	di					; disable interrupts

	iord USB_Status_Control		; check again if there is no bus activity
	and A, 08h				; after 5ms
	cmp A, 00h
	jnz GPIO_disable_interrupts   ; if there is bus activity, 
						; disable interrupts and exit


	mov A, FORCE_J                ; force J state to correct cross-over voltage
	iowr USB_Status_Control       ; problem during resume signalling

	mov A, FORCE_K			; start sending resume signal
	iowr USB_Status_Control

	ei					; enable 1ms interrupt again
	mov A, [1ms_counter]		; clear wakeup counter
    add A,0ah

wakeup_duration:				; send resume signal for 10ms
    iowr Watchdog
	cmp A, [1ms_counter]
	jnz wakeup_duration

	di					; disable interrupts

	mov A, NOT_FORCING		; let SIE control D+/D-
	iowr USB_Status_Control		


GPIO_disable_interrupts:		;
						;interrupts are off when we get here
	iord USB_Status_Control
	and A, F7h				; clear Bus Activity bit
	iowr USB_Status_Control

	mov A, 0
	iowr Port2_Interrupt		; disable GPIO interrupt for keyboard

	mov A, GPIO_TIMER_RESET_MASK  ; enable GPIO and 1ms interrupts
	iowr Global_Interrupt


	ei
	call mouse_resume			; put PS/2 mouse into polling mode
	di  
Skip_suspend:
	mov A, NORMAL                 ; restore original GPIO configuration
	iowr GPIO_Config                        
      mov A,0
      mov [suspend_counter],A
	call ksc_restore_ports            ; restore column ports to pre-suspend values
    ei
    pop A
    ret



check_activity:

	iord    USB_Status_Control		    ; check if there is  bus activity
	and     A, 08h
    ret

;========================================================================
; The 1 msec interrupt is used to clear the watchdog timer, to maintain
; all timers with a 1msec granularity
;========================================================================

One_mSec_ISR:
    inc		[1ms_counter]				    ;increment 1msec timer
    mov		A,[1ms_counter]
    and		A,3                         
    
    jnz		check_bus_activity_status	    ;every 4 msec, do the following:

    mov		A,[background_flags]		    ; set the flag to scan the keyboard
    or		A,SCAN_FLAG
    mov		[background_flags],A

check_bus_activity_status:
	iord	USB_Status_Control				; check if there is no bus activity
	and		A, 08h
	cmp		A,0h
	jz		Inc_counter						; if there was bus activity
	iord	USB_Status_Control				;   clear the bus activity bit
	and		A, 0F7h
	iowr	USB_Status_Control
	mov		A, 0h							;   clear the suspend counter
	mov		[suspend_counter], A			;   
	jmp		Exit_1ms

Inc_counter:								;there was no bus activity,
    inc		[suspend_counter]				;so increment the bus activity counter
	mov		A,[suspend_counter]
	cmp		A, 03h							;if 3msecs of bus inactivity passed
    jc		Exit_1ms
    mov		A,[background_flags]			; set the suspend flag
    or		A,SUSPEND_FLAG
    mov		[background_flags],A			;


Exit_1ms:
    call mouse_1mS_int				; call the mouse 1msec ISR code.
	pop A
	reti                   			; return from interrupt
;========================================================================
; Endpoint one is used to send keyboard data to the host.  This interrupt
; occurs if the USB serial interface engine has transferred a packet
; to the host (including NAKs).
;
; This routine disables another transfer until valid data has been loaded
; into the endpoint.  This routine is also responsible for toggling the
; data 0/1 bit for endpoint one after every successful transfer.
USB_EP1_ISR:
	push	A		  				; save accumulator on stack
	iord	EP_A1_Mode	  			; test whether we have an ACK bit
	and		A, ACK_BIT
	jz doneEP1						; do nothing if we don't have an ACK bit

	mov		A, NAKIN				; clear ACK bit
	iowr	EP_A1_Mode

	iord	EP_A1_Counter			; flip data 0/1 bit after
	xor		A, DATATOGGLE	        ; a successful data transfer
	iowr	EP_A1_Counter


doneEP1:
	pop		A						; restore accumulator from stack
	reti							; return from interrupt

;========================================================================
; Endpoint two is used to consumer/power key  data to the host.  This interrupt
; occurs if the USB serial interface engine has transferred a packet
; to the host (including NAKs).
;
; This routine disables another transfer until valid data has been loaded
; into the endpoint.  This routine is also responsible for toggling the
; data 0/1 bit for endpoint one after every successful transfer.
USB_EP2_ISR:
	push	A		  			; save accumulator on stack
	iord	EP_A2_Mode	  		; test whether we have an ACK bit
	and		A, ACK_BIT
	jz		doneEP2				; do nothing if we don't have an ACK bit

	mov		A, NAKIN			; clear ACK bit
	iowr	EP_A2_Mode

	iord	EP_A2_Counter		; flip data 0/1 bit after
	xor		A, DATATOGGLE	    ; a successful data transfer
	iowr	EP_A2_Counter

doneEP2:
	pop		A					; restore accumulator from stack
	reti						; return from interrupt

;========================================================================
; The DAC interrupt is unused

DAC_ISR:
    reti							; return from interrupt
;========================================================================
; The GPIO interrupt normally occurs as a result of the mouse clock transitioning.
; This happens during normal operation.
;
;
; GPIO interrupts can also occur if the keyboard is in suspend and a key is pressed
; or the mouse is moved. In this case, this GPIO interrupt will wake up the keyboard
; and control will return to the code executing just after the suspend bit was set.
; Note that this routine calls mouse_int, even if the keyboard might have generated
; the interrupt.  This is OK because mouse_int is internally protected from doing
; anything rash during a suspend operation. So, rather than incur overhead to determine
; if the keyboard is the source of an interrupt during suspend, we let the call
; to mouse_int go through anyway.
GPIO_ISR:
    ei                      ;allow nesting
	iowr Watchdog			; clear Watchdog timer

    call mouse_int			;call mouse interrupt stuff
    reti

;========================================================================

⌨️ 快捷键说明

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