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

📄 kbd9.asm

📁 一个PS2键盘单片机, 使用Philips的接口+8051,写的不错,非常值得学习.
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	JB	EMB_CONFIG,EMB_HAD_CONFIG
EMB_GET_CONFIG_1:
	ACALL	WRITE_THREE_BYTE
	RET
EMB_HAD_CONFIG:
	MOV	I2C_BUFFER+3,#1
	AJMP	EMB_GET_CONFIG_1

;==================================================================
; 	Configure or unconfigure device
;==================================================================
EMB_SET_CONFIG: 			    ;9
	MOV	A,R4
	JZ	EMB_DISABLE_CONFIG
	CJNE	A,#1,NO_SUPPORT_REQ		;WRONG_SET_CONFIG
;-----
	SETB	EMB_CONFIG
;----
	MOV	I2C_BUFFER,#SET_EPOINT_EN	;enable interrupt endpoint
	MOV	I2C_BUFFER+1,#02h
	ACALL	WRITE_ONE_BYTE
;---
EMB_SET_CONFIG_1:
	ACALL	SEND_ZERO_PACKET
	RET
;----
EMB_DISABLE_CONFIG:
	CLR	EMB_CONFIG
	AJMP	EMB_SET_CONFIG_1

;=================================================================
; GET device/interface/endpoint STATUS
;=================================================================
EMB_GET_STATUS:
 	MOV	I2C_BUFFER,#WRITE_BUFFER
	MOV	I2C_BUFFER+1,#0
	MOV	I2C_BUFFER+2,#2
	MOV	I2C_BUFFER+3,#0
	MOV	I2C_BUFFER+4,#0

	MOV	A,R2				;Get bmReqTyp
	ANL	A,#00000011B
	JZ	EMB_GET_DVC_STATUS
	DEC	A
	JZ	EMB_GET_IF_STATUS
	DEC	A
	JZ	EMB_GET_EPT_STATUS
EMB_GET_WRONG_RECIPIENT:
	AJMP	NO_SUPPORT_REQ

EMB_GET_DVC_STATUS:
	MOV	A,EMB_STATUS
	ANL	A,#00000011B
	MOV	I2C_BUFFER+3,A		;STATUS OF SELF POWER AND REMOTE WAKEUP
EMB_GET_IF_STATUS:
EMB_EPT0_OUT:
EMB_EPT_UN_STALL:
	LCALL	WRITE_FOUR_BYTE		;WRITE FOUR BYTES TO D11
	RET

EMB_GET_EPT_STATUS:
	MOV	A,R5		     	;endpoint number
	JZ	EMB_EPT0_OUT 	;Ctrl OUT, SHOULD BE UN_STALL
	XRL	A,#080H
	JZ	EMB_EPT0_IN  	;Ctrl IN
	MOV	A,R5
	XRL	A,#081H
	JZ	EMB_EPT1_IN  	;Int IN
	AJMP	NO_SUPPORT_REQ

EMB_EPT0_IN:
	MOV	C,EMB_EPT0_IN_STALL
RTN_EP_ST:
	CLR	A
	RLC	A
	MOV	I2C_BUFFER+3,A
	AJMP	EMB_EPT_UN_STALL

EMB_EPT1_IN:
	MOV	C,EMB_EPT1_IN_STALL
	AJMP	RTN_EP_ST

;==================================================================
; CLEAR DEVICE,INTERFACE,ENDPOINT FEATURE
;==================================================================
EMB_CLEAR_FEATURE:
	MOV	A,R2					;I2C_BUFFER+OFFSET_bmReqTyp
	JZ	EMB_CLR_DV_FR
	DEC	A
	JZ	EMB_CLR_IF_FR
	DEC	A
	JZ	EMB_CLR_EP_FR

EMB_CLR_IF_FR:
	AJMP	NO_SUPPORT_REQ

EMB_CLR_DV_FR:
	CLR	EMB_REMOTE_WAKE
	MOV	I2C_BUFFER,#SET_MODE
	MOV	I2C_BUFFER+1,#10111100B 	;disable remote wakeup
	ACALL	WRITE_ONE_BYTE

EMB_CLR_FR_RET:
EMB_CLR_EP0_OUT:
	LCALL	SEND_ZERO_PACKET
	RET

