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

📄 usbmain.asm

📁 CY7C63743 usb键盘的源码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;
;
USB_EP0_ISR:
	push	A							; save accumulator on stack
    mov     A,[0f8h]                    ; get fifo 1st byte
    mov     [EP0_fifo_shadow],A         ; save it
    iord    EP_A0_Counter
    mov     [EP_A0_counter_shadow],A
    iord	EP_A0_Mode					;  
    mov     [EP0_mode_shadow],A                ; save mode
    and     A,ACK_BIT                   ; if nothing was ACKed
    jz      .exit                       ; get out now
    disable_EP0_int                     ; prevent further interrupts while we process this one
    mov     A,1                         ; flag that we need to do something
    mov     [EP0_FLAG],A
.exit:
    pop     A
    reti

;========================================================================
;       EP0 -- handle a request that came in on EP0.
;
;The EP0 ISR, in combination with the automatic mode switching of the SIE,
;allows the processing of EP0 traffic to take place in the main loop in a 
;non time-critical fashion. By the time the code has reached this point,
;the incoming EP0 event has been recorded by the ISR and must be parsed here.
;       
;========================================================================

EP0:
.start:
    mov     A,[EP0_mode_shadow]                    ;get the copy of the mode register
    and     A, EP0_SETUP_RCV                ;if a setup was received
    jz      .out
    call    EP0_setup                       ; handle it
    jmp     .exit                           ; and exit
.out:
    mov     A,[EP0_mode_shadow]                    ;if an out was received
    and     A, EP0_OUT_RCV
    jz      .in
    call    EP0_out                         ; handle it
    jmp     .exit                           ; and exit
.in:
    mov     A,[EP0_mode_shadow]                    ;if an in was received
    and     A,EP0_IN_RCV
    jz      .exit
    call    EP0_in                          ; handle it
.exit:
    iord    EP_A0_Mode                      ; get mode reg
    and     A,EP0_SETUP_RCV                 ; if setup bit is set
    jz      .exit1
    enable_EP0_int                          ;get out now
    ret
.exit1:
    di                                      ; 
    mov     A,[EP0_Next_Mode]               ;write the next mode
    iowr    EP_A0_Mode                      ;
    enable_EP0_int                          ;re-enable interrupts
    ei                                      ;
    ret                                     ;and return



;========================================================================
;       EP0_setup handles the setup stage of a transaction
;
;========================================================================


EP0_setup:
    mov     A,NAKINOUT
    iowr    EP_A0_Mode
     iord	EP_A0_Counter				; check if data is valid
	and		A, DATAVALID
	jz		stall_in_out				; otherwise STALL IN/OUT
	iord	EP_A0_Counter				; make sure we received 10 data bytes
	and		A, COUNT_MASK				; (8 data bytes + 2 CRC bytes)
	cmp		A, 0Ah
	jnz		stall_in_out				; otherwise STALL IN/OUT
	iord	EP_A0_Counter				; check if data toggle is 0
	and		A, DATATOGGLE
	jnz		stall_in_out				; otherwise STALL IN/OUT
    call	StageOne					; parse SETUP packet
    ret 

;========================================================================
;       EP0_out handles the out stage of a transaction
;
;========================================================================

EP0_out:                                
;in the case of the keyboard,an ACKed out occurs either in the case of
;the status phase of a control read, or the data out phase of a control write.
   

   mov     A,[EP0_mode_shadow]                 ;get contents of mode
    and     A,USB_MODE_MASK
    cmp     A,NAKOUTSTATUSIN            ;if we've just acked an out
    jnz     stall_in_out
    call    Control_write               ;go process it
    ret


;========================================================================
;       EP0_in handles the in stage of a transaction
;
;========================================================================


EP0_in:
;an ACKed IN occurs either in the case of the status phase of a control write,
;or the data in phase of a control read.

    mov     A,[EP0_mode_shadow]
    and     A,USB_MODE_MASK
    cmp     A,NAKIN_STATUSOUT               ;this indicates we've acked an in
    jnz      stall_in_out
    call    next_control_read               ;so prepare for the next one
    ret

stall_in_out:							; accept SETUP, stall IN/OUT
	call	SendStall
    ret



;========================================================================
;       look for valid combinations of bmRequestType and bRequest.
;       all of the interesting combinations are in the table bRequest_table,
;		represented as 2-byte quantities
;       
;========================================================================


StageOne:
	mov X,bRequest_table_len			;initialize X to size of table
