;***************************************************************************** ;| | ;| PROGARM : KBhub214.asm | ;| | ;| FUNCTIONS : Hub Control Program with keyboard ( Golden Code) | ;| | ;| COMPILER : ASM51 Macro Assembler V1.2 | ;| | ;| USED IN : 83C748 / C751 / C51 | ;| | ;| AUTHORS : Eric Lu / Chui Wei Leong | ;| | ;| WRITTEN AT : 15-10-96 | ;| | ;| VERSION : V 2.20 | ;| | ;| UPDATES : 02-07-97 | ;| : 21-07-98 by Subramanyam S ;| : 24-07-98 by Subramanyam S ;| | ;| Copyright 1996, Product Innovation Centre Asia, Philips Semiconductors | ;| 620A, Lorong 1 Toa Payoh (TP3), 2nd Floor, Singapore 319762 | ;| All rights are reserved. Reproduction in whole or in part is | ;| prohibited without the prior written consent of the copyright owner. | ;| | ;| COMPANY CONFIDENTIAL | ;| | ;***************************************************************************** ;| Code History | ;| 748V1_10.asm: This first officially released version | ;| 748V2_00.asm:1.Corrected " Switch_N not working under suspend mode problem| ;| 2.Supported 2 Hub descriptor type number 00 and 29 | ;| 748V2_10.asm:1.Corrected " Global overcurrent reporting problem" | ;| 2.Changed the Hub device class/subclass to compliance to | ;| USB spec1.0 | ;| 748v2_20.asm:1.Changed the configuration descriptor to support/enable | ;| remote wakeup function. | ;| 2.Checking buffer full bit when setup/out token coming | ;| kb_hub.asm: 1. Remote Wakeup function at send_makecode | ;| 2. Set Configuration change. | ;| 3. Get configuration change. | ;| kbhub2_2.asm 1. Add SetMode command for H11A | ;| kbhub2_4.asm 1. Change Set Mode Command for H11A used on H11 board; | ;| 2. Set Port Suspend on embedded port | ;| kbhub2_5.asm 1. Change to key rotation | ;| kbhub2_6.asm 1. Change F3 keycode to correct 0x3C | ;| 2. Shift Key change function | ;| 3. Add Windows key | ;| 4. Change Descriptor to Bus power | ;| kbhub2_7.asm 1. Change scan for windows key | ;| 2. Restrict bandwidth | ;| kbhub2_8.asm 1. Correct spec version swap | ;| 2. Set Idle and Get Idle condition | ;| kbhub2_9.asm 1. Ghost key | ;| KBHUB210.ASM 1. REMOVE LED LIGHTS IN SUSPEND | ;| kbhub211.asm 1. remove led lights in suspend for h11 | ;| kbhub212.asm 1. windows key flip | ;| kbhub213.asm 1. Update useage table | ;| 2. Corrected for H11A keyboard Hub | ;| 3. Swop order of reading descriptor for Draft 4 compliance | ;| 4. Final Version for demoboard | ;| 5. Swap LED status | ;| | ;| kbhub214.asm 1. Chap 11 (Test 5.5.5) failure fixed. | ;| HC suspend with remote wakeup disable failure, on connecting ;| device HC would resume. | ;| 2. Routines changed clear_device_feature & set_device_feature| ;| 3. HID view failed in "set_protocol" | ;***************************************************************************** $MOD652 $INCLUDE(TRANSCTN.TYP) $INCLUDE(H11.CMD) ;------------------------------ ; All Registers ;------------------------------ ;General ;------- STACK_BUF DATA 60H ;Stack Buffer Pointer ;I2C Routines ;------------ BITCNT DATA 10H ;I2C Bit Counter, sends 8 bits BYTE_CNT DATA 11H ;#BYTES TO BE PROCESSED BY I2C TX/RX I2C_FLAG DATA 20H ;I2C SOFTWARE STATUS FLAGS. I2C_FAIL BIT I2C_FLAG.0 ;I2C NO ACKNOWLEDGE FLAG. ;Comms to H11 ;------------ CNT_BYTE DATA 12H ;NUMBER OF BYTES TO BE TRANSMITTED SLV_ADR DATA 13H ;I2C ADDRESS OF ACTIVE SLAVE. I2C_BUFFER DATA 14H ;I2C TRANSMIT/RECEIVE DATA BUFFER RW_COUNTER DATA 30H VALIDATE_FLAG BIT I2C_FLAG.1 SUSPEND_FLAG BIT I2C_FLAG.2 ;Function Setup Register ;----------------------- TRANSACTION DATA 31H ; #00000000B FN_FEATURE_SEL DATA 32H ; FEATURE SELECTOR & REPORT TYPE FOR KB CLASS FN_ADDR DATA 33H ; Low 7 bits - address ; 7th bit - set means configured FN_TRANSACTION_END DATA 34H FN_TRANSACTION_INDEX DATA 35H FN_IDLE_TIME DATA 36H ; IDLE TIME FOR KEYBOARD FN_DATA_REQUEST_LENGTH DATA 37H ;Keyboard Registers ;------------------ ROW_NUM DATA 24H X_LO BIT ROW_NUM.3 WIN_KEY BIT ROW_NUM.4 KEY_HIT0 DATA 46H KEY_HIT1 DATA 47H KEY_HIT2 DATA 48H KEY_HIT3 DATA 49H KEY_HIT4 DATA 4AH KEY_HIT5 DATA 4BH MODIFIER_BYTE DATA 4CH TOTAL_KEYS DATA 4DH LAST_ZERO_SENT DATA 4EH BIT_NUMBER DATA 39H KEY1 DATA 50H KEY2 DATA 51H KEY3 DATA 52H KEY4 DATA 53H KEY5 DATA 54H KEY6 DATA 55H KEY_MODIFIER DATA 56H BOOT_PROTOCOL DATA 57H LED_STATUS DATA 58H END_PT_STALL DATA 59H ;------------------------ ; RS232 ;------------------------ BITTIM EQU 31H TXD_BITCNT DATA 37H ;------------------------------ ; H11 Commands and Addresses ;------------------------------ ; Addresses ;---------- COMMAND_ADDRESS EQU 36H DATA_READ_ADDR EQU 35H DATA_WRITE_ADDR EQU 34H ; H11A commands ;-------------- SET_MODE EQU 0F3H ; H11 commands ;------------- SET_HUB_ADDRESS_EN EQU 0D0h SET_EMB_ADDRESS_EN EQU 0D1h SET_EPOINT_EN EQU 0D8h SEL_HUB_OUT_ENDPT EQU 000H SEL_HUB_IN_ENDPT EQU 001H SEL_FN_OUT_ENDPT EQU 002H SEL_FN_IN_ENDPT EQU 003H SEL_FN_INT_ENDPT EQU 004H EMB_IN_STATUS EQU 083H READ_BUFFER EQU 0F0h WRITE_BUFFER EQU 0F0h CLEAR_BUF EQU 0F2h READ_INT EQU 0F4h VALIDATE_BUF EQU 0FAh ACK_SETUP EQU 0F1H RESUME_DEV EQU 0F6H EMB_ENDPT0_STATUS EQU 042H EMB_ENDPT1_STATUS EQU 043H EMB_INT_ENDPT_STATUS EQU 044H ;----------------- OFFSET_bmReqTyp EQU 02h OFFSET_bmReq EQU 03h OFFSET_wValue EQU 04h OFFSET_wIndex EQU 06h OFFSET_wLenght EQU 08h ;---------------------------------------- ; Feature Selector ;--------------------------------------- DEVICE_REMOTE_WAKEUP EQU 01h ENDPOINT_STALL EQU 00H ;---------------------------------------- ; IO PORT ;--------------------------------------- ;Hub Usage ;--------- SCLPIN BIT P3.1 SDAPIN BIT P3.0 H11_INT BIT P3.2 SUSPEND BIT P3.3 ;Keyboard Usage ;-------------- LED_ENABLE BIT P3.5 CAPS BIT P0.1 ; CAPS NUM BIT P0.2 ; NUM SCROLL BIT P0.0 ; SCROLL WIN_BIT BIT P3.4 X0 EQU P0 X1 EQU P1 Y0 EQU P2 R4_DIRECT DATA 04H ; DIRECT LOCATION OF R4 ;------------------------------ ; INTERRUPT VECTOR TABLE ;------------------------------ CSEG AT 0000H ORG 0000H AJMP START ;PROGRAM START ORG 0003H AJMP INT0_SERVER ;INT0 SERVICE ROUTINE ORG 000BH AJMP T0_SERVER ;TIMER0 SERVICE ROUTINE ORG 0013H AJMP INT1_SERVER ;INT1 SERVICE ROUTINE ORG 001BH AJMP T1_SERVER ;TIMER1 SERVICE ROUTINE ORG 0023H AJMP UART_SERVER ;UART SERVICE ROUTINE ORG 002BH AJMP I2C_SERVER ;I2C SERVICE ROUTINE ;****************************** INT0_SERVER: ;INT0 SERVICE ROUTINE RETI T0_SERVER: ;TIMER0 SERVICE ROUTINE PUSH ACC MOV TL0, #0E8H ; TL0 AND TH0 MAKES 1 millisec MOV TH0, #03H MOV TCON, #00010000B ; TURNS TIMER0 ON MOV A, FN_IDLE_TIME JZ END_T0_SERVER DEC A MOV FN_IDLE_TIME, A END_T0_SERVER: POP ACC RETI INT1_SERVER: ;INT1 SERVICE ROUTINE T1_SERVER: ;TIMER1 SERVICE ROUTINE UART_SERVER: ;UART SERVICE ROUTINE I2C_SERVER: ;I2C SERVICE ROUTINE RETI ;*************************************** ; PROGRAM START ;*************************************** ORG 0050H START: MOV IE,#00000000B ;ALL INTERRUPT DISABLED MOV SP,#STACK_BUF ;SET STACK POINTER ;----------------------------- ; INITIAL I/O PORT ;----------------------------- MOV P0,#11111111B ; MOV P1,#11111111B MOV P2,#11111111B MOV P3,#11111111B CLR SUSPEND CLR LED_ENABLE CLR NUM CLR SCROLL CLR CAPS ;--------------------------------------------------------------------------- ; Blank out for H11 ;--------------------------------------------------------------------------- MOV I2C_BUFFER,#SET_MODE MOV I2C_BUFFER+1,#0FFH ; SET SOFT CONNECT NON BLINKING MOV I2C_BUFFER+2,#03H ; SET CLOCK ACALL WRITE_TWO_BYTE ;--------------------------------------------------------------------------- LCALL KEYBOARD_INITIAL MOV IE,#00000000B ;ALL INTERRUPT DISABLED SETB SUSPEND MAIN: ACALL USB_INTERRUPT JB SUSPEND_FLAG,OFF_LED JNB SUSPEND, LITE_LED SETB SUSPEND_FLAG OFF_LED: SETB NUM SETB CAPS SETB SCROLL SJMP KEY_ROUTINE LITE_LED: LCALL WRITE_LED KEY_ROUTINE: LCALL KEYBOARD_ROUTINE AJMP MAIN USB_INTERRUPT: JNB H11_INT, PROCESS_INTERRUPT ;RETURN IF NOT INTERRUPTED RET PROCESS_INTERRUPT: CLR SUSPEND_FLAG MOV I2C_BUFFER,#READ_INT ;READ INTERRUPT REGISTER ;--------------------------------------------------------------------------- ; For H11 ;--------------------------------------------------------------------------- ACALL READ_ONE_BYTE ;READ DATA FROM H11 ;--------------------------------------------------------------------------- ; For H11A ;--------------------------------------------------------------------------- ; ACALL READ_TWO_BYTE ;READ DATA FROM H11 MOV A,I2C_BUFFER JB ACC.0,HUB_CTRL_OUT_P ; HUB CONTROL OUT ENDPT JB ACC.1,HUB_CTRL_IN_P ; HUB CONTROL IN ENDPT JB ACC.2,FN_CTRL_OUT_P ; FUNCTION CONTROL OUT ENDPOINT JB ACC.3,FN_CTRL_IN_P ; FUNCTION CONTROL IN ENDPOINT JB ACC.4,FN_INT_P ; FUNCTION INTERRUPT ENDPOINT ;--------------------------------------------------------------------------- ; Blank out for H11 ;--------------------------------------------------------------------------- ; MOV A,I2C_BUFFER+1 ; JB ACC.6,RESTART_H11 ; RET ;--------------------------------------------------------------------------- RESTART_H11: SETB NUM ;CLEAR NUM LED SETB SCROLL ;CLEAR SCROLL LED SETB CAPS ;CLEAR CAPS LED MOV I2C_BUFFER,#SET_HUB_ADDRESS_EN MOV I2C_BUFFER+1,#80H ;ENABLE HUB ACALL WRITE_ONE_BYTE MOV I2C_BUFFER,#SET_EMB_ADDRESS_EN MOV I2C_BUFFER+1,#00H ;DISABLE EMBEDDED FN ACALL WRITE_ONE_BYTE MOV I2C_BUFFER,#SET_EPOINT_EN ;DISENABLE HUB/EMBEDDED INTERRUPT MOV I2C_BUFFER+1,#00H ;ENDPOINT ACALL WRITE_ONE_BYTE ACALL USB_INITIAL END_USB_INTERRUPT: RET; USB_INTERRUPT HUB_CTRL_OUT_P: LJMP HUB_CTRL_OUT HUB_CTRL_IN_P: LJMP HUB_CTRL_IN FN_CTRL_OUT_P: AJMP FN_CTRL_OUT FN_CTRL_IN_P: AJMP FN_CTRL_IN FN_INT_P: AJMP FN_INT USB_INITIAL: CLR VALIDATE_FLAG MOV TRANSACTION, #NO_TRANSACTION MOV FN_IDLE_TIME, #00H MOV FN_ADDR, #00H MOV HUB_ADDR,#00H MOV EMB_ADDR,#00H MOV EMBED_STATUS0,#01H MOV EMBED_STATUS1,#00H CLR EMBED_CONFIG SETB EMBED_REMOTE_WKUP RET; USB_INITIAL ;======================================== ; FUNCTION CODE ;======================================== FN_CTRL_OUT: MOV I2C_BUFFER,#EMB_ENDPT0_STATUS ;READ INTERRUPT REGISTER ACALL READ_ONE_BYTE ;READ DATA FROM H11 FN_RCV_TXD_OK: MOV I2C_BUFFER,#82H ;READ INTERRUPT REGISTER ACALL READ_ONE_BYTE ;READ DATA FROM H11 MOV A, I2C_BUFFER JNB ACC.5, BUFF_NOT_FULL JB ACC.2, FN_SETUP SJMP FN_ACK_DATA_RCV BUFF_NOT_FULL: RET FN_ACK_DATA_RCV: MOV I2C_BUFFER, #SEL_FN_OUT_ENDPT ; SELECT OUT BUFFER ACALL WRITE_COMMAND MOV RW_COUNTER,#0AH ;READ NEXT 10 BTYES MOV I2C_BUFFER,#READ_BUFFER ACALL READ_FROM_FN_OUT MOV A,I2C_BUFFER+1 ;READ TOTAL HOW MANY BYTES JZ FN_ACK_DATA_RCV02 ; check if it is "SET" data from host CJNE A, #01H, FN_ACK_DATA_RCV02 MOV A, TRANSACTION MOV TRANSACTION, #NO_TRANSACTION CJNE A,#32H, FN_ACK_DATA_RCV02 ;CHECK FOR SET REPORT MOV LED_STATUS, I2C_BUFFER+2 CHK_NUM: END_SET_REPORT: MOV I2C_BUFFER,#CLEAR_BUF ;CLEAR BUFFER ACALL WRITE_COMMAND FN_ACK_DATA_RCV01: ACALL SEND_FN_ZERO_PACKET RET FN_ACK_DATA_RCV02: MOV I2C_BUFFER,#CLEAR_BUF ;CLEAR BUFFER ACALL WRITE_COMMAND RET FN_SETUP: ; Setting up of Ctrl-In is essential MOV I2C_BUFFER, #SEL_FN_IN_ENDPT ; SELECT IN BUFFER ACALL WRITE_COMMAND MOV I2C_BUFFER,#ACK_SETUP ;ACKNOWLEDGE SETUP ACALL WRITE_COMMAND MOV I2C_BUFFER,#CLEAR_BUF ;CLEAR BUFFER ACALL WRITE_COMMAND MOV I2C_BUFFER, #SEL_FN_OUT_ENDPT ; SELECT OUT BUFFER ACALL WRITE_COMMAND MOV I2C_BUFFER,#ACK_SETUP ;ACKNOWLEDGE SETUP ACALL WRITE_COMMAND ;TO RELEASE THE LOCK ON THE BUFFER MOV RW_COUNTER,#0AH ;READ NEXT 10 BTYES MOV I2C_BUFFER,#READ_BUFFER ACALL READ_FROM_FN_OUT MOV I2C_BUFFER,#CLEAR_BUF ;CLEAR BUFFER TO RE-ENABLE ACALL WRITE_COMMAND ;ACK MOV A,I2C_BUFFER+1 ;READ TOTAL HOW MANY BYTES CJNE A,#08H, ERROR_SETUP ;NOT CORRECT COMMAND FROM HOST FN_DECODE_REQUEST: MOV R2,I2C_BUFFER+OFFSET_bmReqTyp MOV R3,I2C_BUFFER+OFFSET_bmReq MOV R4,I2C_BUFFER+OFFSET_wValue MOV R7,I2C_BUFFER+OFFSET_wValue+1 MOV R5,I2C_BUFFER+OFFSET_wIndex MOV R6,I2C_BUFFER+OFFSET_wLenght MOV FN_DATA_REQUEST_LENGTH, R6 ; Length of data to send MOV A, R3 ; Check if it is less than 16. ANL A, #0F0H ; Standard and class specified requests JNZ ERROR_SETUP ; has only 16 requests MOV A, R2 ; Check if it is a standard or ANL A, #00100000B ; class request RR A PUSH ACC MOV A, R3 ANL A, #00001111B MOV TRANSACTION, A POP ACC ORL A, TRANSACTION RL A MOV TRANSACTION, A MOV DPTR, #SETUP_FN_ACTION JMP @A+DPTR SETUP_FN_ACTION: ; Standard Requests AJMP STD_FN_GET_STATUS ;0 AJMP STD_FN_CLEAR_FEATURE ;2 AJMP RESERVED ;4 AJMP STD_FN_SET_FEATURE ;6 AJMP RESERVED ;8 AJMP STD_FN_SET_ADDRESS ;A AJMP STD_FN_GET_DESCRIPTOR ;C AJMP STD_FN_SET_DESCRIPTOR ;E AJMP STD_FN_GET_CONFIGURATION;10 AJMP STD_FN_SET_CONFIGURATION;12 AJMP STD_FN_GET_INTERFACE ;14 AJMP STD_FN_SET_INTERFACE ;16 AJMP STD_FN_SYNCH_FRAME ;18 AJMP RESERVED ;1A AJMP RESERVED ;1C AJMP RESERVED ;1E ; Class Requests AJMP RESERVED ;20 AJMP CLSS_FN_GET_REPORT ;22 AJMP CLSS_FN_GET_IDLE ;24 AJMP CLSS_FN_GET_PROTOCOL ;26 AJMP RESERVED ;28 AJMP RESERVED ;2A AJMP RESERVED ;2C AJMP RESERVED ;2E AJMP RESERVED ;30 AJMP CLSS_FN_SET_REPORT ;32 AJMP CLSS_FN_SET_IDLE ;34 AJMP CLSS_FN_SET_PROTOCOL ;36 AJMP RESERVED ;38 AJMP RESERVED ;3A AJMP RESERVED ;3C AJMP RESERVED ;3E ERROR_SETUP: ; Should send a stall for unknown Requests ACALL SEND_FN_STALL_ENDPT1 ACALL SEND_FN_STALL_ENDPT0 AJMP SEND_FN_STALL_INT END_ERROR_SETUP: RET; FN_CTRL_OUT FN_CTRL_IN: MOV I2C_BUFFER,#EMB_ENDPT1_STATUS ;READ INTERRUPT REGISTER ACALL READ_ONE_BYTE ;READ DATA FROM H11 MOV A, TRANSACTION ANL A, #NO_TRANSACTION XRL A, #NO_TRANSACTION JNZ GIVE_FN_REPLY RET ; Return because there's no transaction GIVE_FN_REPLY: MOV A, TRANSACTION CLR ACC.0 ANL A, #00011111B MOV DPTR, #REPLY_FN_ACTION JMP @A+DPTR REPLY_FN_ACTION: ; Standard Requests AJMP REPLY_STD_FN_GET_STATUS AJMP REPLY_STD_FN_CLEAR_FEATURE AJMP REPLY_RESERVED AJMP REPLY_STD_FN_SET_FEATURE AJMP REPLY_RESERVED AJMP REPLY_STD_FN_SET_ADDRESS AJMP REPLY_STD_FN_GET_DESCRIPTOR AJMP REPLY_STD_FN_SET_DESCRIPTOR AJMP REPLY_STD_FN_GET_CONFIGURATION AJMP REPLY_STD_FN_SET_CONFIGURATION AJMP REPLY_STD_FN_GET_INTERFACE AJMP REPLY_STD_FN_SET_INTERFACE AJMP REPLY_STD_FN_SYNCH_FRAME AJMP REPLY_RESERVED AJMP REPLY_RESERVED AJMP REPLY_RESERVED ; Class Requests AJMP REPLY_RESERVED AJMP REPLY_CLSS_FN_GET_REPORT AJMP REPLY_CLSS_FN_GET_IDLE AJMP REPLY_CLSS_FN_GET_PROTOCOL AJMP REPLY_RESERVED AJMP REPLY_RESERVED AJMP REPLY_RESERVED AJMP REPLY_RESERVED AJMP REPLY_RESERVED AJMP REPLY_CLSS_FN_SET_REPORT AJMP REPLY_CLSS_FN_SET_IDLE AJMP REPLY_CLSS_FN_SET_PROTOCOL AJMP REPLY_RESERVED AJMP REPLY_RESERVED AJMP REPLY_RESERVED AJMP REPLY_RESERVED RET; FN_CTRL_IN FN_INT: MOV I2C_BUFFER, #EMB_INT_ENDPT_STATUS ACALL READ_ONE_BYTE MOV A, FN_IDLE_TIME JNZ END_FN_INT MOV A, LAST_ZERO_SENT JNZ END_FN_INT MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #08H MOV I2C_BUFFER+3, KEY_MODIFIER; Modifier MOV I2C_BUFFER+4, #00H; Reserved MOV I2C_BUFFER+5, KEY1; K1 MOV I2C_BUFFER+6, KEY2; K2 MOV I2C_BUFFER+7, KEY3; K3 MOV I2C_BUFFER+8, KEY4; K4 MOV I2C_BUFFER+9, KEY5; K5 MOV I2C_BUFFER+10, KEY6; K6 MOV RW_COUNTER, #0AH LCALL WRITE_TO_EMB_INT MOV A, KEY1 JZ DONT_SEND_NEXT RET DONT_SEND_NEXT: MOV A, KEY_MODIFIER JZ DONT_SEND_NEXT1 RET DONT_SEND_NEXT1: MOV LAST_ZERO_SENT, #01H END_FN_INT: RET; FN_INT ;======================================== ; FUNCTION DESCRIPTOR'S CODE ;======================================== STD_FN_GET_STATUS: MOV A, R2 ; I2C_BUFFER+OFFSET_bmReqTyp ANL A, #00000011B JZ STD_FN_GET_STATUS2; GOTO DEVICE STATUS DEC A JZ STD_FN_GET_STATUS0; GOTO INTERFACE STATUS DEC A JZ STD_FN_GET_STATUS1; GOTO ENDPOINT STATUS ERROR_FN_GET_STATUS: MOV TRANSACTION, #NO_TRANSACTION ACALL SEND_FN_STALL_ENDPT1 ACALL SEND_FN_STALL_ENDPT0 AJMP SEND_FN_STALL_INT STD_FN_GET_STATUS0: ; Get Interface Status ;--------------------- ;MOV A, R5 ; I2C_BUFFER+OFFSET_wIndex ;JNZ ERROR_FN_GET_STATUS ; ONLY ONE INTERFACE MOV A, #FN_GET_INTERFACE_STATUS ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_GET_STATUS1: ; Get Endpoint Status ;-------------------- MOV A, R5 ; I2C_BUFFER+OFFSET_wIndex JZ EPT0_STATUS CJNE A, #01H, EPT1_STATUS SJMP ERROR_FN_GET_STATUS EPT1_STATUS: MOV I2C_BUFFER,#084H ; Interrupt Endpoint Status LCALL READ_ONE_BYTE MOV END_PT_STALL, #00H MOV A, I2C_BUFFER JNB ACC.3, END_EPT_STATUS MOV END_PT_STALL, #01H SJMP END_EPT_STATUS EPT0_STATUS: MOV END_PT_STALL, #00H ACALL SEND_FN_UNSTALL_ENDPT1 ACALL SEND_FN_UNSTALL_ENDPT0 END_EPT_STATUS: MOV A, #FN_GET_ENDPOINT_STATUS ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_GET_STATUS2: ; Get Device Status ;------------------ ;MOV A, R5 ; I2C_BUFFER+OFFSET_wIndex ;JNZ ERROR_FN_GET_STATUS MOV A, #FN_GET_DEVICE_STATUS ORL A, TRANSACTION MOV TRANSACTION, A RET END_STD_FN_GET_STATUS: RET; STD_FN_GET_STATUS STD_FN_CLEAR_FEATURE: MOV A, R2 ; I2C_BUFFER+OFFSET_bmReqTyp ANL A, #00000011B JZ STD_FN_CLEAR_FEATURE0; GOTO DEVICE CLEAR FEATURE DEC A JZ STD_FN_CLEAR_FEATURE1; GOTO INTERFACE CLEAR FEATURE DEC A JZ STD_FN_CLEAR_FEATURE2; GOTO ENDPOINT CLEAR FEATURE ERROR_FN_CLEAR_FEATURE: MOV TRANSACTION, #NO_TRANSACTION ACALL SEND_FN_STALL_ENDPT1 ACALL SEND_FN_STALL_ENDPT0 AJMP SEND_FN_STALL_INT STD_FN_CLEAR_FEATURE0: ; Clear Device Feature ;------------------ MOV A, R4 CJNE A, #DEVICE_REMOTE_WAKEUP, ERROR_FN_CLEAR_FEATURE ;MOV A, R5 ;JNZ ERROR_FN_CLEAR_FEATURE CLR EMBED_REMOTE_WKUP MOV A, #FN_CLEAR_DEVICE_FEATURE ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_CLEAR_FEATURE1: ; Clear Interface Feature ;------------------------ AJMP ERROR_FN_CLEAR_FEATURE; NO SUPPORT MOV A, #FN_CLEAR_INTERFACE_FEATURE ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_CLEAR_FEATURE2: ; Clear Endpoint Feature ;-------------------- MOV A, R4 CJNE A, #ENDPOINT_STALL, ERROR_FN_CLEAR_FEATURE; NO SUPPORT MOV A, R5 CJNE A, #01H, UNSTALL_ENDPOINT1 END_STD_FN_CLEAR_FEATURE2: MOV A, #FN_CLEAR_ENDPOINT_FEATURE ORL A, TRANSACTION MOV TRANSACTION, A RET UNSTALL_ENDPOINT1: ACALL SEND_FN_UNSTALL_INT SJMP END_STD_FN_CLEAR_FEATURE2 END_STD_FN_CLEAR_FEATURE: RET; STD_FN_CLEAR_FEATURE STD_FN_SET_FEATURE: MOV A, R2 ; I2C_BUFFER+OFFSET_bmReqTyp ANL A, #00000011B JZ STD_FN_SET_FEATURE0; GOTO DEVICE SET FEATURE DEC A JZ STD_FN_SET_FEATURE1; GOTO INTERFACE SET FEATURE DEC A JZ STD_FN_SET_FEATURE2; GOTO ENDPOINT SET FEATURE ERROR_FN_SET_FEATURE: MOV TRANSACTION, #NO_TRANSACTION ACALL SEND_FN_STALL_ENDPT1 ACALL SEND_FN_STALL_ENDPT0 AJMP SEND_FN_STALL_INT STD_FN_SET_FEATURE0: ; Set Device Feature ;------------------ MOV A, R4 ; wValue CJNE A, #DEVICE_REMOTE_WAKEUP, ERROR_FN_SET_FEATURE ;MOV A, R5 ; wIndex ;JNZ ERROR_FN_SET_FEATURE SETB EMBED_REMOTE_WKUP MOV A, #FN_SET_DEVICE_FEATURE ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_SET_FEATURE1: ; Set Interface Feature ;--------------------- AJMP ERROR_FN_SET_FEATURE; NO SUPPORT MOV A, #FN_SET_INTERFACE_FEATURE ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_SET_FEATURE2: ; Set Endpoint Feature ;-------------------- MOV A, R4 CJNE A, #ENDPOINT_STALL, ERROR_FN_SET_FEATURE; NO SUPPORT MOV A, R5 CJNE A, #01H, STALL_ENDPOINT1 END_STD_FN_SET_FEATURE2: MOV A, #FN_SET_ENDPOINT_FEATURE ORL A, TRANSACTION MOV TRANSACTION, A RET STALL_ENDPOINT1: ACALL SEND_FN_STALL_INT SJMP END_STD_FN_SET_FEATURE2 END_STD_FN_SET_FEATURE: RET; STD_FN_SET_FEATURE STD_FN_SET_ADDRESS: MOV TRANSACTION, #NO_TRANSACTION MOV FN_ADDR, R4 ACALL SEND_FN_ZERO_PACKET WAIT_FOR_CHANGE1: MOV I2C_BUFFER,#READ_INT ;READ INTERRUPT REGISTER ACALL READ_ONE_BYTE ;READ DATA FROM H11 MOV A,I2C_BUFFER JNB ACC.3, WAIT_FOR_CHANGE1 MOV I2C_BUFFER,#SET_EMB_ADDRESS_EN MOV A,FN_ADDR ORL A,#080H MOV I2C_BUFFER+1,A ;ENABLE EMBEDDED FN ACALL WRITE_ONE_BYTE MOV BYTE_TO_SEND,#0 RET; STD_FN_SET_ADDRESS STD_FN_GET_DESCRIPTOR: MOV A, R7 ; wIndex states which item it refers to DEC A JNZ STD_FN_GET_DESCRIPTOR0 ; Get Device Descriptor ;---------------------- MOV A, #FN_GET_DEVICE_DESC ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_GET_DESCRIPTOR0: DEC A JNZ STD_FN_GET_DESCRIPTOR1 ; Get Configuration Descriptor ;----------------------------- MOV A, #FN_GET_CONFIG_DESC ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_GET_DESCRIPTOR1: DEC A JNZ STD_FN_GET_DESCRIPTOR2 ; Get String Descriptor ;---------------------- MOV A, #FN_GET_STRING_DESC ORL A, TRANSACTION MOV TRANSACTION, A STD_FN_GET_DESCRIPTOR2: DEC A JNZ STD_FN_GET_DESCRIPTOR3 ; Set Interface Descriptor ;------------------------- MOV A, #FN_GET_INTERFACE_DESC ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_GET_DESCRIPTOR3: DEC A JNZ STD_FN_GET_DESCRIPTOR4 ; Set Endpoint Feature ;--------------------- MOV A, #FN_GET_ENDPOINT_DESC ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_GET_DESCRIPTOR4: MOV A, R7 ; wIndex states which item it refers to CJNE A, #21H, STD_FN_GET_DESCRIPTOR5 ; Get HID Descriptor ;---------------------- MOV A, #FN_GET_HID_DESC ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_GET_DESCRIPTOR5: CJNE A, #22H, STD_FN_GET_DESCRIPTOR6 ; Get Report Descriptor ;---------------------- MOV A, #FN_GET_REPORT_DESC ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_GET_DESCRIPTOR6: CJNE A, #23H, END_STD_FN_GET_DESCRIPTOR ; Get Physical Descriptor ;------------------------ MOV TRANSACTION, #NO_TRANSACTION RET END_STD_FN_GET_DESCRIPTOR: MOV TRANSACTION, #NO_TRANSACTION RET; STD_FN_GET_DESCRIPTOR STD_FN_SET_DESCRIPTOR: MOV A, R4 ; wIndex states which item it refers to DEC A JNZ STD_FN_SET_DESCRIPTOR0 ; Get Device Descriptor ;---------------------- MOV A, #FN_SET_DEVICE_DESC ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_SET_DESCRIPTOR0: DEC A JNZ STD_FN_SET_DESCRIPTOR1 ; Get Configuration Descriptor ;----------------------------- MOV A, #FN_SET_CONFIG_DESC ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_SET_DESCRIPTOR1: DEC A JNZ STD_FN_SET_DESCRIPTOR2 ; Get String Descriptor ;---------------------- MOV A, #FN_SET_STRING_DESC ORL A, TRANSACTION MOV TRANSACTION, A STD_FN_SET_DESCRIPTOR2: DEC A JNZ STD_FN_SET_DESCRIPTOR3 ; Set Interface Descriptor ;------------------------- MOV A, #FN_SET_INTERFACE_DESC ORL A, TRANSACTION MOV TRANSACTION, A RET STD_FN_SET_DESCRIPTOR3: DEC A JNZ END_STD_FN_SET_DESCRIPTOR ; Set Endpoint Feature ;--------------------- MOV A, #FN_SET_ENDPOINT_DESC ORL A, TRANSACTION MOV TRANSACTION, A RET END_STD_FN_SET_DESCRIPTOR: RET; STD_FN_SET_DESCRIPTOR STD_FN_GET_CONFIGURATION: RET; STD_FN_GET_CONFIGURATION STD_FN_SET_CONFIGURATION: MOV A, R4 JZ DISABLE_EMBED SETB EMBED_CONFIG RET; STD_FN_SET_CONFIGURATION DISABLE_EMBED: CLR EMBED_CONFIG RET; STD_FN_SET_CONFIGURATION STD_FN_GET_INTERFACE: RET; STD_FN_GET_INTERFACE STD_FN_SET_INTERFACE: RET; STD_FN_SET_INTERFACE STD_FN_SYNCH_FRAME: RET; STD_FN_SYNCH_FRAME CLSS_FN_GET_REPORT: MOV FN_FEATURE_SEL, I2C_BUFFER+OFFSET_wValue+1; REPORT TYPE MOV TRANSACTION, #NO_TRANSACTION MOV A, FN_FEATURE_SEL DEC A JZ REPORT_TYPE_INPUT DEC A JZ REPORT_TYPE_OUTPUT ; NO SUPPORT FOR OTHER REPORT TYPES AJMP SEND_FN_STALL_ENDPT1 REPORT_TYPE_INPUT: MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #08H MOV I2C_BUFFER+3, KEY_MODIFIER; MOV I2C_BUFFER+4, #00H; Reserved MOV I2C_BUFFER+5, KEY1; K1 MOV I2C_BUFFER+6, KEY2; K2 MOV I2C_BUFFER+7, KEY3; K3 MOV I2C_BUFFER+8, KEY4; K4 MOV I2C_BUFFER+9, KEY5; K5 MOV I2C_BUFFER+10,KEY6; K6 MOV RW_COUNTER, #0AH MOV TOTAL_KEYS, #00H AJMP WRITE_TO_EMB_IN REPORT_TYPE_OUTPUT: MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #01H MOV I2C_BUFFER+3, #00H; Modifier MOV RW_COUNTER, #03H AJMP WRITE_TO_EMB_IN RET; CLSS_FN_GET_REPORT CLSS_FN_GET_IDLE: MOV TRANSACTION, #NO_TRANSACTION MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #01H MOV I2C_BUFFER+3, FN_IDLE_TIME; Idle Duration MOV RW_COUNTER, #03H AJMP WRITE_TO_EMB_IN RET; CLSS_FN_GET_IDLE CLSS_FN_GET_PROTOCOL: MOV TRANSACTION, #NO_TRANSACTION MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #01H MOV I2C_BUFFER+3, BOOT_PROTOCOL; BOOT PROTOCOL SELECTION MOV RW_COUNTER, #03H AJMP WRITE_TO_EMB_IN RET; CLSS_FN_GET_PROTOCOL CLSS_FN_SET_REPORT: RET; CLSS_FN_SET_REPORT CLSS_FN_SET_IDLE: MOV FN_IDLE_TIME, I2C_BUFFER+OFFSET_wValue+1; DURATION OF IDLE MOV TRANSACTION, #NO_TRANSACTION ACALL SEND_FN_ZERO_PACKET RET; CLSS_FN_SET_IDLE CLSS_FN_SET_PROTOCOL: MOV BOOT_PROTOCOL, I2C_BUFFER+OFFSET_wValue ACALL SEND_FN_ZERO_PACKET RET; CLSS_FN_SET_PROTOCOL RESERVED: MOV TRANSACTION, #NO_TRANSACTION ACALL SEND_FN_STALL_ENDPT1 ACALL SEND_FN_STALL_ENDPT0 AJMP SEND_FN_STALL_INT RET; RESERVED ; Standard Requests REPLY_STD_FN_GET_STATUS: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_GET_STATUS0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A ANL A, #SPECIFIC_TRANSACTION SWAP A MOV DPTR, #REPLY_STD_FN_GET_STATUS1 MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #02H MOV I2C_BUFFER+4, #00H JMP @A+DPTR REPLY_STD_FN_GET_STATUS1: AJMP REPLY_FN_GET_DEVICE_STATUS AJMP REPLY_FN_GET_INTERFACE_STATUS AJMP REPLY_FN_GET_ENDPOINT_STATUS REPLY_FN_GET_DEVICE_STATUS: MOV TRANSACTION, #NO_TRANSACTION MOV A, #FN_DEVICE_STATUS JB EMBED_REMOTE_WKUP, REMOTE_WAKEUP_STATUS ANL A, #00000001B ; DON'T TOUCH BUS-POWERED REMOTE_WAKEUP_STATUS: MOV I2C_BUFFER+3, A MOV RW_COUNTER, #04H AJMP WRITE_TO_EMB_IN REPLY_FN_GET_INTERFACE_STATUS: MOV TRANSACTION, #NO_TRANSACTION MOV I2C_BUFFER+3, #FN_INTERFACE_STATUS MOV RW_COUNTER, #04H AJMP WRITE_TO_EMB_IN REPLY_FN_GET_ENDPOINT_STATUS: MOV TRANSACTION, #NO_TRANSACTION MOV I2C_BUFFER+3, END_PT_STALL MOV RW_COUNTER, #04H AJMP WRITE_TO_EMB_IN REPLY_STD_FN_GET_STATUS0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_STD_FN_CLEAR_FEATURE: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_CLEAR_FEATURE0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A ANL A, #SPECIFIC_TRANSACTION SWAP A MOV DPTR, #REPLY_STD_CLEAR_FEATURE1 JMP @A+DPTR REPLY_STD_CLEAR_FEATURE1: AJMP REPLY_FN_CLEAR_DEVICE_FEATURE AJMP REPLY_FN_CLEAR_INTERFACE_FEATURE AJMP REPLY_FN_CLEAR_ENDPOINT_FEATURE REPLY_FN_CLEAR_DEVICE_FEATURE: ACALL SEND_FN_ZERO_PACKET MOV TRANSACTION, #NO_TRANSACTION RET REPLY_FN_CLEAR_INTERFACE_FEATURE: ACALL SEND_FN_ZERO_PACKET MOV TRANSACTION, #NO_TRANSACTION RET REPLY_FN_CLEAR_ENDPOINT_FEATURE: MOV TRANSACTION, #NO_TRANSACTION CLR E_PORT_STALL ACALL SEND_FN_ZERO_PACKET ACALL SEND_FN_UNSTALL_ENDPT0 ACALL SEND_FN_UNSTALL_ENDPT1 ACALL SEND_FN_UNSTALL_INT RET REPLY_STD_FN_CLEAR_FEATURE0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_STD_FN_SET_FEATURE: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_SET_FEATURE0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A ANL A, #SPECIFIC_TRANSACTION SWAP A MOV DPTR, #REPLY_STD_SET_FEATURE1 JMP @A+DPTR REPLY_STD_SET_FEATURE1: AJMP REPLY_FN_SET_DEVICE_FEATURE AJMP REPLY_FN_SET_INTERFACE_FEATURE AJMP REPLY_FN_SET_ENDPOINT_FEATURE REPLY_FN_SET_DEVICE_FEATURE: ACALL SEND_FN_ZERO_PACKET MOV TRANSACTION, #NO_TRANSACTION RET REPLY_FN_SET_INTERFACE_FEATURE: ACALL SEND_FN_ZERO_PACKET MOV TRANSACTION, #NO_TRANSACTION RET REPLY_FN_SET_ENDPOINT_FEATURE: MOV TRANSACTION, #NO_TRANSACTION SETB E_PORT_STALL ACALL SEND_FN_ZERO_PACKET ACALL SEND_FN_STALL_ENDPT1 ACALL SEND_FN_STALL_ENDPT0 ACALL SEND_FN_STALL_INT RET REPLY_STD_FN_SET_FEATURE0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_STD_FN_SET_ADDRESS: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_SET_ADDRESS0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A ACALL SEND_FN_ZERO_PACKET RET REPLY_STD_FN_SET_ADDRESS0: ; Routine for every Ctrl-In entry MOV TRANSACTION, #NO_TRANSACTION MOV I2C_BUFFER,#SET_EMB_ADDRESS_EN MOV A,FN_ADDR ORL A,#080H MOV I2C_BUFFER+1,A ;ENABLE EMBEDDED FN ACALL WRITE_ONE_BYTE RET; REPLY_STD_FN_GET_DESCRIPTOR: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_GET_DESC0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A MOV FN_TRANSACTION_INDEX, #00H REPLY_STD_FN_GET_DESC0: ; Routine for every Ctrl-In entry ANL A, #SPECIFIC_TRANSACTION SWAP A MOV DPTR, #REPLY_STD_FN_GET_DESC1 JMP @A+DPTR REPLY_STD_FN_GET_DESC1: AJMP REPLY_FN_GET_DEVICE_DESC0 AJMP REPLY_FN_GET_CONFIG_DESC0 AJMP REPLY_FN_GET_STRING_DESC0 AJMP REPLY_FN_GET_INTERFACE_DESC0 AJMP REPLY_FN_GET_ENDPOINT_DESC0 AJMP REPLY_FN_GET_HID_DESC0 AJMP REPLY_FN_GET_REPORT_DESC0 REPLY_FN_GET_DEVICE_DESC0: MOV DPTR, #FN_STAND_DEV_DESC MOV FN_TRANSACTION_END, #12H AJMP SEND_FN_DATA REPLY_FN_GET_CONFIG_DESC0: MOV DPTR, #FN_CONFIG_DESC MOV FN_TRANSACTION_END, #22H AJMP SEND_FN_DATA REPLY_FN_GET_STRING_DESC0: MOV TRANSACTION, #NO_TRANSACTION AJMP SEND_FN_STALL_ENDPT1 REPLY_FN_GET_INTERFACE_DESC0: MOV DPTR, #FN_INTERFACE_DESC MOV FN_TRANSACTION_END, #09H AJMP SEND_FN_DATA REPLY_FN_GET_ENDPOINT_DESC0: MOV DPTR, #FN_ENDP1_INT_DESC MOV FN_TRANSACTION_END, #07H AJMP SEND_FN_DATA REPLY_FN_GET_HID_DESC0: MOV DPTR, #FN_HID_DESC MOV FN_TRANSACTION_END, #09H AJMP SEND_FN_DATA REPLY_FN_GET_REPORT_DESC0: MOV DPTR, #FN_REPORT_DESC MOV FN_TRANSACTION_END, #3FH AJMP SEND_FN_DATA REPLY_STD_FN_SET_DESCRIPTOR: ; NOT SUPPORTED ; MOV A, TRANSACTION ; JB ACC.0, REPLY_STD_FN_SET_DESC0 ; Routine for First Ctrl-In entry ; SETB ACC.0 ; MOV TRANSACTION, A REPLY_STD_FN_SET_DESC0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_STD_FN_GET_CONFIGURATION: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_GET_CONFIG0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #01H MOV I2C_BUFFER+3, #00H MOV RW_COUNTER, #03H MOV TRANSACTION, #NO_TRANSACTION JB EMBED_CONFIG, REPLY_FN_CONFIG REPLY_FN_NO_CONFIG: AJMP WRITE_TO_EMB_IN REPLY_FN_CONFIG: MOV I2C_BUFFER+3, #FN_CONFIGURED_STATUS AJMP WRITE_TO_EMB_IN REPLY_STD_FN_GET_CONFIG0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_STD_FN_SET_CONFIGURATION: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_SET_CONFIG0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A MOV TRANSACTION, #NO_TRANSACTION MOV A, FN_ADDR ORL A, #80H MOV FN_ADDR, A ACALL SEND_FN_ZERO_PACKET REPLY_STD_FN_SET_CONFIG0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_STD_FN_GET_INTERFACE: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_GET_INTERFACE0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #01H MOV I2C_BUFFER+3, #00H MOV RW_COUNTER, #03H AJMP WRITE_TO_EMB_IN REPLY_STD_FN_GET_INTERFACE0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_STD_FN_SET_INTERFACE: MOV A, TRANSACTION JB ACC.0, REPLY_STD_FN_SET_INTERFACE0 ; Routine for First Ctrl-In entry SETB ACC.0 MOV TRANSACTION, A MOV TRANSACTION, #NO_TRANSACTION ACALL SEND_FN_ZERO_PACKET REPLY_STD_FN_SET_INTERFACE0: ; Routine for every Ctrl-In entry ; AJMP SEND_FN_DATA RET; REPLY_STD_FN_SYNCH_FRAME: ; NOT SUPPORTED ;MOV A, TRANSACTION ;JB ACC.0, REPLY_STD_FN_SYNCH_FRAME0 ; Routine for First Ctrl-In entry ;SETB ACC.0 ;MOV TRANSACTION, A REPLY_STD_FN_SYNCH_FRAME0: ; Routine for every Ctrl-In entry ;AJMP SEND_FN_DATA RET; ; Class Requests REPLY_CLSS_FN_GET_REPORT: RET; REPLY_CLSS_FN_GET_IDLE: RET; REPLY_CLSS_FN_GET_PROTOCOL: RET; REPLY_CLSS_FN_SET_REPORT: RET; REPLY_CLSS_FN_SET_IDLE: RET; REPLY_CLSS_FN_SET_PROTOCOL: RET; REPLY_RESERVED: ACALL SEND_FN_STALL_ENDPT1 ACALL SEND_FN_STALL_ENDPT0 AJMP SEND_FN_STALL_INT RET SEND_FN_DATA: MOV I2C_BUFFER, #EMB_IN_STATUS ACALL READ_ONE_BYTE MOV A, I2C_BUFFER JB ACC.5, END_SEND_FN_DATA MOV I2C_BUFFER,#WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV RW_COUNTER, #00H MOV R0, #I2C_BUFFER+3 MOV R1, #08H FILL_FN_BUFFER: INC RW_COUNTER MOV A, FN_TRANSACTION_INDEX MOVC A, @A+DPTR INC FN_TRANSACTION_INDEX MOV @R0, A INC R0 MOV A, FN_TRANSACTION_INDEX CJNE A, FN_DATA_REQUEST_LENGTH, NEXT_CHECK_LEVEL MOV TRANSACTION, #NO_TRANSACTION AJMP END_FN_DATA NEXT_CHECK_LEVEL: CJNE A, FN_TRANSACTION_END, NEXT_CHECK_LEVEL1 ANL A, #00000111B JNZ NOT_MULTIPLE_OF_8 MULTIPLE_OF_8: AJMP END_FN_DATA NOT_MULTIPLE_OF_8: MOV TRANSACTION, #NO_TRANSACTION AJMP END_FN_DATA NEXT_CHECK_LEVEL1: CLR C SUBB A, FN_TRANSACTION_END JC MORE_FN_DATA ; FN_INDEX < FN_END MOV I2C_BUFFER+2, #00H MOV RW_COUNTER, #3 AJMP WRITE_TO_EMB_IN MORE_FN_DATA: DJNZ R1, FILL_FN_BUFFER END_FN_DATA: MOV R0, #I2C_BUFFER+2 MOV @R0, RW_COUNTER INC RW_COUNTER INC RW_COUNTER ACALL WRITE_TO_EMB_IN END_SEND_FN_DATA: RET ;======================================== ; Common H11 commands ;======================================== SEND_FN_ZERO_PACKET: MOV I2C_BUFFER,#SEL_FN_IN_ENDPT ACALL WRITE_COMMAND MOV I2C_BUFFER, #WRITE_BUFFER MOV I2C_BUFFER+1, #00H MOV I2C_BUFFER+2, #00H MOV I2C_BUFFER+3, #00H MOV RW_COUNTER, #03H ACALL WRITE_DATA MOV I2C_BUFFER,#VALIDATE_BUF ACALL WRITE_COMMAND RET SEND_FN_STALL_ENDPT1: MOV I2C_BUFFER, #EMB_ENDPT1_STATUS MOV I2C_BUFFER+1, #STALL_DATA MOV RW_COUNTER, #01H AJMP WRITE_DATA SEND_FN_STALL_ENDPT0: MOV I2C_BUFFER, #EMB_ENDPT0_STATUS MOV I2C_BUFFER+1, #STALL_DATA MOV RW_COUNTER, #01H AJMP WRITE_DATA SEND_FN_STALL_INT: MOV I2C_BUFFER, #EMB_INT_ENDPT_STATUS MOV I2C_BUFFER+1, #STALL_DATA MOV RW_COUNTER, #01H AJMP WRITE_DATA SEND_FN_UNSTALL_ENDPT1: MOV I2C_BUFFER, #EMB_ENDPT1_STATUS MOV I2C_BUFFER+1, #UNSTALL_DATA MOV RW_COUNTER, #01H AJMP WRITE_DATA SEND_FN_UNSTALL_ENDPT0: MOV I2C_BUFFER, #EMB_ENDPT0_STATUS MOV I2C_BUFFER+1, #UNSTALL_DATA MOV RW_COUNTER, #01H AJMP WRITE_DATA SEND_FN_UNSTALL_INT: MOV I2C_BUFFER, #EMB_INT_ENDPT_STATUS MOV I2C_BUFFER+1, #UNSTALL_DATA MOV RW_COUNTER, #01H AJMP WRITE_DATA ;======================================== ; Comms to H11 ;======================================== WRITE_ONE_BYTE: MOV RW_COUNTER,#1 AJMP WRITE_DATA WRITE_TWO_BYTE: MOV RW_COUNTER,#2 AJMP WRITE_DATA READ_ONE_BYTE: MOV RW_COUNTER,#1 AJMP READ_DATA ; Read N bytes from the selected Buffer ; N - RW_COUNTER ; DATA - I2C_BUFFER ;--------------------------------------- READ_FROM_HUB_OUT: MOV A, I2C_BUFFER PUSH ACC MOV I2C_BUFFER,#SEL_HUB_OUT_ENDPT ACALL WRITE_COMMAND ACALL READ_ONE_BYTE POP ACC MOV I2C_BUFFER, A SJMP READ_DATA READ_FROM_FN_OUT: MOV A, I2C_BUFFER PUSH ACC MOV A, RW_COUNTER PUSH ACC MOV I2C_BUFFER,#SEL_FN_OUT_ENDPT ACALL WRITE_COMMAND ACALL READ_ONE_BYTE POP ACC MOV RW_COUNTER, A POP ACC MOV I2C_BUFFER, A READ_DATA: MOV SLV_ADR,#COMMAND_ADDRESS ;WRITE COMMAND MOV CNT_BYTE,#1 ;NUMBER OF BYTES TO BE SENT ACALL WRITE_H11_POINT ;WRITE COMMAND MOV SLV_ADR,#DATA_READ_ADDR ;READ DATA MOV CNT_BYTE,RW_COUNTER ACALL READ_H11 RET; READ_FROM_H11 ; Write N bytes into the selected Buffer ; N - RW_COUNTER ; DATA - I2C_BUFFER ;--------------------------------------- WRITE_TO_HUB_IN: SETB VALIDATE_FLAG MOV I2C_BUFFER,#SEL_HUB_IN_ENDPT ACALL WRITE_COMMAND MOV I2C_BUFFER, #WRITE_BUFFER SJMP WRITE_DATA WRITE_TO_EMB_INT: SETB VALIDATE_FLAG MOV I2C_BUFFER,#SEL_FN_INT_ENDPT ACALL WRITE_COMMAND MOV I2C_BUFFER, #WRITE_BUFFER SJMP WRITE_DATA WRITE_TO_EMB_IN: SETB VALIDATE_FLAG MOV I2C_BUFFER,#SEL_FN_IN_ENDPT ACALL WRITE_COMMAND MOV I2C_BUFFER, #WRITE_BUFFER WRITE_DATA: ACALL WRITE_COMMAND MOV SLV_ADR,#DATA_WRITE_ADDR ;WRITE DATA MOV CNT_BYTE,RW_COUNTER ACALL WRITE_H11 JNB VALIDATE_FLAG, END_WRITE_TO_H11 MOV I2C_BUFFER,#VALIDATE_BUF ;READY DATA TO SEND ACALL WRITE_COMMAND CLR VALIDATE_FLAG END_WRITE_TO_H11: RET; WRITE_TO_H11 ; Write One Byte to Command Address ;---------------------------------- WRITE_COMMAND: MOV SLV_ADR,#COMMAND_ADDRESS ;WRITE COMMAND MOV CNT_BYTE,#1 ;NUMBER OF BYTES TO BE SENT ACALL WRITE_H11_POINT ;READ 1 BYTES RET; WRITE_COMMAND ; Read From H11: ADDR+DATA ; ADDR = SLR_ADR ; DATA = Pointer at I2C_BUFFER ; #DATA = CNT_Byte ;------------------------ READ_H11: MOV BYTE_CNT,CNT_BYTE ACALL GOMASTER ;ACQUIRE BUS AND SEND SLAVE ADDRESS. JB I2C_FAIL,READ_NOK ;CHECK FOR SLAVE NOT RESPONDING. MOV R0,#I2C_BUFFER ;SET FIRST RECEIVE DATA BUFFER ADDRESS READ_DATA_LOOP: ACALL RCV_BYTE ;RECEIVE DATA BYTE MOV @R0,A ;PUT RECEIVED DATA TO BUFFER INC R0 ;PREPARE NEXT BYTE DJNZ BYTE_CNT,READ_DATA_LOOP ;REPEAT UNTIL ALL BYTES RECEIVED READ_NOK: READ_OK: ACALL SEND_STOP ;DONE, SEND AN I2C STOP. RET; READ_H11 ; WRITE TO H11: ADDR+DATA ; ADDR = SLR_ADR ; DATA = Pointer at I2C_BUFFER ; #DATA = CNT_Byte ;------------------------ WRITE_H11_POINT: MOV R0,#I2C_BUFFER ;SET FIRST RECEIVE DATA BUFFER ADDRESS WRITE_H11: MOV BYTE_CNT,CNT_BYTE ACALL GOMASTER ;ACQUIRE BUS AND SEND SLAVE ADDRESS. JB I2C_FAIL,WRITE_NOK ;CHECK FOR SLAVE NOT RESPONDING.; WRITE_DATA_LOOP: MOV A,@R0 ;GET DATA BYTE FROM BUFFER. ACALL SEND_BYTE ;SEND NEXT DATA BYTE. INC R0 ;ADVANCE BUFFER POINTER. JB I2C_FAIL,WRITE_NOK ;CHECK FOR SLAVE NOT RESPONDING. DJNZ BYTE_CNT,WRITE_DATA_LOOP ;ALL BYTES SENT? WRITE_NOK: WRITE_OK: ACALL SEND_STOP ;DONE, SEND AN I2C STOP. RET; WRITE_H11_POINT ;SEND SLAVE ADDRESS TO H11 ;------------------------- GOMASTER: CLR I2C_FAIL ;CLEAR ERROR STATUS FLAGS. JNB SCLPIN,FAULT ;CHECK FOR BUS CLEAR. JNB SDAPIN,FAULT CLR SDAPIN ;BEGIN I2C START. ACALL BITDLY CLR SCLPIN ACALL BITDLY ;COMPLETE I2C START. MOV A,SLV_ADR ;GET SLAVE ADDRESS. ACALL SEND_BYTE ;SEND SLAVE ADDRESS. RET; GOMASTER FAULT: SETB I2C_FAIL ;SET FAULT STATUS AND EXIT RET ;======================================== ; I2C ROUTINES ;======================================== RCV_BYTE: MOV BITCNT,#8 ;SET BIT COUNT. RCV_LOOP: ACALL SCLHIGH ;READ ONE DATA BIT. ACALL BITDLY MOV C,SDAPIN ;GET DATA BIT FROM PIN. RLC A ;ROTATE BIT INTO RESULT BYTE. CLR SCLPIN ACALL BITDLY DJNZ BITCNT,RCV_LOOP ;REPEAT UNTIL ALL BITS RECEIVED. PUSH ACC ;SAVE ACCUMULATOR MOV A,BYTE_CNT CJNE A,#1,SRBACK ;CHECK FOR LAST BYTE OF FRAME. SETB SDAPIN ;SEND NO ACKNOWLEDGE ON LAST BYTE. SJMP SRBACLK ;NO ACK WHEN IT'S LAST BYTE SRBACK: CLR SDAPIN ;SEND ACKNOWLEDGE BIT. SRBACLK: ACALL SCLHIGH ;SEND ACKNOWLEDGE CLOCK. POP ACC ;RESTORE ACCUMULATOR ACALL BITDLY CLR SCLPIN SETB SDAPIN ;CLEAR ACKNOWLEDGE BIT. ACALL BITDLY RET; RCV_BYTE ;----------------------------------- SEND_BYTE: MOV BITCNT,#8 ;SET BIT COUNT. SBLOOP: RLC A ;SEND ONE DATA BIT. MOV SDAPIN,C ;PUT DATA BIT ON PIN. ACALL SCLHIGH ;SEND CLOCK. ACALL BITDLY CLR SCLPIN ACALL BITDLY DJNZ BITCNT,SBLOOP ;REPEAT UNTIL ALL BITS SENT. SETB SDAPIN ;RELEASE DATA LINE FOR ACKNOWLEDGE. ACALL SCLHIGH ;SEND CLOCK FOR ACKNOWLEDGE. ACALL BITDLY JNB SDAPIN,SBEX ;CHECK FOR VALID ACKNOWLEDGE BIT. SETB I2C_FAIL ;SET STATUS FOR NO ACKNOWLEDGE. SBEX: CLR SCLPIN ;FINISH ACKNOWLEDGE BIT. ACALL BITDLY RET; SEND_BYTE ;----------------------------------- SCLHIGH: SETB SCLPIN ;Set SCL from our end. JNB SCLPIN,$ ;Wait for pin to actually go high. RET; SCLHIGH ;----------------------------------- SEND_STOP: CLR SDAPIN ;Get SDA ready for stop. ACALL SCLHIGH ;SET CLOCK FOR STOP. ACALL BITDLY SETB SDAPIN ;SEND I2C STOP. ACALL BITDLY RET; SEND_STOP ;BUS SHOULD NOW BE RELEASED. ;----------------------------------- BITDLY: ;NOPS TO DELAY 5 MICROSECONDS (MINUS 4 RET; BITDLY ;---------------------------------------- ; Addition for HUB function ;---------------------------------------- SEND_TO_HOST: MOV A,@R0 ;SEND DATA LENGTH CLR C ;R0 = BYTE_TO_SEND SUBB A,#08H JNC SEND01 MOV A,@R0 MOV R1,A ;NUMBER BYTES TO SEND ADD A,#2 MOV RW_COUNTER,A ;TOTAL BYTES TO SEND MOV BYTE_TO_SEND,#0 ;REMAIN BYTES TO SEND LJMP SEND02 ;----- SEND01: MOV BYTE_TO_SEND,A ;REMAIN BYTES MOV R1,#8 MOV RW_COUNTER,#0AH ;TOTAL BYTES TO SEND ;----- SEND02: ;---- MOV I2C_BUFFER,#SEL_EPOINT_0_IN LCALL WRITE_COMMAND ;---- 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 ;--- SEND03: CLR A MOVC A,@A+DPTR MOV @R0,A INC R0 INC DPTR DJNZ R1,SEND03 ;--- MOV MSG_DPH,DPH MOV MSG_DPL,DPL ;--- LCALL WRITE_N_BYTE ;--- RET READ_TEN_BYTE: MOV RW_COUNTER,#10 LJMP READ_DATA READ_TWO_BYTE: MOV RW_COUNTER,#2 LJMP READ_DATA SEND_EP0I_STALL: MOV I2C_BUFFER,#SET_EPT0_IN_ST ;SET ENDPOINT 0 MOV I2C_BUFFER+1,#01H ;SET ENDPOINT STALL LCALL WRITE_ONE_BYTE RET SEND_ZERO_PACKET: MOV I2C_BUFFER,#SEL_EPOINT_0_IN LCALL WRITE_COMMAND MOV I2C_BUFFER,#WRITE_BUFFER MOV I2C_BUFFER+1,#0 MOV I2C_BUFFER+2,#0 MOV I2C_BUFFER+3,#0 LCALL WRITE_THREE_BYTE RET WRITE_THREE_BYTE: MOV RW_COUNTER,#3 LJMP WRITE_TO_HUB_IN WRITE_FOUR_BYTE: MOV RW_COUNTER,#4 LJMP WRITE_TO_HUB_IN WRITE_SIX_BYTE: MOV RW_COUNTER,#6 LJMP WRITE_TO_HUB_IN WRITE_N_BYTE: LJMP WRITE_TO_HUB_IN ;---------------------------------------- ; End of addition for HUB function ;---------------------------------------- ;======================================== ; HUB CODE ;======================================== ;======================== HUB_CTRL_IN: MOV I2C_BUFFER,#READ_LAST_EPT0_IN_ST ;READ ENDPOINT STATUS FROM H11 LCALL READ_ONE_BYTE ;------ MOV I2C_BUFFER,#SEL_EPOINT_0_IN LCALL READ_ONE_BYTE MOV A,I2C_BUFFER ANL A,#00000001B ;IS BUFFER EMPTY? JNZ END_IN ;------ SET_HUB_ADDR: MOV A,LAST_COM CJNE A,#REQ_SET_ADDRESS,MORE_MESSAGE ;STILL HAVE DATA TO SEND MOV LAST_COM,#0 ;---- MOV I2C_BUFFER,#SET_HUB_ADDRESS_EN ;WRITE NEW ADDRESS TO HUB MOV A,HUB_ADDR ORL A,#080H MOV I2C_BUFFER+1,A LCALL WRITE_ONE_BYTE RET ;----- MORE_MESSAGE: MOV R0,#BYTE_TO_SEND MOV A,@R0 JZ END_IN MOV DPH,MSG_DPH MOV DPL,MSG_DPL LCALL SEND_TO_HOST END_IN: RET ;======================== HUB_CTRL_OUT: ;==== MOV I2C_BUFFER,#READ_LAST_EPT0_OUT_ST ;READ ENDPOINT STATUS FROM H11 LCALL READ_ONE_BYTE ; ;------ MOV I2C_BUFFER,#READ_EPT0_OUT_ST ;READ ENDPOINT STATUS FROM H11 LCALL READ_ONE_BYTE ; ;------ MOV A,I2C_BUFFER ANL A,#00000100B JNZ READ_SETUP_DATA ;SETUP PACKET IS NOT ACK RET ;--------------------------- ;MAYBE OUT TOKEN READ_SETUP_DATA: ;------ MOV I2C_BUFFER,#SEL_EPOINT_0_IN LCALL WRITE_COMMAND ;----- MOV I2C_BUFFER,#ACK_SETUP ;SEND ACK TO ENDPOINT 0 IN LCALL WRITE_COMMAND ;--------------------------- MOV I2C_BUFFER,#SEL_EPOINT_0_OUT LCALL WRITE_COMMAND ;----- MOV I2C_BUFFER,#ACK_SETUP ;SEND ACK TO ENDPOINT 0 OUT LCALL WRITE_COMMAND ;--------------------------- MOV I2C_BUFFER,#READ_BUFFER ;SEND READ BUFFER CMD TO H11 LCALL READ_TEN_BYTE ;------ MOV I2C_BUFFER,#CLEAR_BUF ;RELEASE BUFFER LCALL WRITE_COMMAND ;----- MOV A,I2C_BUFFER+1 ;READ TOTAL HOW MANY BYTES CJNE A,#8,END_READ_SETUP ;NOT CORRECT COMMAND FROM HOST SJMP DECODE_REQUEST END_READ_SETUP: RET ;----------------------------------------------------------------- ; DECODE HUB ENDPOINT 0 STANDARD REQUEST COMMAND ;----------------------------------------------------------------- DECODE_REQUEST: ;--- MOV R2,I2C_BUFFER+OFFSET_bmReqTyp MOV R3,I2C_BUFFER+OFFSET_bmReq MOV R4,I2C_BUFFER+OFFSET_wValue MOV R5,I2C_BUFFER+OFFSET_wIndex MOV R6,I2C_BUFFER+OFFSET_wLenght ;============================ MOV A,R2 ;I2C_BUFFER+OFFSET_bmReqTyp ANL A,#01100000B JZ STANDARD_REQUEST LJMP CLASS_REQUEST ;--------- STANDARD_REQUEST: MOV A,R3 ;I2C_BUFFER+OFFSET_bmReq JZ GET_STATUS_P ;0 DEC A JZ CLEAR_FEATURE_P ;1 DEC A ;2 UNDEFINED DEC A JZ SET_FEATURE_P ;3 DEC A ;4 UNDEFINED DEC A JZ SET_ADDRESS ;5 DEC A JZ GET_DESCRIPTOR_P ;6 DEC A ;7 SET_DESCRIPTOR, NO SUPPORT DEC A JZ GET_CONFIG ;8 DEC A JZ SET_CONFIG ;9 DEC A JZ GET_INTERFACE ;A DEC A JZ SET_INTERFACE ;B ;----- NO_SUPPORT_REQ: LCALL SEND_EP0I_STALL ;10 - GET INTERFACE, NO SUUPORT RET ;11 - SET INTERFACE, NO SUPPORT ;12 - SYNCH FRAME, NO SUPPORT ;------------------------------------ GET_STATUS_P: LJMP GET_STATUS CLEAR_FEATURE_P: LJMP CLEAR_FEATURE SET_FEATURE_P: ;3 LJMP SET_FEATURE GET_DESCRIPTOR_P: ;6 LJMP GET_DESCRIPTOR ;================================================================= SET_INTERFACE: LCALL SEND_ZERO_PACKET RET ;----- GET_INTERFACE: MOV I2C_BUFFER,#WRITE_BUFFER ;WRITE BUFFER COMMAND MOV I2C_BUFFER+1,#0 MOV I2C_BUFFER+2,#1 MOV I2C_BUFFER+3,#0 LCALL WRITE_THREE_BYTE RET ;------ ;================================================================= SET_ADDRESS: ;5 MOV R0,#I2C_BUFFER+OFFSET_wValue MOV HUB_ADDR,@R0 LCALL SEND_ZERO_PACKET ; MOV LAST_COM,#REQ_SET_ADDRESS ; MOV BYTE_TO_SEND,#0 ;-- WAIT_FOR_CHANGE: MOV I2C_BUFFER,#READ_INT ;READ INTERRUPT REGISTER LCALL READ_ONE_BYTE ;READ DATA FROM H11 MOV A,I2C_BUFFER JNB ACC.1, WAIT_FOR_CHANGE MOV I2C_BUFFER,#SET_HUB_ADDRESS_EN ;WRITE NEW ADDRESS TO HUB MOV A,HUB_ADDR ORL A,#080H MOV I2C_BUFFER+1,A LCALL WRITE_ONE_BYTE MOV BYTE_TO_SEND,#0 RET ;=============================================================== GET_CONFIG: ;8 ;--- MOV I2C_BUFFER,#WRITE_BUFFER ;WRITE BUFFER COMMAND MOV I2C_BUFFER+1,#0 MOV I2C_BUFFER+2,#1 MOV I2C_BUFFER+3,#0 JB HUB_CONFIG,HUB_HAD_CONFIG GET_CONFIG_1: LCALL WRITE_THREE_BYTE RET HUB_HAD_CONFIG: MOV I2C_BUFFER+3,#1 LJMP GET_CONFIG_1 ;================================================================== SET_CONFIG: ;9 MOV A,R4 JZ DISABLE_CONFIG CJNE A,#1,NO_SUPPORT_REQ ;WRONG_SET_CONFIG ;----- SETB HUB_CONFIG MOV I2C_BUFFER,#SET_EPOINT_EN MOV I2C_BUFFER+1,#01H SET_CONFIG_1: LCALL WRITE_ONE_BYTE ;--- LCALL SEND_ZERO_PACKET RET ;---- DISABLE_CONFIG: CLR HUB_CONFIG MOV I2C_BUFFER,#SET_EPOINT_EN MOV I2C_BUFFER+1,#00H LJMP SET_CONFIG_1 ;================================================================= ; GET HUB OR PORT STATUS FROM H11 ;------------------------------------ GET_STATUS: ;0 ;----- 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 ;I2C_BUFFER+OFFSET_bmReqTyp ANL A,#00000011B JZ GET_DEVICE_STATUS DEC A JZ GET_IF_STATUS DEC A JZ GET_EPT_STATUS GET_WRONG_RECIPIENT: LJMP NO_SUPPORT_REQ ;----- GET_DEVICE_STATUS: MOV A,FLAG_STATUS ANL A,#00000011B MOV I2C_BUFFER+3,A ;STATUS OF SELF POWER AND REMOTE WAKEUP GET_IF_STATUS: HUB_EPT0_OUT: EPT_UN_STALL: LCALL WRITE_FOUR_BYTE ;WRITE FOUR BYTES TO H11 RET ;----- GET_EPT_STATUS: MOV A,R5 ;I2C_BUFFER+OFFSET_wIndex JZ HUB_EPT0_OUT ;SHOULD BE UN_STALL ;--- XRL A,#080H JZ HUB_EPT0_IN ;HUB EPT0 IN ;--- MOV A,R5 XRL A,#081H JZ HUB_EPT1_IN ;HUB EPT0 OUT LJMP NO_SUPPORT_REQ ;----- HUB_EPT0_IN: JNB EPT0_OUT_STALL,EPT_UN_STALL ;HUB EPT0 IN UN_STALL ;----- EPT_STALL: MOV I2C_BUFFER+3,#1 ;HUB EPT0 IN STALL AJMP EPT_UN_STALL ;----- HUB_EPT1_IN: JNB EPT1_IN_STALL,EPT_UN_STALL ;HUB EPT1 IN UN_STALL AJMP EPT_STALL ;HUB EPT1 IN STALL ;================================================================== ; CLEAR DEVICE,INTERFACE,ENDPOINT FEATURE ;---------------------------------------- CLEAR_FEATURE: ;1 MOV A,R2 ;I2C_BUFFER+OFFSET_bmReqTyp JZ CLEAR_DEVICE_FEATURE DEC A JZ CLEAR_INTERFACE_FEATURE DEC A JZ CLEAR_EPT_FEATURE ;----- CLEAR_INTERFACE_FEATURE: LJMP NO_SUPPORT_REQ ;----- CLEAR_DEVICE_FEATURE: CLR REMOTE_WAKE ;*** bug fix of chapter 11, kbhub214.asm MOV I2C_BUFFER,#0F3H MOV I2C_BUFFER+1,#10110100B LCALL WRITE_ONE_BYTE ;*** end of bug fix CLEAR_FEATURE_RET: CLR_EPT0_OUT: LCALL SEND_ZERO_PACKET RET ;--------------------------------- ;CLEAR ENDPOINR FEATURE CLEAR_EPT_FEATURE: MOV A,R5 ;I2C_BUFFER+OFFSET_wIndex JZ CLR_EPT0_OUT ;SHOULD BE UN_STALL ;--- XRL A,#080H JZ CLR_EPT0_IN ;HUB EPT0 IN ;--- MOV A,R5 XRL A,#081H JZ CLR_EPT1_IN LJMP NO_SUPPORT_REQ ;---------------- CLR_EPT0_IN: CLR EPT0_IN_STALL ;HUB EPT0 IN STALL FLAG MOV I2C_BUFFER,#SEL_EPOINT_0_IN ;ENDPOINT 0 IN MOV I2C_BUFFER+1,#0 ;CLEAR ENDPOINT STALL CONDITION LCALL WRITE_ONE_BYTE AJMP CLEAR_FEATURE_RET ;--------------- CLR_EPT1_IN: CLR EPT1_IN_STALL AJMP CLEAR_FEATURE_RET ;========================================================= SET_FEATURE: ;3 MOV A,R2 ;I2C_BUFFER+OFFSET_bmReqTyp JZ SET_DEVICE_FEATURE DEC A JZ SET_INTERFACE_FEATURE DEC A JZ SET_EPT_FEATURE ;----- SET_INTERFACE_FEATURE: NO_SUPPORT_REQ1: LJMP NO_SUPPORT_REQ ;---- SET_DEVICE_FEATURE: SETB REMOTE_WAKE ;*** bug fix of chapter 11, kbhub214.asm MOV I2C_BUFFER,#0F3H MOV I2C_BUFFER+1,#10110101B LCALL WRITE_ONE_BYTE ;*** end of bug fix SET_FEATURE_RET: SET_EPT0_OUT: LCALL SEND_ZERO_PACKET RET ;--------------------------------- ;CLEAR ENDPOINR FEATURE SET_EPT_FEATURE: MOV A,R5 ;I2C_BUFFER+OFFSET_wIndex JZ SET_EPT0_OUT ;SHOULD BE UN_STALL ;--- XRL A,#080H JZ SET_EPT0_IN ;HUB EPT0 IN ;--- MOV A,R5 XRL A,#081H JZ SET_EPT1_IN LJMP NO_SUPPORT_REQ ;---------------- SET_EPT0_IN: SETB EPT0_IN_STALL ;HUB EPT0 IN STALL FLAG MOV I2C_BUFFER,#SET_EPT0_IN_ST ;ENDPOINT 0 IN MOV I2C_BUFFER+1,#1 ;SETR ENDPOINT STALL CONDITION LCALL WRITE_ONE_BYTE AJMP SET_FEATURE_RET ;--------------- SET_EPT1_IN: SETB EPT1_IN_STALL AJMP SET_FEATURE_RET ;------- ;======================================================= 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 ;---- CHK_DEV_DESC: CJNE A,#01,CHK_CONF_DESC MOV DPTR,#STAND_DEV_DESC MOV R0,#I2C_BUFFER+OFFSET_wLenght ;--- INC R0 ;IF HOST ISSUE OVER 256 BYTES MOV A,@R0 JNZ CHK_DEV_DESC1 DEC R0 ;--- MOV A,@R0 CLR C SUBB A,#18 JC SEND_DESCRIPTOR CHK_DEV_DESC1: MOV @R0,#18 AJMP SEND_DESCRIPTOR ;---- CHK_CONF_DESC: CJNE A,#02,NO_SUPPORT_REQ1 MOV DPTR,#CONFIG_DESC MOV R0,#I2C_BUFFER+OFFSET_wLenght ;--- INC R0 ;IF HOST ISSUE OVER 256 BYTES MOV A,@R0 JNZ CHK_CONF_DESC1 ;-- DEC R0 MOV A,@R0 CLR C SUBB A,#25 JC SEND_DESCRIPTOR CHK_CONF_DESC1: MOV @R0,#25 ;---- SEND_DESCRIPTOR: LCALL SEND_TO_HOST RET ;******************************************************* ; MOV R2,I2C_BUFFER+OFFSET_bmReqTyp ; MOV R3,I2C_BUFFER+OFFSET_bmReq ; MOV R4,I2C_BUFFER+OFFSET_wValue ; MOV R5,I2C_BUFFER+OFFSET_wIndex ; MOV R6,I2C_BUFFER+OFFSET_wLenght ;******************************************************* CLASS_REQUEST: MOV A,R3 ;I2C_BUFFER+OFFSET_bmReq JZ GET_C_STATUS ;0 DEC A JZ CLEAR_C_FEATURE_P ;1 DEC A ;;; JZ GET_C_STATE ;2 NO SUPPORT DEC A JZ SET_C_FEATURE_P ;3 DEC A ;4 DEC A ;5 DEC A JZ GET_C_DESCRIPTOR ;6 ;; DEC A ;; JZ SET_C_DESCRIPTOR ;7 NO SUPPORT ;-------- NO_SUPPORT_REQ2: LJMP NO_SUPPORT_REQ SET_C_FEATURE_P: LJMP SET_C_FEATURE CLEAR_C_FEATURE_P: LJMP CLEAR_C_FEATURE ;1 ;========================================= GET_C_DESCRIPTOR: ;6 MOV A,I2C_BUFFER+OFFSET_wValue+1 ;I2C_BUFFER+OFFSET_wValue+1 XRL A,#029H JNZ HUB_DESC_TYPE_00 MOV DPTR,#HUB_DESC2 ;FOR USB SPEC 1.1 AJMP HUB_DESC_TYPE_29 ;---- HUB_DESC_TYPE_00: MOV DPTR,#HUB_DESC1 HUB_DESC_TYPE_29: MOV R0,#I2C_BUFFER+OFFSET_wLenght MOV A,@R0 CLR C SUBB A,#9 JC SEND_HUB_DESCRIPTOR MOV @R0,#9 AJMP SEND_HUB_DESCRIPTOR SEND_HUB_DESCRIPTOR: LCALL SEND_TO_HOST RET ;========================================= GET_C_STATUS: ;0 GET CLASS STATUS MOV A,R5 JZ GET_HUB_STATUS DEC A JZ GET_PORT1_STATUS DEC A JZ GET_PORT2_STATUS DEC A JZ GET_PORT3_STATUS DEC A JZ GET_PORT4_STATUS DEC A JZ GET_PORT5_STATUS NO_SUPPORT_REQ3: LJMP NO_SUPPORT_REQ ;---------------------------------------- GET_HUB_STATUS: MOV I2C_BUFFER,#0E0H LCALL READ_TWO_BYTE ;---- MOV A,I2C_BUFFER+1 ;SECOND BYTE RR A RR A ANL A,#00000010B MOV R6,A MOV R7,A AJMP SEND_STATUS_HOST GET_PORT1_STATUS: MOV I2C_BUFFER,#SET_STATUS_CHG_BITS ;INFORM HOST, CURRENT EMBEDDED MOV I2C_BUFFER+1,#00 ;FUNCTION IS LOSE MOV I2C_BUFFER+1, #00H LCALL WRITE_ONE_BYTE MOV R6,EMBED_STATUS0 MOV R7,EMBED_STATUS1 AJMP SEND_STATUS_HOST ;----- GET_PORT2_STATUS: GET_PORT3_STATUS: GET_PORT4_STATUS: GET_PORT5_STATUS: MOV A,R5 DEC A DEC A ORL A,#0E0H MOV I2C_BUFFER,A LCALL READ_TWO_BYTE ;--- MOV R6,I2C_BUFFER ;FIRST BYTE MOV R7,I2C_BUFFER+1 ;SECOND BYTE ;--- SEND_STATUS_HOST: ;--- MOV I2C_BUFFER,#WRITE_BUFFER MOV I2C_BUFFER+1,#0 MOV I2C_BUFFER+2,#4 ;--- MOV A,R6 ANL A,#00011111B MOV I2C_BUFFER+3,A ;--- MOV A,R6 SWAP A RR A ANL A,#00000011B MOV I2C_BUFFER+4,A ;--- MOV A,R7 ANL A,#00011111B MOV I2C_BUFFER+5,A ;---- MOV I2C_BUFFER+6,#0 ;---- LCALL WRITE_SIX_BYTE RET ;====================================== CLEAR_C_FEATURE: ;1 GET CLASS FEATURE JNB HUB_CONFIG,NO_SUPPORT_REQ3 ;HUB NOT CONFIGURATION,SEND STALL ;--- MOV A,R5 ; JZ CLEAR_HUB_FEATURE ;CLEAR HUB FEATURE DEC A JNZ CLEAR_DN_PORT AJMP CLEAR_PORT0_FEATURE ;CLEAR EMBED PORT FEATURE ;------ CLEAR_DN_PORT: DEC A MOV R1,A ANL A,#11111100B JNZ NO_SUPPORT_REQ3 ;OVER PORT5, NO SUPPORT ;--- MOV A,R1 ORL A,#0E0H ;CLEAR PORT2-5 FEATURE MOV R1,A ;E0-E3 ;----- CLEAR_PORT_FEATURE: MOV A,R4 ;; JZ ;0 PORT CONNECTION DEC A JZ CL_PORT_ENABLE ;1 DEC A JZ CL_PORT_SUSPEND ;2 CLR C ;3,4 SUBB A,#6 JZ CL_PORT_POWER ;8 CLEAR PORT POWER CLR C SUBB A,#8 JZ CL_C_PORT_CONN ;16 DEC A JZ CL_C_PORT_ENABLE ;17 DEC A JZ CL_C_PORT_SUSPEND ;18 DEC A JZ CL_C_PORT_OVER_CURR ;19 DEC A JZ CL_C_PORT_RESET ;20 NO_SUPPORT_REQ4: LJMP NO_SUPPORT_REQ ;------------------------------------------- CL_PORT_ENABLE: MOV R6,#F_PORT_ENABLE ;1 AJMP VALID_CL_FEATURE ;----------- CL_PORT_SUSPEND: MOV R6,#F_PORT_SUSPEND ;2 AJMP VALID_CL_FEATURE ;---------- CL_PORT_POWER: MOV EMBED_STATUS0,#0 ;8 ALL EMBED STATUS SHOULD BE CLEAR MOV EMBED_STATUS1,#0 ;--- MOV R6,#F_PORT_POWER ;8 AJMP VALID_CL_FEATURE ;---------- CL_C_PORT_CONN: MOV R6,#C_PORT_CONN ;16 AJMP VALID_CL_FEATURE ;---------- CL_C_PORT_ENABLE: MOV R6,#C_PORT_ENABLE ;17 AJMP VALID_CL_FEATURE ;----------- CL_C_PORT_SUSPEND: MOV R6,#C_PORT_SUSPEND ;18 AJMP VALID_CL_FEATURE ;----------- CL_C_PORT_OVER_CURR: MOV R6,#C_PORT_OVERCUR ;19 AJMP VALID_CL_FEATURE ;----------- CL_C_PORT_RESET: MOV R6,#FC_PORT_RESET ;20 ;----- VALID_CL_FEATURE: ;--- MOV I2C_BUFFER,R1 MOV I2C_BUFFER+1,R6 LCALL WRITE_ONE_BYTE ;--- LCALL SEND_ZERO_PACKET CL_RET: RET ;--------------- CLEAR_HUB_FEATURE: MOV A,R4 JB ACC.0,CLEAR_HUB_OVERCURRENT ;NO SUPPORT FEATURE SELECTORS AJMP NO_SUPPORT_REQ4 CLEAR_HUB_OVERCURRENT: MOV R1,#0E0H ;CLEAR PORT2-5 OVERCURRENT AJMP CL_C_PORT_OVER_CURR ;===================---------------- CLEAR_PORT0_FEATURE: MOV A,R4 ;; JZ ;0 PORT CONNECTION DEC A JZ CL_PORT0_ENABLE ;IGNORE 1:CL_PORT0_ENABLE DEC A JZ CL_PORT0_SUSPEND ;IGNORE 2:CL_PORT0_SUSPEND CLR C ;3,4 SUBB A,#6 JZ CL_PORT0_POWER ;IGNORE 8:CLEAR PORT POWER CLR C SUBB A,#8 JZ CL_PORT0_OK ;IGNORE 16:CL_C_PORT0_CONN DEC A JZ CL_PORT0_C_ENABLE ;IGNORE 17:CL_C_PORT0_ENABLE DEC A JZ CL_PORT0_C_SUSPEND ;IGNORE 18:CL_C_PORT0_SUSPEND DEC A JZ CL_PORT0_OK ;IGNORE 19:CL_C_PORT0_OVER_CURR DEC A JZ CL_PORT0_RESET ;IGNORE 20:CL_C_PORT0_RESET LJMP NO_SUPPORT_REQ ;------------------------------ CL_PORT0_SUSPEND: CLR E_PORT_SUSPEND SETB E_C_PORT_SUSPEND MOV I2C_BUFFER,#SET_STATUS_CHG_BITS ;INFORM HOST, CURRENT EMBEDDED MOV I2C_BUFFER+1,#02 ;FUNCTION IS LOSE LCALL WRITE_ONE_BYTE ;---- AJMP CL_PORT0_OK CL_PORT0_C_SUSPEND: CLR E_C_PORT_SUSPEND AJMP CL_PORT0_OK CL_PORT0_POWER: MOV I2C_BUFFER,#SET_EMB_ADDRESS_EN ;DISABLE EMBED ADDRESS MOV I2C_BUFFER+1,#00 LCALL WRITE_ONE_BYTE ;---- MOV I2C_BUFFER,#SET_STATUS_CHG_BITS ;INFORM HOST, CURRENT EMBEDDED MOV I2C_BUFFER+1,#02 ;FUNCTION IS LOSE LCALL WRITE_ONE_BYTE ;---- MOV R1,#0E0H AJMP CL_PORT_POWER CL_PORT0_RESET: CLR E_C_PORT_RESET LCALL SEND_ZERO_PACKET RET ;---- CL_PORT0_C_ENABLE: CLR E_C_PORT_ENABLE AJMP CL_PORT0_OK ;---- CL_PORT0_ENABLE: JNB E_PORT_ENABLE,CL_PORT0_OK ;PORT0 CURRENT IS DISBALE SETB E_C_PORT_ENABLE ;PORT0 CURRENT IS ENABLE, SET CHNAGE BIT CLR E_PORT_ENABLE ;CLEAR PROT0 ENABLE ;--- MOV I2C_BUFFER,#SET_EMB_ADDRESS_EN ;DISABLE EMBED ADDRESS MOV I2C_BUFFER+1,#00 LCALL WRITE_ONE_BYTE ;--- CL_PORT0_OK: LCALL SEND_ZERO_PACKET RET ;========================================== SET_C_FEATURE: ;3 JNB HUB_CONFIG,NO_SUPPORT_REQ5 ;HUB NOT CONFIGURATION ;----- MOV A,R5 ;I2C_BUFFER+OFFSET_wIndex JZ NO_SUPPORT_REQ5 ;SET HUB FEATURE DEC A JZ SET_PORT0_FEATURE ;SET EMBEDED PORT FEATURE SET_PORT_FEATURE: DEC A MOV R1,A ;PORT2-5 ANL A,#11111100B JNZ NO_SUPPORT_REQ5 ;OVER PORT 5 MOV A,R1 ORL A,#0E8H MOV R1,A ;E8,9,A,B ;----- SET_FEATURE_TABLE: MOV A,R4 ;; JZ ;0 PORT CONNECTION DEC A JZ SET_PORT_ENABLE ;1 DEC A JZ SET_PORT_SUSPEND ;2 DEC A ;3 DEC A JZ SET_PORT_RESET ;4 DEC A ;5 DEC A ;6 DEC A ;7 DEC A JZ SET_PORT_POWER ;8 CLEAR PORT POWER NO_SUPPORT_REQ5: LJMP NO_SUPPORT_REQ ;------------------------------------------- SET_PORT_ENABLE: MOV R6,#F_PORT_ENABLE ;1 AJMP VALID_SET_FEATURE ;-------------------- SET_PORT_SUSPEND: MOV R6,#F_PORT_SUSPEND ;2 AJMP VALID_SET_FEATURE ;------------------ SET_PORT_RESET: MOV R6,#FC_PORT_RESET ;4 AJMP VALID_SET_FEATURE ;------------------ SET_PORT_POWER: SETB E_PORT_POWER ;WHEN ONE PORT HAS POWER TEHN EVERY ONE HAS POWER SETB E_PORT_CONN ;THE PORT0 IS ALWAYS CONNECTED TO HUB ;---- MOV R6,#F_PORT_POWER ;8 ;---- MOV I2C_BUFFER,R1 MOV I2C_BUFFER+1,R6 LCALL WRITE_ONE_BYTE ;--- VALID_SET_FEATURE: AJMP VALID_CL_FEATURE ;======================----------------- SET_PORT0_FEATURE: MOV A,R4 ;;; JZ ;0 PORT CONNECTION DEC A JZ SET_PORT0_ENABLE ;IGNORE 1:SET_PORT_ENABLE DEC A JZ SET_PORT0_SUSPEND ;IGNORE 2:SET_PORT_SUSPEND DEC A ;3 DEC A JZ SET_PORT0_RESET ;IGNORE 4:SET_PORT0_RESET DEC A ;5 DEC A ;6 DEC A ;7 DEC A JZ SET_PORT0_POWER ;8 SET PORT POWER LJMP NO_SUPPORT_REQ ;------------------------------------------- SET_PORT0_SUSPEND: ;SETB E_C_PORT_SUSPEND SETB E_PORT_SUSPEND AJMP SET_PORT0_OK SET_PORT0_POWER: MOV I2C_BUFFER,#SET_STATUS_CHG_BITS ;INFORM HOST, CURRENT EMBEDDED MOV I2C_BUFFER+1,#02 ;FUNCTION IS ATTACHED LCALL WRITE_ONE_BYTE ;---- MOV R1, #0E8H ; H11 IS GANG POWER HUB AJMP SET_PORT_POWER SET_PORT0_OK: LCALL SEND_ZERO_PACKET RET H11_RET2: RET ;--------------------- SET_PORT0_RESET: JNB E_PORT_POWER,SET_PORT0_OK ;PORT0 NO POWER ;-------------- MOV I2C_BUFFER,#SET_STATUS_CHG_BITS ;INFORM HOST, CURRENT EMBEDDED MOV I2C_BUFFER+1,#02 ;FUNCTION IS LOSE LCALL WRITE_ONE_BYTE ;------------- SETB E_C_PORT_RESET ;SETTING PORT RESET READY FLAG MOV EMB_ADDR,#0 CLR E_C_PORT_SUSPEND CLR E_PORT_SUSPEND AJMP SET_PORT0_1 ;--------------------- SET_PORT0_ENABLE: JNB E_PORT_POWER,SET_PORT0_OK ;PORT0 NO POWER JB E_PORT_ENABLE,SET_PORT0_OK ;CURRENT IS ENABLE SETB E_C_PORT_ENABLE ;CURRENT IS DISBALE ;--- SET_PORT0_1: SETB E_PORT_ENABLE ;SET PROT0 ENABLE ;---- MOV I2C_BUFFER,#SET_EMB_ADDRESS_EN ;DISABLE EMBED ADDRESS MOV A,EMB_ADDR ;ADDRESS OF THE EMBEDDED FUNCTION ORL A,#080H MOV I2C_BUFFER+1,A LCALL WRITE_ONE_BYTE ;---- MOV I2C_BUFFER,#SET_EPOINT_EN ;ENABLE HUB INTERRUPT ENDPOINT MOV I2C_BUFFER+1,#03H ;and EMBEDDED FUNCTION LCALL WRITE_ONE_BYTE ;--- AJMP SET_PORT0_OK ;======================================== ; KEYBOARD'S CODE ;======================================== KEYBOARD_INITIAL: MOV LAST_ZERO_SENT, #00H MOV ROW_NUM, #00H MOV BOOT_PROTOCOL, #01H ; REPORT PROTOCOL ON DEFAULT ; Activate Timer0 MOV TL0, #0E8H ; TL0 AND TH0 MAKES 1 millisec MOV TH0, #03H MOV TMOD, #00000000B ; TIMER0 IS SET AT MODE 0 MOV TCON, #00010000B ; TURNS TIMER0 ON MOV IE,#10000010B ;ALL INTERRUPT DISABLED, EXCEPT TIMER AND GLOBAL CLR NUM CLR SCROLL CLR CAPS MOV KEY1, #00H MOV KEY2, #00H MOV KEY3, #00H MOV KEY4, #00H MOV KEY5, #00H MOV KEY6, #00H MOV KEY_MODIFIER, #00H MOV LED_STATUS, #00H CLEAN_KEY_BUFFER: MOV TOTAL_KEYS, #00H MOV KEY_HIT0, #00; K1 MOV KEY_HIT1, #00; K2 MOV KEY_HIT2, #00; K3 MOV KEY_HIT3, #00; K4 MOV KEY_HIT4, #00; K5 MOV KEY_HIT5, #00; K5 MOV MODIFIER_BYTE, #00; K6 RET KEYBOARD_ROUTINE: ; PURPOSE IS TO PULL EACH BIT OF X0 AND X1 SEQUENTIALLY AND ; SEE IF THE STATE OF Y0 HAS CHANGED, THEN OUTPUT THE READ ; VALUE ACALL SCAN_OUT CHECKKEY: MOV A, Y0 CPL A JZ END_KEYBOARD_ROUTINE START_OF_GHOST_ROUTINE: MOV R3, ROW_NUM ; STORE CURRENT ROW_NUM IN R3 MOV R4, Y0 ; Store this somewhere MOV R1, #10H ; TOTAL OF 16 ROWS TO COMPARE AGAINST (17-1) NEXT_CMP_GHOST: JNB WIN_KEY, GOTO_NEXT ; INCREMENT TO NEXT ROW MOV ROW_NUM, #00 ; ROLL OVER TO #00 AGAIN SJMP GOTO_NEXT1 ; IF MAXIMUM ROW_NUM OF #10H GOTO_NEXT: ; IS REACHED INC ROW_NUM ; GOTO_NEXT1: ; ACALL SCAN_OUT ; PULL THE RESPECTIVE ROLL DOWN MOV A, Y0 ; MOVE THE READ KEYSCAN INTO A MOV R2, A ; Store the new key scan MOV R6, #01H ; START bitwise test bit 0 NEXT_BIT_TEST1: MOV A, R4 ; R4 Is the row to test CPL A ; translating it into 1 means keypressed ANL A, R6 ; masking just one bit for testing JZ NEXT_BIT_TEST2 MOV A, R2 ; CHECK IF THE BIT CORRESPONDS TO ANY CPL A ; KEYPRESS ON THE SAME COLUMN ANL A, R6 JZ NEXT_BIT_TEST2 ; JUMP IF NO KEYS ON SAME COLUMN MOV A, R4 ; R4 Is the row to test CPL A ANL A, R6 ; masking just one bit for testing ORL A, R2 CPL A JNZ GHOST_KEY_FOUND NEXT_BIT_TEST2: MOV A, R6 ; PREPARING BITMASK FOR NEXT BIT CLR C ; CLEAR CARRY FOR SHIFTING ZERO INTO LSB RLC A ; SHIFT LEFT TO NEXT BIT JZ GOTO_NEXT2 ; 8 BITS ARE ALL SCANNED, GOTO NEXT ROW ;JZ END_CMP_GHOST MOV R6, A ; STORE THE BITMASK IN R6 SJMP NEXT_BIT_TEST1 GOTO_NEXT2: DJNZ R1, NEXT_CMP_GHOST SJMP END_CMP_GHOST GHOST_KEY_FOUND: MOV ROW_NUM, R3 ACALL FILL_KEY_BUFFER AJMP END_KEYBOARD_ROUTINE END_CMP_GHOST: MOV ROW_NUM, R3 ; RESTORE TO ORIGINAL ACALL SCAN_OUT END_OF_GHOST_ROUTINE: CHECKKEY1: ACALL KEYPRESSED END_KEYBOARD_ROUTINE: JB WIN_KEY, RESET_ZERO INC ROW_NUM RET RESET_ZERO: MOV ROW_NUM, #00H MOV KEY1, KEY_HIT0 MOV KEY2, KEY_HIT1 MOV KEY3, KEY_HIT2 MOV KEY4, KEY_HIT3 MOV KEY5, KEY_HIT4 MOV KEY6, KEY_HIT5 MOV KEY_MODIFIER, MODIFIER_BYTE ACALL CLEAN_KEY_BUFFER RET ; Uses A as temp register and ROW_NUM to pull down appropriate pin SCAN_OUT: SETB LED_ENABLE SETB NUM SETB SCROLL SETB CAPS MOV A, ROW_NUM JB WIN_KEY, WIN_SCAN ACALL SCAN_ROW SETB WIN_BIT JB X_LO, XLO ; JUMP TO XLO IF BIT IS SET XHI: ; Upper byte MOV X1, A MOV X0, #0FFH RET XLO: ; Lower byte MOV X1, #0FFH MOV X0, A RET WIN_SCAN: MOV X1, #0FFH MOV X0, #0FFH CLR WIN_BIT RET FILL_KEY_BUFFER: MOV KEY_HIT0, #01H MOV KEY_HIT1, #01H MOV KEY_HIT2, #01H MOV KEY_HIT3, #01H MOV KEY_HIT4, #01H MOV KEY_HIT5, #01H MOV TOTAL_KEYS, #06H RET ; SET The bit corresponding to ROW NUMBER of A zero ; ------------------------------------------------- SCAN_ROW: MOV A, ROW_NUM ANL A, #07H MOV DPTR, #SCAN_ROW_MATRIX MOVC A, @A+DPTR RET; SCAN_ROW ; Processing of keypressed ; ------------------------ KEYPRESSED: MOV A, Y0 MOV BIT_NUMBER, #08H CLR C NEXT_KEY1: RLC A JC NEXT_KEY2 ACALL SEND_MAKE_CODE NEXT_KEY2: DJNZ BIT_NUMBER, NEXT_KEY1 RET ; Send make code ; -------------- SEND_MAKE_CODE: DEC BIT_NUMBER ; Because BIT_NUMBER ranges from 1 - 8 PUSH ACC MOV DPTR, #KEYS_LUT MOV A, ROW_NUM RL A RL A RL A ANL A, #0f8H ORL A, BIT_NUMBER MOVC A, @A+DPTR JZ END_SEND_MAKE_CODE MOV R4_DIRECT, A ; STORE IN R4 MOV DPTR, #SPECIAL_KEYS MOV R5, #8 CHECK_SPECIAL: MOV A, R5 MOVC A, @A+DPTR CJNE A, R4_DIRECT, CHECK_SPECIAL_1 MOV A, R5 ADD A, #8 MOVC A, @A+DPTR ORL MODIFIER_BYTE, A MOV LAST_ZERO_SENT, #00H AJMP END_SEND_MAKE_CODE CHECK_SPECIAL_1: DJNZ R5, CHECK_SPECIAL MOV A, #06 ; Check if total keys stored is over 6 CJNE A, TOTAL_KEYS, ADD_KEY MAX_KEY_HIT: ACALL FILL_KEY_BUFFER SJMP END_SEND_MAKE_CODE ADD_KEY: MOV LAST_ZERO_SENT, #00H MOV A, R1 PUSH ACC MOV A, R4 ; Key Code pushed onto stack PUSH ACC MOV A, #KEY_HIT0 ADD A, TOTAL_KEYS MOV R1, A ; Put location of keyhit in R1 POP ACC MOV @R1, A POP ACC MOV R1, A INC TOTAL_KEYS END_SEND_MAKE_CODE: JNB SUSPEND, FINISH_SEND_MAKE_CODE ;JNB EMBED_CONFIG, FINISH_SEND_MAKE_CODE JNB EMBED_REMOTE_WKUP, FINISH_SEND_MAKE_CODE ; ONLY SEND RESUME IF IT IS CONFIGURED AND SUSPENDED MOV A, R0 ; SAFE KEEPING PUSH ACC MOV A, R2 ; SAFE KEEPING PUSH ACC MOV I2C_BUFFER,#RESUME_DEV MOV I2C_BUFFER+1,#00H ;DISENABLE HUB LCALL WRITE_ONE_BYTE POP ACC MOV R2, A POP ACC MOV R0, A FINISH_SEND_MAKE_CODE: POP ACC INC BIT_NUMBER RET WRITE_LED: MOV A, LED_STATUS CPL A RRC A MOV NUM, C RRC A MOV CAPS, C RRC A MOV SCROLL, C CLR LED_ENABLE RET ASCII: DB '0123456789ABCDEF' SPECIAL_KEYS: DB 00H ; DUMMY DB 0E1H ; LEFT SHIFT DB 0E5H ; RIGHT SHIFT DB 0E0H ; LEFT CONTROL DB 0E4H ; RIGHT CONTROL DB 0E2H ; LEFT ALT DB 0E6H ; RIGHT ALT DB 0E3H ; KEYBOARD LEFT GUI DB 0E7H ; KEYBOARD RIGHT GUI MODIFIER_SPECIAL_KEYS: DB 00000010B ; LEFT SHIFT DB 00100000B ; RIGHT SHIFT DB 00000001B ; LEFT CONTROL DB 00010000B ; RIGHT CONTROL DB 00000100B ; LEFT ALT DB 01000000B ; RIGHT ALT DB 00001000B ; KEYBOARD LEFT GUI DB 10000000B ; KEYBOARD RIGHT GUI ;============================================= ; EMBEDDED FUNCTION STANDARD DEVICE DESCRIPTOR ;============================================= FN_STAND_DEV_DESC: DB 12h ;0 bLength DB 01h ;1 bDescriptorType DB 00h ; DB 01h ;2-3 version 1.00 USB spec Word DB 00h ;4 Class DB 00h ;5 bDeviceSubClass DB 00h ;6 bDeviceProtocol DB 08h ;7 bMaxPacketSize0 DW 7104h ;8-9 idVendor For keyboard DW 0204h ;a-b idProduct product 02 version 05 -Fast Stack!!- DW 0001h ;c-d bcdDevice DB 00h ;e iManufacturer DB 00h ;f iProduct DB 00h ;10 iSerialNumber DB 01h ;11 bNumConfigurations FN_CONFIG_DESC: DB 09h ;0 DB 02h ;1 DW 2200h ;2-3 DB 01h ;4 DB 01h ;5 DB 00h ;6 DB 0A0h ;7 Bus powered and remote wakeup DB 05h ;8 FN_INTERFACE_DESC: DB 09h ;0 DB 04h ;1 DB 00h ;2 DB 00h ;3 DB 01h ;4 DB 03h ;5 DB 01h ;6 DB 01h ;7 DB 00h ;8 FN_HID_DESC: DB 09H DB 21H DB 00H DB 01H DB 00H DB 01H DB 22H DB 3FH DB 00H FN_ENDP1_INT_DESC: DB 07h ;0 DB 05h ;1 DB 81h ;2 DB 03h ;3 DW 0800h ;4-5 DB 012h ;6 polling time FN_REPORT_DESC: DB 005H DB 001H DB 009H DB 006H DB 0A1H DB 001H DB 005H DB 007H DB 019H DB 0E0H DB 029H DB 0E7H DB 015H DB 000H DB 025H DB 001H DB 075H DB 001H DB 095H DB 008H DB 081H DB 002H DB 095H DB 001H DB 075H DB 008H DB 081H DB 001H DB 095H DB 005H DB 075H DB 001H DB 005H DB 008H DB 019H DB 001H DB 029H DB 005H DB 091H DB 002H DB 095H DB 001H DB 075H DB 003H DB 091H DB 001H DB 095H DB 006H DB 075H DB 008H DB 015H DB 000H DB 025H DB 065H ; Change to accomodate Usage of Lang key DB 005H DB 007H DB 019H DB 000H DB 029H DB 065H ; Change to accomodate Usage of Lang key DB 081H DB 000H DB 0C0H ;********* END OF EMBEDDED FUNCTION DESCRIPTOR ****** SCAN_ROW_MATRIX: DB 0FEH DB 0FDH DB 0FBH DB 0F7H DB 0EFH DB 0DFH DB 0BFH DB 07FH ;_______________________________________________ ; Keys corresponding to X and Y ;_______________________________________________ KEYS_LUT: $INCLUDE(h11a_MAT.txt) ;**************************** ;* STANDARD DEVICE DESCRIPTOR ;**************************** STAND_DEV_DESC: DB 12h ;0 bLength DB 01h ;1 bDescriptorType DB 00h ; DB 01h ;2-3 version 1.00 USB spec Word DB 09h ;4 Class DB 01h ;5 bDeviceSubClass DB 00h ;6 bDeviceProtocol DB 08h ;7 bMaxPacketSize0 DW 7104h ;8-9 idVendor for Hub DW 0109h ;a-b idProduct product 02 version 05 -Fast Stack!!- DW 4000h ;c-d bcdDevice DB 00h ;e iManufacturer DB 00h ;f iProduct DB 00h ;10 iSerialNumber DB 01h ;11 bNumConfigurations CONFIG_DESC: DB 09h ;0 DB 02h ;1 DW 1900h ;2-3 DB 01h ;4 DB 01h ;5 DB 00h ;6 DB 0A0h ;7 Bus Powered with remote wakeup DB 05h ; DB 00h ;8 INTERFACE_DESC: DB 09h ;0 DB 04h ;1 DB 00h ; DB 01h ;2 DB 00h ;3 DB 01h ;4 DB 09h ;5 DB 01h ;6 DB 00h ;7 DB 00h ;8 ENDP1_INT_DESC: DB 07h ;0 DB 05h ;1 DB 81h ;2 DB 03h ;3 DW 0100h ; DW 0800h ;4-5 DB 0ffh ;6 ;**************** ;* HUB DECRIPTOR ;**************** HUB_DESC1: DB 09h ; 0 DB 00h ; standard HUB descriptortype = 0 DB 05h ; 5 downstreamports DB 04H ; D4D3=00 D2=1 D1D0=0 DB 00h ; D15--D5=0 DB 30h ; 48 msec DB 0Ah ; 10 mA DB 02h ; B7--B4=0 B3-B0=0 DB 02h ; HUB_DESC2: DB 09h ; 0 DB 29h ; standard HUB descriptortype = 0 DB 05h ; 5 downstreamports DB 04H ; D4D3=00 D2=1 D1D0=0 DB 00h ; D15--D5=0 DB 30h ; 48 msec DB 0Ah ; 10 mA DB 02h ; B7--B4=0 B3-B0=0 DB 02h ; END