EMB_CLR_EP_FR:
	MOV	A,R5					;endpoint number
	JZ	EMB_CLR_EP0_OUT			;Ctrl OUT never stall, no need clear
	XRL	A,#080H
	JZ	EMB_CLR_EP0_IN 			;Ctrl IN

	MOV	A,R5
	XRL	A,#081H
	JZ	EMB_CLR_EP1_IN 	    		;Int IN

	AJMP	NO_SUPPORT_REQ

EMB_CLR_EP0_IN:
	CLR	EMB_EPT0_IN_STALL			;clear ctrl IN STALL FLAG for Get_Status command
	MOV	I2C_BUFFER,#SET_EMBF_IN_ST	;Unstall ctrl IN
	AJMP	EP_UNSTALL
EMB_CLR_EP1_IN:
	CLR	EMB_EPT1_IN_STALL	      	;clear int IN STALL FLAG for Get_Status command
	MOV	I2C_BUFFER,#SET_EMBF_INT_ST	;Unstall int IN
EP_UNSTALL:
	MOV	I2C_BUFFER+1,#0
	ACALL	WRITE_ONE_BYTE
	AJMP	EMB_CLR_FR_RET

;=========================================================
;	Set feature for device/interface/endpoint
;========================================================
EMB_SET_FEATURE:
	MOV	A,R2  	    		;I2C_BUFFER+OFFSET_bmReqTyp
	JZ	EMB_SET_DV_FTR
	DEC	A
	JZ	EMB_SET_IF_FTR
	DEC	A
	JZ	EMB_SET_EP_FTR

EMB_SET_IF_FTR:
NO_SUPPORT_REQ1:
	AJMP	NO_SUPPORT_REQ

EMB_SET_DV_FTR:
	SETB	EMB_REMOTE_WAKE		; only one possibly set feature: remote wakeup for device
	MOV	I2C_BUFFER,#SET_MODE
	MOV	I2C_BUFFER+1,#10111101B 	;enable remote wakeup
	ACALL	WRITE_ONE_BYTE
EMB_SET_FTR_RET:
EMB_SET_EPT0_OUT:
	LCALL	SEND_ZERO_PACKET
	RET

EMB_SET_EP_FTR:
	MOV	A,R5  			;endpoint number
	JZ	EMB_SET_EPT0_OUT  	;Never stalled the ctrl OUT, so no need unstall it

	XRL	A,#080H
	JZ	EMB_SET_EPT0_IN 	;ctrl IN
	MOV	A,R5
	XRL	A,#081H
	JZ	EMB_SET_EPT1_IN        	;int IN
	AJMP	NO_SUPPORT_REQ
	
EMB_SET_EPT0_IN:
	SETB	EMB_EPT0_IN_STALL		;set ctrl IN STALL FLAG for Get_Status command
	MOV	I2C_BUFFER,#SET_EMBF_IN_ST	;Stall ctrl IN
	AJMP	EP_STALL
EMB_SET_EPT1_IN:
	SETB	EMB_EPT1_IN_STALL		;set int IN STALL FLAG for Get_Status command
	MOV	I2C_BUFFER,#SET_EMBF_INT_ST	;Stall int IN
EP_STALL:
	MOV	I2C_BUFFER+1,#1
	ACALL	WRITE_ONE_BYTE
	AJMP	EMB_SET_FTR_RET

;=================================================================
; Get descriptor of device, string, configuration, hid, and report
;=================================================================
EMB_GET_DESCRIPTOR:			    ;6
	MOV	A,R4			;I2C_BUFFER+OFFSET_wValue
	JNZ	NO_SUPPORT_REQ1
	MOV	A,I2C_BUFFER+OFFSET_wValue+1	;I2C_BUFFER+OFFSET_wValue+1
;----
EMB_CHK_DEV_DESC:
	CJNE	A,#01,EMB_CHK_CONF_DESC
	MOV	DPTR,#USBDvcDsc
	MOV	R0,#I2C_BUFFER+OFFSET_wLength
;---
	INC	R0			;IF HOST ISSUE OVER 256 BYTES
	MOV	A,@R0
	JNZ	EMB_CHK_DEV_DESC1
	DEC	R0