.loop:
	dec X								;decrement by 2 to point to entry
	jc SendStall						;if result is minus, we didn't find an entry
	dec X
	mov	A,X								;move index to A
	index bRequest_table				;get table entry and compare with bmRequestType
	cmp A,[bmRequestType]
	jnz	.loop							;no match, try next entry
	mov	A,X								;now get next table entry and compare with bRequest
	index bRequest_table+1
	cmp A,[bRequest]
	jnz .loop							;no match, try next entry
.found:
	mov A,X								;X contains entry into jump table
	jacc jmp_tbl


; 
XPAGEOFF
jmp_tbl:
    jmp ClearRemoteWakeup 
    jmp SetRemoteWakeup
	jmp SetAddress
	jmp SetConfiguration

	jmp SetInterface

    jmp ClearEndpointStall
    jmp SetEndpointStall

    jmp GetDeviceStatus
	jmp GetDescriptor
	jmp GetConfiguration
	jmp GetInterface

    jmp GetInterfaceStatus
    jmp GetInterfaceStatus
    jmp GetDescriptor
	jmp GetInterface

    jmp GetEndpointStatus
	jmp GetDescriptor
	jmp GetInterface

	jmp SetReport
    jmp SetIdle
    jmp SetProtocol

	jmp SetReport
    jmp SetIdle
    jmp SetProtocol

    jmp GetReport
    jmp GetIdle
    jmp GetProtocol
;the following table contains valid pairs of bmRequestType and bRequest.
;The offset into the table matches the offset into the above jump table
bRequest_table:
db 00,01,00,03,00,05,00,09		;clear remote wkp,set remote wkp,set address,set config
db 01,11						;set interface
db 02,01,02,03					;clear endpoint stall, set endpoint stall
db 80h,00,80h,06,80h,08,80h,10	;get device status, descriptor, configuration ,interface
db 81h,00,81h,01,81h,06,81h,10	;get interface status,get interface status, descriptor,get interface
db 82h,00,82h,06,82h,10			;get endpoint status, descriptor,get interface
db 21h,09,21h,10,21h,11			;set report,set idle, set protocol
db 22h,09,22h,10,22h,11			;set report,set idle, set protocol
db A1h,01,A1h,02,A1h,03			;get report,get idle, get protocol
end_bRequest_table:
bRequest_table_len: EQU (end_bRequest_table - bRequest_table)
XPAGEON
;-----------------------------------------------------------------------
; Stall unsupported functions
;-----------------------------------------------------------------------
SendStall:			      ; stall unsupported functions
	  mov A, STALL
      mov [EP0_Next_Mode],A
	  ret

;========================================================================
;       stage three ... process the request
;========================================================================
; Remote wakeup is the ability to wakeup a system from power down mode
; when the user presses a key.    These routines
; allow the host to enable/disable the ability to request remote wakeup.
;
; Disable the remote wakeup capability.
ClearRemoteWakeup:
    mov     A,[wValueHi]
    cmp     A,0
    jnz     SendStall
	mov		A, [wValue]						; load wValue
	cmp		A, device_remote_wakeup			; test for valid feature
	jnz		SendStall						; stall unsupported features
	mov		A, DISABLE_REMOTE_WAKEUP		; disable remote wakeup
	mov		[remote_wakeup_status], A
	call	no_data_control					; handshake with host
	ret										; return

; Enable the remote wakeup capability.
SetRemoteWakeup:
	mov		A, [wValue]						; load wValue
	cmp		A, device_remote_wakeup			; test for valid feature
	jnz		SendStall						; stall unsupported features
	mov		A, ENABLE_REMOTE_WAKEUP			; enable remote wakeup
	mov		[remote_wakeup_status], A
	call	no_data_control					; handshake with host
	ret										; return

; Set the device address to the wValue in the SETUP packet at
; the completion of the current transaction.
SetAddress:
	call	no_data_control_wait			; handshake with host
	iord	EP_A0_Mode						; read mode register
    and		A, EP0_SETUP_RCV				; did we receive premature SETUP?
    jnz     done_SetAddress                 ; yes, abort the set address
	mov		A, [wValue]						; load wValue 
	or		A, ADDRESS_ENABLE_BIT			; enable USB address
	iowr	USB_Device_Address				; write new USB device address

done_SetAddress:
	ret										; return

