;**************************************************************************** ; ; file: USBcode.asm ; Description: This file contains all the procedures necessary to interface ; with USB ; External Functions: ; ; Target: Cypress CY7C63723/CY7C63743 Encore Chips ; $Header: ; Version: 1.3.0000 ; ;**************************************************************************** ; Copyright (2003), Cypress Semiconductor Corporation ; This software is owned by Cypress Semiconductor Corporation (Cypress) and is ; protected by United States copyright laws and international treaty provisions. ; Cypress hereby grants to Licensee a personal, non-exclusive, non-transferable ; license to copy, use, modify, create derivative works of, and compile the ; Cypress Source Code and derivative works for the sole purpose of creating ; custom software in support of Licensee product ("Licensee Product") to be used ; only in conjunction with a Cypress integrated circuit. Any reproduction, ; modification, translation, compilation, or representation of this software ; except as specified above is prohibited without the express written permission ; of Cypress. ; Disclaimer: Cypress makes no warranty of any kind, express or implied, with ; regard to this material, including, but not limited to, the implied warranties ; of merchantability and fitness for a particular purpose. Cypress reserves the ; right to make changes without further notice to the materials described herein. ; Cypress does not assume any liability arising out of the application or use of ; any product or circuit described herein. Cypress’ products described herein are ; not authorized for use as components in life-support devices. ; This software is protected by and subject to worldwide patent coverage, ; including U.S. and foreign patents. Use may be limited by and subject to the ; Cypress Software License Agreement. ; ;**************************************************************************** ;******************************************************* ; This file contains all the usb-related code ; For the WirelessUSB-LS bridge running on the ; 637xx, including the descriptor tables. ;******************************************************* ;******************************************************* ; ; Interrupt: endpoint0 ; Purpose: Usb control endpoint handler. This interrupt ; handler formulates responses to SETUP AND ; CONTROL READ, AND NO-DATA CONTROL transactions. ; ; Jump table entry formulation for bmRequestType AND bRequest ; ; 1. Add high AND low nibbles of bmRequestType. ; 2. Put result into high nibble of A. ; 3. Mask off bits [6:4]. ; 4. Add bRequest to A. ; 5. Double value of A (JMP is two bytes). ; ;******************************************************* endpoint0: PUSH X PUSH A IORD ep0_mode AND A, EP0_ACK JZ ep0_done IORD ep0_mode ASL A JC ep0_setup_received ASL A JC ep0_in_received ASL A JC ep0_out_received ep0_done: POP A POP X RET ep0_setup_received: MOV A, NAK_IN_OUT ; clear setup bit to enable IOWR ep0_mode ; writes to EP0 DMA buffer IFDEF DEVICE_RDK_COMBO MOV A, 00h ; set state machine state MOV [ep0_in_machine], A ENDIF MOV A, [bmRequestType] ; compact bmRequestType into 5 bit field AND A, E3h ; clear bits 4-3-2, these unused for our purposes PUSH A ; store value ASR A ; move bits 7-6-5 into 4-3-2's place ASR A ASR A MOV [int_temp], A ; store shifted value POP A ; get original value OR A, [int_temp] ; OR the two to get the 5-bit field AND A, 1Fh ; clear bits 7-6-5 (ASR wraps bit7) ASL A ; shift to INDEX jumptable JACC bmRequestType_jumptable ; jump to handle bmRequestType h2d_std_device: MOV A, [bRequest] ASL A JACC h2d_std_device_jumptable h2d_std_interface: MOV A, [bRequest] ASL A JACC h2d_std_interface_jumptable h2d_std_endpoint: MOV A, [bRequest] ASL A JACC h2d_std_endpoint_jumptable h2d_class_interface: MOV A, [bRequest] ASL A JACC h2d_class_interface_jumptable d2h_std_device: MOV A, [bRequest] ASL A JACC d2h_std_device_jumptable d2h_std_interface: MOV A, [bRequest] ASL A JACC d2h_std_interface_jumptable d2h_std_endpoint: MOV A, [bRequest] ASL A JACC d2h_std_endpoint_jumptable d2h_class_interface: MOV A, [bRequest] ASL A JACC d2h_class_interface_jumptable ;;************ DEVICE REQUESTS ************** clear_device_feature: MOV A, [wValuelo] CMP A, DEVICE_REMOTE_WAKEUP JNZ request_not_supported MOV A, 00h ; disable remote wakeup capability MOV [remote_wakeup], A MOV A, NO_CHANGE_PENDING ; respond with no-data control MOV [ep0_in_flag], A JMP initialize_no_data_control set_device_feature: MOV A, [wValuelo] CMP A, DEVICE_REMOTE_WAKEUP JNZ request_not_supported MOV A, 01h ; enable remote wakeup capability MOV [remote_wakeup], A MOV A, NO_CHANGE_PENDING ; respond with no-data control MOV [ep0_in_flag], A JMP initialize_no_data_control set_device_address: ; SET ADDRESS MOV A, ADDRESS_CHANGE_PENDING ; set flag to indicate we MOV [ep0_in_flag], A ; need to change address on MOV A, [wValuelo] MOV [pending_data], A JMP initialize_no_data_control set_device_configuration: ; SET CONFIGURATION MOV A, [wValuelo] CMP A, 01h JZ configure_device unconfigure_device: ; set device as unconfigured MOV [configuration], A MOV A, DISABLE ; disable endpoint 1 IOWR ep1_mode IOWR ep2_mode MOV A, EP0_INT ; turn off endpoint 1 interrupts IOWR endpoint_int JMP set_device_configuration_done configure_device: ; set device as configured MOV [configuration], A MOV A, NAK_IN_OUT IOWR ep1_mode IOWR ep2_mode MOV A, EP0_INT IOWR endpoint_int MOV A, 00h MOV [ep1_data_toggle], A ; reset the data toggle MOV [ep2_data_toggle], A ; reset the data toggle MOV [ep1_dmabuff0], A ; reset endpoint 1 fifo values MOV [ep1_dmabuff1], A MOV [ep1_dmabuff2], A MOV [ep2_dmabuff0], A ; reset endpoint 2 fifo values MOV [ep2_dmabuff1], A MOV [ep2_dmabuff2], A MOV [ep2_dmabuff3], A MOV [ep2_dmabuff4], A set_device_configuration_done: MOV A, NO_CHANGE_PENDING MOV [ep0_in_flag], A JMP initialize_no_data_control get_device_status: ; GET STATUS MOV A, DEVICE_STATUS_LENGTH MOV [maximum_data_count], A MOV A, [remote_wakeup] ; test remote wakeup status CMP A, 00h JZ remote_wakeup_disabled remote_wakeup_enabled: ; send remote wakeup enabled status MOV A, (device_status_wakeup_enabled - control_read_table) MOV [data_start], A JMP initialize_control_read remote_wakeup_disabled: ; send remote wakeup disabled status MOV A, (device_status_wakeup_disabled - control_read_table) MOV [data_start], A JMP initialize_control_read get_device_descriptor: ; GET DESCRIPTOR MOV A, [wValuehi] ASL A JACC get_device_descriptor_jumptable send_device_descriptor: MOV A, 00h ; get device descriptor length INDEX device_desc_table MOV [maximum_data_count], A MOV A, (device_desc_table - control_read_table) MOV [data_start], A JMP initialize_control_read send_configuration_descriptor: MOV A, 02h INDEX config_desc_table MOV [maximum_data_count], A IFDEF DEVICE_RDK_COMBO MOV A, [wLengthlo] CMP A, 09h ; asking for config_desc_table only JZ set_pc_has_desc CMP A, [maximum_data_count] ; asking for known config_desc JZ set_pc_has_desc MOV A, 00h ; PC doesn't have Desc JMP init_pc_has_desc set_pc_has_desc: MOV A, 01h init_pc_has_desc: MOV [pc_has_desc], A ENDIF MOV A, (config_desc_table - control_read_table) MOV [data_start], A JMP initialize_control_read send_string_descriptor: MOV A, [wValuelo] ASL A JACC string_jumptable language_string: MOV A, 00h INDEX ilanguage_string MOV [maximum_data_count], A MOV A, (ilanguage_string - control_read_table) MOV [data_start], A JMP initialize_control_read manufacturer_string: MOV A, 00h INDEX imanufacturer_string MOV [maximum_data_count], A MOV A, (imanufacturer_string - control_read_table) MOV [data_start], A JMP initialize_control_read product_string: MOV A, 00h INDEX iproduct_string MOV [maximum_data_count], A MOV A, (iproduct_string - control_read_table) MOV [data_start], A JMP initialize_control_read serial_string: MOV A, 00h INDEX iserialnumber_string MOV [maximum_data_count], A MOV A, (iserialnumber_string - control_read_table) MOV [data_start], A JMP initialize_control_read configuration_string: MOV A, 00h INDEX iconfiguration_string MOV [maximum_data_count], A MOV A, (iconfiguration_string - control_read_table) MOV [data_start], A JMP initialize_control_read send_interface_descriptor: IFDEF COMBO_DEVICE MOV A, [wIndexlo] AND A, 01h JNZ send_IF2_desc ENDIF ; COMBO_DEVICE MOV A, 00h ; get interface descriptor length INDEX interface_desc1_table MOV [maximum_data_count], A MOV A, (interface_desc1_table - control_read_table) MOV [data_start], A JMP initialize_control_read IFDEF COMBO_DEVICE send_IF2_desc: MOV A, 00h ; get interface descriptor length INDEX interface_desc2_table MOV [maximum_data_count], A MOV A, (interface_desc2_table - control_read_table) MOV [data_start], A JMP initialize_control_read ENDIF ; COMBO_DEVICE send_endpoint_descriptor: IFDEF COMBO_DEVICE MOV A, [wIndexlo] AND A, 01h JNZ send_EP2_desc ENDIF ; COMBO_DEVICE MOV A, 00h ; get endpoint descriptor length INDEX endpoint_desc1_table MOV [maximum_data_count], A MOV A, (endpoint_desc1_table - control_read_table) MOV [data_start], A JMP initialize_control_read IFDEF COMBO_DEVICE send_EP2_desc: MOV A, 00h ; get endpoint descriptor length INDEX endpoint_desc2_table MOV [maximum_data_count], A MOV A, (endpoint_desc2_table - control_read_table) MOV [data_start], A JMP initialize_control_read ENDIF ; COMBO_DEVICE get_device_configuration: ; GET CONFIGURATION MOV A, DEVICE_CONFIG_LENGTH MOV [maximum_data_count], A MOV A, [configuration] ; test configuration status AND A, FFh JZ device_unconfigured device_configured: ; send configured status MOV A, (device_configured_table - control_read_table) MOV [data_start], A JMP initialize_control_read device_unconfigured: ; send unconfigured status MOV A, (device_unconfigured_table - control_read_table) MOV [data_start], A JMP initialize_control_read ;;************ INTERFACE REQUESTS *********** set_interface_interface: ; SET INTERFACE MOV A, [wValuelo] CMP A, 00h ; there are no alternate interfaces JZ alternate_supported ; for this device alternate_not_supported: ; if the host requests any other JMP request_not_supported ; alternate than 0, stall. alternate_supported: MOV A, NO_CHANGE_PENDING MOV [ep0_in_flag], A JMP initialize_no_data_control get_interface_status: ; GET STATUS MOV A, INTERFACE_STATUS_LENGTH MOV [maximum_data_count], A MOV A, (interface_status_table - control_read_table) MOV [data_start], A JMP initialize_control_read get_interface_interface: ; GET INTERFACE MOV A, INTERFACE_ALTERNATE_LENGTH MOV [maximum_data_count], A MOV A, (interface_alternate_table - control_read_table) MOV [data_start], A JMP initialize_control_read set_interface_report: IFDEF DEVICE_RDK_COMBO ; Decide which battery value (a or b) to request MOV A, [wIndexlo] ; Interface # (0=kbd, 1=mouse) CMP A, 01h JZ req_bat_b ENDIF IFDEF DEVICE_RDK_MOUSE JMP req_bat_b ENDIF MOV A, 01h MOV [batt_report_req_a], A JMP set_interface_report_done req_bat_b: MOV A, 01h MOV [batt_report_req_b], A set_interface_report_done: JMP initialize_control_write set_interface_idle: ; SET IDLE MOV A, [wValuehi] ; test if new idle time CMP A, 00h ; disables idle timer JZ idle_timer_disable MOV A, [idle_timer] ; test if less than 4ms left CMP A, 01h JZ set_idle_last_not_expired MOV A, [wValuehi] ; test if time left less than SUB A, [idle_timer] ; new idle value JNC set_idle_new_timer_less JMP set_idle_normal idle_timer_disable: MOV [idle], A ; disable idle timer JMP set_idle_done set_idle_last_not_expired: MOV A, EVENT_PENDING ; send report immediately MOV [event_machine], A MOV A, 00h ; reset idle prescaler MOV [idle_prescaler], A MOV A, [wValuehi] ; set new idle value MOV [idle_timer], A MOV [idle], A JMP set_idle_done set_idle_new_timer_less: MOV A, 00h MOV [idle_prescaler], A ; reset idle prescaler MOV A, [wValuehi] MOV [idle_timer], A ; update idle time value MOV [idle], A JMP set_idle_done set_idle_normal: MOV A, 00h ; reset idle prescaler MOV [idle_prescaler], A MOV A, [wValuehi] ; update idle time value MOV [idle_timer], A MOV [idle], A set_idle_done: MOV A, NO_CHANGE_PENDING ; respond with no-data control MOV [ep0_in_flag], A ; transaction JMP initialize_no_data_control set_interface_protocol: ; SET PROTOCOL MOV A, [wValuelo] MOV [protocol], A ; set protocol value MOV A, NO_CHANGE_PENDING MOV [ep0_in_flag], A ; respond with no-data control JMP initialize_no_data_control ; transaction get_interface_report: ; GET HID REPORT IFDEF DEVICE_RDK_COMBO ; Decide which values (a or b) to send MOV A, [wIndexlo] ; Interface # (0=kbd, 1=mouse) CMP A, 01h JZ radio_report_b ENDIF IFDEF DEVICE_RDK_MOUSE ; Just send the mouse values (xxx_b) JMP radio_report_b ENDIF radio_report_a: MOV A, [battery_a] ; KBD Battery level MOV [ep0_dmabuff1],A MOV A, [rssi_a] ; KBD Signal strengthbad_packets_a_low] MOV [ep0_dmabuff2dmabuff4],A MOV A, [bad_packets_a_high] MOV [ep0_dmabuff5],A MOV A, [good_packets_a_low] MOV [ep0_dmabuff6],A ; Total Pkts Xferred (Lo byte) MOV A, [good_packets_a_high] MOV [ep0_dmabuff7],A ; Total Pkts Xferred (Hi byte) MOV A, 0 MOV [ep0_dmabuff5],A ; KBD Pkts Xferred (Hi byte) MOV [ep0_dmabuff6],A ; KBD Pkts Xferred (Lo byte) MOV [bad_packets_a_low], A MOV [bad_packets_a_high], A MOV [good_packets_a_low], A MOV [good_packets_a_high], A JMP send_radio_report radio_report_b: MOV A, [battery_b] ; Mouse Battery level MOV [ep0_dmabuff1],A MOV A, [rssi_b] ; Mouse Signal strengthbad_packets_b_low] MOV [ep0_dmabuff2dmabuff4],A MOV A, [bad_packets_b_high] MOV [ep0_dmabuff5],A MOV A, [good_packets_b_low] MOV [ep0_dmabuff6],A ; Total Pkts Xferred (Lo byte) MOV A, [good_packets_b_high] MOV [ep0_dmabuff7],A ; Total Pkts Xferred (Hi byte) MOV A, 0 MOV [ep0_dmabuff5],A ; Mouse Pkts Xferred (Hi byte) MOV [ep0_dmabuff6],A ; Mouse Pkts Xferred (Lo byte) MOV [bad_packets_b_low], A MOV [bad_packets_b_high], A MOV [good_packets_b_low], A MOV [good_packets_b_high], A send_radio_report: ; common data fields - independent of mouse vs kbd MOV A, 04h ; REPORT ID MOV [ep0_dmabuff0], A MOV A, [channel] ; Channel MOV [ep0_dmabuff3dmabuff2], A MOV A, [pn_code] ; PN Code MOV [ep0_dmabuff4dmabuff3], A MOV A, TRANS_CONTROL_READ ; set transaction type to control read MOV [ep0_transtype], A MOV A, DATA_TOGGLE ; set data toggle to DATA ONE MOV [ep0_data_toggle], A MOV A, NAK_IN_OUT ; clear setup bit to write to IOWR ep0_mode ; endpoint fifo MOV X, 07h ; set number of byte to transfer JMP dmabuffer_load_done ; jump to finish transfer get_interface_idle: ; GET IDLE MOV A, DATA_TOGGLE ; set data toggle to DATA ONE MOV [ep0_data_toggle], A MOV A, NAK_IN_OUT ; clear setup bit to write to IOWR ep0_mode ; endpoint fifo MOV A, [idle] ; copy over idle time MOV [ep0_dmabuff0], A MOV A, CONTROL_READ_DATA ; set state machine state MOV [ep0_in_machine], A MOV X, 01h ; set number of byte to transfer to 1 JMP dmabuffer_load_done ; jump to finish transfer get_interface_protocol: ; GET PROTOCOL MOV A, INTERFACE_PROTOCOL_LENGTH MOV [maximum_data_count], A ; get offset of device descriptor table MOV A, [protocol] AND A, 01h JZ boot_protocol report_protocol: MOV A, (interface_report_protocol - control_read_table) MOV [data_start], A JMP initialize_control_read ; get ready to send data boot_protocol: MOV A, (interface_boot_protocol - control_read_table) MOV [data_start], A JMP initialize_control_read ; get ready to send data get_interface_hid: MOV A, [wValuehi] CMP A, 21h JZ get_interface_hid_descriptor CMP A, 22h JZ get_interface_hid_report JMP request_not_supported get_interface_hid_descriptor: ; GET HID CLASS DESCRIPTOR IFDEF COMBO_DEVICE MOV A, [wIndexlo] AND A, 01h JNZ send_HID2_desc ENDIF ; COMBO_DEVICE MOV A, 00h ; get hid decriptor length INDEX hid_desc1_table MOV [maximum_data_count], A ; get offset of device descriptor table MOV A, (hid_desc1_table - control_read_table) MOV [data_start], A JMP initialize_control_read ; get ready to send data IFDEF COMBO_DEVICE send_HID2_desc: MOV A, 00h ; get hid decriptor length INDEX hid_desc1_table MOV [maximum_data_count], A ; get offset of device descriptor table MOV A, (hid_desc2_table - control_read_table) MOV [data_start], A JMP initialize_control_read ; get ready to send data ENDIF ; COMBO_DEVICE IFNDEF DEVICE_RDK_COMBO get_interface_hid_report: ; GET HID REPORT DESCRIPTOR IFDEF COMBO_DEVICE MOV A, [wIndexlo] AND A, 01h JNZ send_report2_desc ENDIF ; COMBO_DEVICE MOV A, 07h ; get hid report descriptor length INDEX hid_desc1_table MOV [maximum_data_count], A ; get offset of device descriptor table MOV A, (hid_report_desc1_table - control_read_table) MOV [data_start], A JMP initialize_control_read ; get ready to send data IFDEF COMBO_DEVICE send_report2_desc: MOV A, 07h ; get hid report descriptor length INDEX hid_desc2_table MOV [maximum_data_count], A ; get offset of device descriptor table MOV A, (hid_report_desc2_table - control_read_table) MOV [data_start], A JMP initialize_control_read ; get ready to send data ENDIF ; COMBO_DEVICE ENDIF ENDIF ; DEVICE_RDK_COMBO IFDEF DEVICE_RDK_COMBO get_interface_hid_report: ; GET HID REPORT DESCRIPTOR MOV A, CTRL_READ_HID_RPT_DESC ; set state machine state MOV [ep0_in_machine], A MOV A, 01h MOV [pc_has_desc], A MOV A, [wIndexlo] AND A, 01h JNZ send_report2_desc MOV A, 07h ; get hid report descriptor length INDEX hid_desc1_table MOV [maximum_data_count], A MOV A, (hid_report_desc1_table - ctrl_read_hid_rpt_desc_table) MOV [data_start], A JMP initialize_control_read ; get ready to send data send_report2_desc: MOV A, 07h ; get hid report descriptor length INDEX hid_desc2_table MOV [maximum_data_count], A MOV A, (hid_report_desc2_table - ctrl_read_hid_rpt_desc_table) MOV [data_start], A JMP initialize_control_read ; get ready to send data ENDIF ;;************ ENDPOINT REQUESTS ************ clear_endpoint_feature: ; CLEAR FEATURE MOV A, [wValuelo] CMP A, ENDPOINT_STALL JNZ request_not_supported MOV A, 00h ; clear endpoint 1 stall MOV [ep1_stall], A MOV A, NO_CHANGE_PENDING ; respond with no-data control MOV [ep0_in_flag], A JMP initialize_no_data_control set_endpoint_feature: ; SET FEATURE MOV A, [wValuelo] CMP A, ENDPOINT_STALL JNZ request_not_supported MOV A, FFh ; stall endpoint 1 MOV [ep1_stall], A MOV A, NO_CHANGE_PENDING ; respond with no-data control MOV [ep0_in_flag], A JMP initialize_no_data_control get_endpoint_status: ; GET STATUS MOV A, ENDPOINT_STALL_LENGTH MOV [maximum_data_count], A MOV A, [ep1_stall] ; test if endpoint 1 stalled AND A, FFh JNZ endpoint_stalled endpoint_not_stalled: ; send no-stall status MOV A, (endpoint_nostall_table - control_read_table) MOV [data_start], A JMP initialize_control_read endpoint_stalled: ; send stall status MOV A, (endpoint_stall_table - control_read_table) MOV [data_start], A JMP initialize_control_read ;;***************** CONTROL READ TRANSACTION ************** initialize_control_read: MOV A, TRANS_CONTROL_READ ; set transaction type to control read MOV [ep0_transtype], A MOV A, DATA_TOGGLE ; set data toggle to DATA ONE MOV [ep0_data_toggle], A ; if wLengthhi == 0 MOV A, [wLengthhi] ; find lesser of requested AND maximum CMP A, 00h JNZ initialize_control_read_done ; AND wLengthlo < maximum_data_count MOV A, [wLengthlo] ; find lesser of requested AND maximum CMP A, [maximum_data_count] ; response lengths JNC initialize_control_read_done ; then maximum_data_count >= wLengthlo MOV A, [wLengthlo] MOV [maximum_data_count], A initialize_control_read_done: JMP control_read_data_stage ; send first packet ;;***************** CONTROL WRITE TRANSACTION ************* initialize_control_write: MOV A, TRANS_CONTROL_WRITE ; set transaction type to control write MOV [ep0_transtype], A MOV A, DATA_TOGGLE ; set accepted data toggle MOV [ep0_data_toggle], A MOV A, ACK_OUT_NAK_IN IOWR ep0_mode POP A POP X RET ;;***************** NO DATA CONTROL TRANSACTION *********** initialize_no_data_control: MOV A, TRANS_NO_DATA_CONTROL ; set transaction type to no data control MOV [ep0_transtype], A MOV A, STATUS_IN_ONLY ; set SIE for STATUS IN mode IOWR ep0_mode POP A POP X RET ;;***************** UNSUPPORTED TRANSACTION *************** request_not_supported: IORD ep0_mode MOV A, STALL_IN_OUT ; send A stall to indicate that the request IOWR ep0_mode ; is not supported POP A POP X RET ;********************************************************** ;********************************** ; IN - CONTROL READ DATA STAGE ; - CONTROL WRITE STATUS STAGE ; - NO DATA CONTROL STATUS STAGE ep0_in_received: MOV A, [ep0_transtype] JACC ep0_in_jumptable ;********************************** control_read_data_stage: MOV X, 00h MOV A, [maximum_data_count] CMP A, 00h ; has all been sent JZ dmabuffer_load_done dmabuffer_load: MOV A, X ; check if 8 byte ep0 dma CMP A, 08h ; buffer is full JZ dmabuffer_load_done MOV A, [data_start] ; read data from desc. table IFDEF DEVICE_RDK_COMBO MOV A, [ep0_in_machine] CMP A, CTRL_READ_HID_RPT_DESC ; if get_interface_hid_report JNZ non_hid_read ; other read types hid_read: MOV A, [data_start] INDEX ctrl_read_hid_rpt_desc_table JMP non_hid_read_end non_hid_read: MOV A, [data_start] INDEX control_read_table non_hid_read_end: ELSE INDEX control_read_table ENDIF MOV [X + ep0_dmabuff0], A INC X ; increment buffer offset INC [data_start] ; increment descriptor table pointer DEC [maximum_data_count] ; decrement number of bytes requested JZ dmabuffer_load_done JMP dmabuffer_load ; loop to load more data dmabuffer_load_done: .ep0_count: IORD ep0_count ; unlock counter register MOV A, X ; find number of bytes loaded OR A, [ep0_data_toggle] ; OR data toggle MOV [temp], A IOWR ep0_count ; write ep0 count register IORD ep0_count CMP A, [temp] JNZ .ep0_count IORD ep0_mode AND A, (EP0_SETUP | EP0_OUT) JNZ .return IORD ep0_mode MOV A, ACK_IN_STATUS_OUT ; set endpoint mode to ack next IN IOWR ep0_mode ; OR STATUS OUT MOV A, DATA_TOGGLE ; toggle data toggle XOR [ep0_data_toggle], A .return: POP A POP X RET ;********************************** control_write_status_stage: MOV A, STATUS_IN_ONLY IOWR ep0_mode MOV A, TRANS_NONE MOV [ep0_transtype], A POP A POP X RET ;********************************** no_data_control_status_stage: MOV A, [ep0_in_flag] ; end of no-data control transaction CMP A, ADDRESS_CHANGE_PENDING JNZ no_data_status_done change_address: MOV A, [pending_data] ; change the device address if this OR A, ADDRESS_ENABLE ; data is pending IOWR usb_address no_data_status_done: ; otherwise set to stall in/out until MOV A, STALL_IN_OUT ; A new setup IOWR ep0_mode MOV A, TRANS_NONE MOV [ep0_transtype], A POP A POP X RET ;********************************************************** ;********************************** ; OUT - CONTROL READ STATUS STAGE ; - CONTROL WRITE DATA STAGE ; - ERROR DURING NO DATA CONTROL TRANSACTION ep0_out_received: MOV A, [ep0_transtype] JACC ep0_out_jumptable ;********************************** control_read_status_stage: MOV A, STATUS_OUT_ONLY IOWR ep0_mode MOV A, TRANS_NONE MOV [ep0_transtype], A POP A POP X RET ;********************************** control_write_data_stage: IORD ep0_count ; check that data is valid AND A, DATA_VALID JZ control_write_data_stage_done IORD ep0_count ; check data toggle is 1. If not, AND A, DATA_TOGGLE ; ignore the transaction. Exit. XOR A, [ep0_data_toggle] JNZ control_write_data_stage_done MOV A, DATA_TOGGLE XOR [ep0_data_toggle], A control_write_data_stage_done: POP A POP X RET ;********************************** no_data_control_error: MOV A, STALL_IN_OUT IOWR ep0_mode MOV A, TRANS_NONE MOV [ep0_transtype], A POP A POP X RET ;********************************************************** ; JUMP TABLES ;********************************************************** XPAGEOFF ORG 1500h ; bmRequestTypes commented out are not used for this device, ; but may be used for your device. They are kept here as ; an example of how to use this jumptable. bmRequestType_jumptable: JMP h2d_std_device ; 00 JMP h2d_std_interface ; 01 JMP h2d_std_endpoint ; 02 JMP request_not_supported ; h2d_std_other 03 JMP request_not_supported ; h2d_class_device 04 JMP h2d_class_interface ; h2d_class_interface 05 JMP request_not_supported ; h2d_class_endpoint 06 JMP request_not_supported ; h2d_class_other 07 JMP request_not_supported ; h2d_vendor_device 08 JMP request_not_supported ; h2d_vendor_interface 09 JMP request_not_supported ; h2d_vendor_endpoint 0A JMP request_not_supported ; h2d_vendor_other 0B JMP request_not_supported ; 0C JMP request_not_supported ; 0D JMP request_not_supported ; 0E JMP request_not_supported ; 0F JMP d2h_std_device ; 10 JMP d2h_std_interface ; 11 JMP d2h_std_endpoint ; 12 JMP request_not_supported ; d2h_std_other 13 JMP request_not_supported ; d2h_class_device 14 JMP d2h_class_interface ; d2h_class_interface 15 JMP request_not_supported ; d2h_class_endpoint 16 JMP request_not_supported ; d2h_class_other 17 JMP request_not_supported ; d2h_vendor_device 18 JMP request_not_supported ; d2h_vendor_interface 19 JMP request_not_supported ; d2h_vendor_endpoint 1A JMP request_not_supported ; d2h_vendor_other 1B JMP request_not_supported ; 1C JMP request_not_supported ; 1D JMP request_not_supported ; 1E JMP request_not_supported ; 1F h2d_std_device_jumptable: JMP request_not_supported ; 00 JMP clear_device_feature ; 01 Clear Feature (Clear Remote Wakeup) JMP request_not_supported ; 02 Reserved JMP set_device_feature ; 03 Set Feature (Set Remote Wakeup) JMP request_not_supported ; 04 JMP set_device_address ; 05 JMP request_not_supported ; 06 JMP request_not_supported ; set_device_descriptor 07 JMP request_not_supported ; 08 JMP set_device_configuration; 09 h2d_std_interface_jumptable: JMP request_not_supported ; 00 JMP request_not_supported ; clear_interface_feature 01 JMP request_not_supported ; 02 JMP request_not_supported ; set_interface_feature 03 JMP request_not_supported ; 04 JMP request_not_supported ; 05 JMP request_not_supported ; 06 JMP request_not_supported ; 07 JMP request_not_supported ; 08 JMP request_not_supported ; 09 JMP request_not_supported ; 0A JMP set_interface_interface ; 0B h2d_std_endpoint_jumptable: JMP request_not_supported ; 00 JMP clear_endpoint_feature ; 01 JMP request_not_supported ; 02 JMP set_endpoint_feature ; 03 ;Host-to-device HID-specific requests h2d_class_interface_jumptable: JMP request_not_supported ; 00 JMP request_not_supported ; 01 JMP request_not_supported ; 02 JMP request_not_supported ; 03 JMP request_not_supported ; 04 JMP request_not_supported ; 05 JMP request_not_supported ; 06 JMP request_not_supported ; 07 JMP request_not_supported ; 08 JMP set_interface_report ; 09 set_report - (Output or Feature) JMP set_interface_idle ; 0A set_idle JMP set_interface_protocol ; 0B set_protocol d2h_std_device_jumptable: JMP get_device_status ; 00 JMP request_not_supported ; 01 JMP request_not_supported ; 02 JMP request_not_supported ; 03 JMP request_not_supported ; 04 JMP request_not_supported ; 05 JMP get_device_descriptor ; 06 JMP request_not_supported ; 07 JMP get_device_configuration; 08 d2h_std_interface_jumptable: JMP get_interface_status ; 00 JMP request_not_supported ; 01 JMP request_not_supported ; 02 JMP request_not_supported ; 03 JMP request_not_supported ; 04 JMP request_not_supported ; 05 JMP get_interface_hid ; 06 JMP request_not_supported ; 07 JMP request_not_supported ; 08 JMP request_not_supported ; 09 JMP get_interface_interface ; 0A d2h_std_endpoint_jumptable: JMP get_endpoint_status ; 00 JMP request_not_supported ; 01 JMP request_not_supported ; 02 JMP request_not_supported ; 03 JMP request_not_supported ; 04 JMP request_not_supported ; 05 JMP request_not_supported ; 06 JMP request_not_supported ; 07 JMP request_not_supported ; 08 JMP request_not_supported ; 09 JMP request_not_supported ; 0A JMP request_not_supported ; 0B JMP request_not_supported ; synch frame 0C ;Device-to-host HID-specific requests d2h_class_interface_jumptable: JMP request_not_supported ; 00 JMP get_interface_report ; 01 get_report JMP get_interface_idle ; 02 get_idle JMP get_interface_protocol ; 03 get_protocol ep0_in_jumptable: JMP request_not_supported JMP control_read_data_stage JMP control_write_status_stage JMP no_data_control_status_stage ep0_out_jumptable: JMP request_not_supported JMP control_read_status_stage JMP control_write_data_stage JMP no_data_control_error get_device_descriptor_jumptable: JMP request_not_supported JMP send_device_descriptor JMP send_configuration_descriptor JMP send_string_descriptor JMP send_interface_descriptor JMP send_endpoint_descriptor string_jumptable: JMP language_string JMP manufacturer_string JMP product_string JMP serial_string JMP configuration_string ;********************************************************* ; rom lookup tables ;********************************************************* XPAGEOFF ORG 1600h IFDEF DEVICE_MOUSE INCLUDE "mouse desc.inc" ENDIF IFDEF DEVICE_GAMEPAD INCLUDE "gamepad desc.inc" ENDIF IFDEF DEVICE_KEYBOARD INCLUDE "kb desc.inc" ENDIF IFDEF DEVICE_KB_MOUSE_COMBO INCLUDE "kbm desc.inc" ENDIF IFDEF DEVICE_PERT INCLUDE "kb desc.inc" ENDIF IFDEF DEVICE_RDK_MOUSE INCLUDE "mouse desc.inc" ENDIF IFDEF DEVICE_RDK_KEYBOARD INCLUDE "rdk kb desc.inc" ENDIF IFDEF DEVICE_RDK_COMBO INCLUDE "rdk kbm desc.inc" ENDIF XPAGEON