;---
	MOV	A,@R0
	CLR	C
	SUBB	A,#18
	JC	SEND_DESCRIPTOR
EMB_CHK_DEV_DESC1:
	MOV	@R0,#18
	AJMP	SEND_DESCRIPTOR
;----
EMB_CHK_CONF_DESC:
	CJNE	A,#02,EMB_CHK_STRING_DESC
	MOV	DPTR,#USBCnfDsc
	MOV	R0,#I2C_BUFFER+OFFSET_wLength
;---
	INC	R0			;IF OVER 256 BYTES
	MOV	A,@R0
	JNZ	EMB_CHK_CONF_DESC1
	DEC	R0
;---
	MOV	A,@R0
	CLR	C
;;;	SUBB	A,#25
	SUBB	A,#022H
	JC	SEND_DESCRIPTOR
EMB_CHK_CONF_DESC1:
	MOV	@R0,#022H
;----
SEND_DESCRIPTOR:
	AJMP	SEND_TO_HOST
;--------------

EMB_CHK_STRING_DESC:
	CJNE	A,#03,EMB_CHK_HID_DESC
	MOV	A,R4		;descritpor index of string descriptor
	JZ	LANG_ID	;iLANGID[n]=0
	dec	a
	jz	manu_desc	;iManufactor=1
	dec	a
	jz	prod_desc	;iProduct=2
	dec	a
	jz	seri_desc	;iSerialNum=3
	ajmp	NO_SUPPORT_REQ1	;no support configuration string and interface string
;
LANG_ID:
	MOV	DPTR,#USBString0
	MOV	R0,#I2C_BUFFER+OFFSET_wLength
;---
	INC	R0			;IF HOST ISSUE OVER 256 BYTES
	MOV	A,@R0
	JNZ	LANG_ID1
;--
	DEC	R0
	MOV	A,@R0
	CLR	C
	SUBB	A,#04
	JC	SEND_DESCRIPTOR
LANG_ID1:
	MOV	@R0,#04
	AJMP	SEND_DESCRIPTOR
;----
;
MANU_DESC:
	MOV	DPTR,#USBString1
	MOV	R0,#I2C_BUFFER+OFFSET_wLength
;---
	INC	R0			;IF HOST ISSUE OVER 256 BYTES
	MOV	A,@R0
	JNZ	MANU_DESC1
;--
	DEC	R0
	MOV	A,@R0
	CLR	C
	SUBB	A,#manu_len
	JC	SEND_DESCRIPTOR
MANU_DESC1:
	MOV	@R0,#manu_len
	AJMP	SEND_DESCRIPTOR
;
PROD_DESC:
	MOV	DPTR,#USBString2
	MOV	R0,#I2C_BUFFER+OFFSET_wLength
;---
	INC	R0			;IF HOST ISSUE OVER 256 BYTES
	MOV	A,@R0
	JNZ	PROD_DESC1
;--
	DEC	R0
	MOV	A,@R0
	CLR	C
	SUBB	A,#prod_len
	JC	SEND_DESCRIPTOR
PROD_DESC1:
	MOV	@R0,#prod_len
	AJMP	SEND_DESCRIPTOR
;
SERI_DESC:
	MOV	DPTR,#USBString3
	MOV	R0,#I2C_BUFFER+OFFSET_wLength
;---
	INC	R0			;IF HOST ISSUE OVER 256 BYTES
	MOV	A,@R0
	JNZ	SERI_DESC1
;--
	DEC	R0
	MOV	A,@R0
	CLR	C
	SUBB	A,#6
	JC	SEND_DESCRIPTOR
SERI_DESC1:
	MOV	@R0,#6
	AJMP	SEND_DESCRIPTOR

;-------------
EMB_CHK_HID_DESC:
	CJNE	A,#021H,EMB_CHK_REPORT_DESC
	MOV	DPTR,#USBHIDDsc
	MOV	R0,#I2C_BUFFER+OFFSET_wLength
;---
	INC	R0			;IF OVER 256 BYTES
	MOV	A,@R0
	JNZ	EMB_CHK_HID_DESC1
	DEC	R0
;---
	MOV	A,@R0
	CLR	C
	SUBB	A,#9
	JC	SEND_DESCRIPTOR