; Set the configuration of the device to either unconfigured (0) or
; configured (1) based on wValue in the SETUP packet.  According to
; the USB spec (page 178), a Set Configuration also clears the endpoint
; stall condition and re-initializes endpoints using data 0/1 toggle to
; Data0.
SetConfiguration:
    mov     A,[wValueHi]
    cmp     A,0
    jnz     SendStall
	mov		A, [wValue]						; load wValue lsb
	cmp		A, UNCONFIGURED					; the only config. values that are 
	jnz		check_value_is_configured		; valid are 0 and 1
	jmp		set_config_value
check_value_is_configured:
	cmp		A, CONFIGURED
	jnz		SendStall

set_config_value:
 	mov		[configuration_status], A		; store configuration byte

	mov		A, 0
	mov		[ep1_stall_status], A		    ; not stalled
	mov		[ep2_stall_status], A		    ; not stalled
	iord	EP_A1_Counter					; clear data 0/1 bit for EP1
	and		A, ~DATATOGGLE
	iowr	EP_A1_Counter 

 	iord	EP_A2_Counter					; clear data 0/1 bit for EP2
	and		A, ~DATATOGGLE
	iowr	EP_A2_Counter 

	mov		A, [configuration_status]
	cmp		A, UNCONFIGURED
	jnz		device_configured

; device is unconfigured
	mov		A, DISABLED						; Disable endpoint 1 and 2
	iowr	EP_A1_Mode 
	iowr	EP_A2_Mode                 
                
	mov		A, ENUMERATE    				; disable endpoint interrupts
	iowr	Endpoint_Interrupt
    mov     A,(CAPS_LOCK_LED + NUM_LOCK_LED + SCROLL_LOCK_LED)
    call    ksc_writeLED
	jmp		done_SetConfiguration

; device is configured
device_configured:
	mov		A, NAKIN						; NAK IN packets until data is
	iowr	EP_A1_Mode						; ready on endpoint one and two
	iowr	EP_A2_Mode                 

	mov		A, EP0_EP1_EP2					; enable endpoint one and two interrupts
	iowr	Endpoint_Interrupt
    mov     A,0
    call    ksc_writeLED

done_SetConfiguration:
	call	 no_data_control				; handshake with host
	ret                                     ; return

; Clear the endpoint stall feature for the selected endpoint.  This
; should also set the data 0/1 bit to Data0 if endpoint one is selected.
ClearEndpointStall:
    mov		A, [configuration_status]
	cmp		A, UNCONFIGURED
    jz      SendStall
    mov		A, [wValue]						; load wValue (which feature)
    cmp		A, endpoint_stall				; test for valid feature
    jnz		SendStall						; stall unsupported features
; clear endpoint stall feature
    mov     A,[wIndexHi]
    cmp     A,0
    jnz     SendStall
    mov     A,[wIndex]
    cmp     A,81h
    jz      .clear1
    cmp     A,82h
    jnz     SendStall
	mov		A,0         
	mov		[ep2_stall_status], A		    ; not stalled
	iord	EP_A2_Counter					; clear data 0/1 bit for EP2
	and		A, ~DATATOGGLE
	iowr	EP_A2_Counter 
	mov		A, NAKIN						; NAK IN packets until data is
	iowr	EP_A2_Mode						; ready on endpoint two
    jmp     .done
.clear1:
    mov     A,0
	mov		[ep1_stall_status], A		    ; not stalled
	iord	EP_A1_Counter					; clear data 0/1 bit for EP1
	and		A, ~DATATOGGLE
	iowr	EP_A1_Counter 
	mov		A, NAKIN						; NAK IN packets until data is
	iowr	EP_A1_Mode						; ready on endpoint one
.done:
	call	no_data_control					; handshake with host
	ret										; return
; host may attempt to set the interface to an alternate setting. We do not
; support any alternate setting, but if the alternate setting number is 0
; then we should not stall that request
SetInterface:
    call    Interface0
    jz      .set
    call    Interface1
    jnz     SendStall
.set:
	mov		A, [wValue]						; which alternate setting is requested?
    or      A, [wValueHi]
	jnz		SendStall						; if host requested alternate setting 0
	iord	EP_A1_Counter					; clear data 0/1 bit for EP1
	and		A, ~DATATOGGLE
	iowr	EP_A1_Counter 

 	iord	EP_A2_Counter					; clear data 0/1 bit for EP2
	and		A, ~DATATOGGLE
	iowr	EP_A2_Counter 

⌨️ 快捷键说明

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