EMB_CHK_HID_DESC1:
	MOV	@R0,#9
	AJMP	SEND_TO_HOST
;-------------
EMB_CHK_REPORT_DESC:
	CJNE	A,#022H,NO_SUPPORT_REQ2
	MOV	DPTR,#RptDsc
	MOV	R0,#I2C_BUFFER+OFFSET_wLength
;---
	INC	R0			;IF OVER 256 BYTES
	MOV	A,@R0
	JNZ	EMB_CHK_REPORT_DESC1
	DEC	R0
;---
	MOV	A,@R0
	CLR	C
	SUBB	A,#rpt_lngh
	JC	SEND_DESCRIPTOR1
EMB_CHK_REPORT_DESC1:
	MOV	@R0,#rpt_lngh
	AJMP	SEND_TO_HOST
SEND_DESCRIPTOR1:
	AJMP	SEND_DESCRIPTOR
NO_SUPPORT_REQ2:
	AJMP	NO_SUPPORT_REQ
;*******************************************************
;	MOV	R2,I2C_BUFFER+OFFSET_bmReqTyp	;1
;	MOV	R3,I2C_BUFFER+OFFSET_bmReq	;1
;	MOV	R4,I2C_BUFFER+OFFSET_wValue	;2
;	MOV	R5,I2C_BUFFER+OFFSET_wIndex	;2
;	MOV	R6,I2C_BUFFER+OFFSET_wLength	;2
;*******************************************************
EMB_CLASS_REQUEST:
;	MOV	A,R3			;I2C_BUFFER+OFFSET_bmReq
;	XRL	A,#09H
;	JZ	SET_REPORT		;HOST SEND "SET_REPORT" COMMAND
;---
;	MOV	A,R3			;THIS COMMAND ONLY FOR CATC DRIVER
;	XRL	A,#01H
;	JZ	GET_REPORT		;GET VCP FEATURE FROM MONITOR
;---
;	MOV	A,R3			;I2C_BUFFER+OFFSET_bmReq
;	XRL	A,#03H
;	JZ	GET_PROTOCOL	;HOST SEND "GET_PROTOCOL" COMMAND
;---
;	MOV	A,R3			;I2C_BUFFER+OFFSET_bmReq
;	XRL	A,#0BH
;	JZ	SET_PROTOCOL	;HOST SEND "SET_PROTOCOL" COMMAND
;---
	MOV	A,R3				;Get bmReq
	CLR	C
	SUBB	A,#0CH
	JNC	NO_SUPPORT_REQ_1

	MOV	DPTR,#EMB_CLASS_RQST_TBL
	MOV	A,R3
	RL	A
	JMP	@A+DPTR		
EMB_CLASS_RQST_TBL:
	AJMP	NO_SUPPORT_REQ
	AJMP	EMB_GET_REPORT
	AJMP	EMB_GET_IDLE
	AJMP	EMB_GET_PROTOCOL
	AJMP	NO_SUPPORT_REQ
	AJMP	NO_SUPPORT_REQ
	AJMP	NO_SUPPORT_REQ
	AJMP	NO_SUPPORT_REQ
	AJMP	NO_SUPPORT_REQ
	AJMP	EMB_SET_REPORT
	AJMP	EMB_SET_IDLE
	AJMP	EMB_SET_PROTOCOL
;=========================================
NO_SUPPORT_REQ_1:
	AJMP	NO_SUPPORT_REQ
;=========================================
EMB_SET_REPORT:
	MOV	A,I2C_BUFFER+OFFSET_wValue+1		;report type
	XRL	A,#02						;OUT REPORT?
	JNZ	NO_SUPPORT_REQ_1
	MOV	EMB_LAST_COM,#REQ_SET_REPORT
	RET
;=========================================
EMB_GET_REPORT:
	AJMP	NO_SUPPORT_REQ
;=========================================
EMB_SET_IDLE:
	AJMP	NO_SUPPORT_REQ
;=========================================
EMB_GET_IDLE:
	AJMP	NO_SUPPORT_REQ
;=========================================
EMB_SET_PROTOCOL:
	MOV	A,I2C_BUFFER+OFFSET_wValue
	MOV	PROTOCOL,A				;0: BOOT PROTOCOL 1: REPORT PROTOCOL
	ACALL	SEND_ZERO_PACKET
	RET
;=========================================
EMB_GET_PROTOCOL:
	MOV	I2C_BUFFER,#WRITE_BUFFER	    ;WRITE BUFFER COMMAND
	MOV	I2C_BUFFER+1,#0
	MOV	I2C_BUFFER+2,#1
	MOV	I2C_BUFFER+3,PROTOCOL
	ACALL	WRITE_THREE_BYTE
	RET

;***********************************************
; SUBROUTINES
;***********************************************
;==============================
SEND_TO_HOST:
	MOV	A,@R0				;SEND DATA LENGTH
	CLR	C				;R0 = BYTE_TO_SEND
	SUBB	A,#08H
	JNC	EMB_SEND01
	MOV	A,@R0
	MOV	R1,A				;NUMBER BYTES TO SEND
	ADD	A,#2
	MOV	RW_COUNTER,A			;TOTAL BYTES TO SEND
	MOV	EMB_BYTE_TO_SEND,#0		;REMAIN BYTES TO SEND
	AJMP	EMB_SEND02
;-----
EMB_SEND01:
	MOV	EMB_BYTE_TO_SEND,A		    ;REMAIN BYTES
	MOV	R1,#8
	MOV	RW_COUNTER,#0AH 		;TOTAL BYTES TO SEND
;-----
EMB_SEND02:
;----
	MOV	I2C_BUFFER,#WRITE_BUFFER	    ;COMMAND
	MOV	I2C_BUFFER+1,#0 		    ;FIRST BYTE SHOULD BE ZERO
	MOV	I2C_BUFFER+2,R1 		    ;DATA LENGTH
;---
	MOV	R0,#I2C_BUFFER+3
;---
EMB_SEND03:
	CLR	A
	MOVC	A,@A+DPTR
	MOV	@R0,A
	INC	R0
	INC	DPTR
	DJNZ	R1,EMB_SEND03
;---
	MOV	EMB_MSG_DPH,DPH
	MOV	EMB_MSG_DPL,DPL
;---
	ACALL	WRITE_N_BYTE
;---
	RET

;========================================
SEND_ZERO_PACKET:
	MOV	EMB_BYTE_TO_SEND,#0
	MOV	I2C_BUFFER,#SEL_EPT_EMBF_IN
	ACALL	WRITE_COMMAND
;----
	MOV	I2C_BUFFER,#WRITE_BUFFER
	MOV	I2C_BUFFER+1,#0
	MOV	I2C_BUFFER+2,#0
	MOV	I2C_BUFFER+3,#0
	ACALL	WRITE_THREE_BYTE
	RET
;========================================

WRITE_NINE_BYTE:
	MOV	RW_COUNTER,#9
	AJMP	WRITE_TO_d11
;----------------------------------------
WRITE_SIX_BYTE:
	MOV	RW_COUNTER,#6
WRITE_N_BYTE:
	AJMP	WRITE_TO_d11
;----------------------------------------
WRITE_THREE_BYTE:
	MOV	RW_COUNTER,#3
	AJMP	WRITE_TO_d11
;----------------------------------------
WRITE_FOUR_BYTE:
	MOV	RW_COUNTER,#4
	AJMP	WRITE_TO_d11
;----------------------------------------
WRITE_TWO_BYTE:
	MOV	RW_COUNTER,#2
	AJMP	WRITE_TO_d11
;----------------------------------------
READ_ONE_BYTE:
	MOV	RW_COUNTER,#1
	AJMP	READ_FROM_d11
;----------------------------------------
READ_TWO_BYTE:
	MOV	RW_COUNTER,#2
	AJMP	READ_FROM_d11
;----------------------------------------
READ_TEN_BYTE:
	MOV	RW_COUNTER,#10
	AJMP	READ_FROM_d11
;----------------------------------------
WRITE_ONE_BYTE:
	MOV	RW_COUNTER,#1
	AJMP	WRITE_TO_d11
;----------------------------------------
WRITE_COMMAND:
	MOV	SLV_ADR,#036H		;WRITE COMMAND
	MOV	CNT_BYTE,#1		;NUMBER OF BYTES TO BE SENT
	LCALL	WRITE_d11_POINT 	;READ 1 BYTES
	RET

⌨️ 快捷键说明

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