/** Enumerate and configure the new device on the port of this HUB interface. @param HubIf The HUB that has the device connected. @param Port The port index of the hub (started with zero). @retval EFI_SUCCESS The device is enumerated (added or removed). @retval EFI_OUT_OF_RESOURCES Failed to allocate resource for the device. @retval Others Failed to enumerate the device. **/ EFI_STATUS UsbEnumerateNewDev ( IN USB_INTERFACE *HubIf, IN UINT8 Port ) { USB_BUS *Bus; USB_HUB_API *HubApi; USB_DEVICE *Child; USB_DEVICE *Parent; EFI_USB_PORT_STATUS PortState; UINTN Address; UINT8 Config; EFI_STATUS Status; Parent = HubIf->Device; Bus = Parent->Bus; HubApi = HubIf->HubApi; Address = Bus->MaxDevices; DBG("USB_WAIT_PORT_STABLE_STALL\n"); gBS->Stall (USB_WAIT_PORT_STABLE_STALL); //100ms // // Hub resets the device for at least 10 milliseconds. // Host learns device speed. If device is of low/full speed // and the hub is a EHCI root hub, ResetPort will release // the device to its companion UHCI and return an error. // Status = HubApi->ResetPort (HubIf, Port); if (EFI_ERROR (Status)) { // DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to reset port %d - %r\n", Port, Status)); return Status; } // DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: hub port %d is reset\n", Port)); Child = UsbCreateDevice (HubIf, Port); if (Child == NULL) { return EFI_OUT_OF_RESOURCES; } // // OK, now identify the device speed. After reset, hub // fully knows the actual device speed. // DBG("GetPortStatus\n"); Status = HubApi->GetPortStatus (HubIf, Port, &PortState); if (EFI_ERROR (Status)) { // DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to get speed of port %d\n", Port)); goto ON_ERROR; } if (!USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_CONNECTION)) { // DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: No device presented at port %d\n", Port)); goto ON_ERROR; } else if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_SUPER_SPEED)){ Child->Speed = EFI_USB_SPEED_SUPER; Child->MaxPacket0 = 512; } else if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_HIGH_SPEED)) { Child->Speed = EFI_USB_SPEED_HIGH; Child->MaxPacket0 = 64; } else if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_LOW_SPEED)) { Child->Speed = EFI_USB_SPEED_LOW; Child->MaxPacket0 = 8; } else { Child->Speed = EFI_USB_SPEED_FULL; Child->MaxPacket0 = 8; } // DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: device is of %d speed\n", Child->Speed)); DBG("UsbEnumerateNewDev: device is of %d speed\n", Child->Speed); if (((Child->Speed == EFI_USB_SPEED_LOW) || (Child->Speed == EFI_USB_SPEED_FULL)) && (Parent->Speed == EFI_USB_SPEED_HIGH)) { // // If the child is a low or full speed device, it is necessary to // set the transaction translator. Port TT is 1-based. // This is quite simple: // 1. if parent is of high speed, then parent is our translator // 2. otherwise use parent's translator. // Child->Translator.TranslatorHubAddress = Parent->Address; Child->Translator.TranslatorPortNumber = (UINT8) (Port + 1); } else { Child->Translator = Parent->Translator; } // DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: device uses translator (%d, %d)\n", // Child->Translator.TranslatorHubAddress, // Child->Translator.TranslatorPortNumber)); DBG("UsbEnumerateNewDev: device uses translator (%d, %d)\n", Child->Translator.TranslatorHubAddress, Child->Translator.TranslatorPortNumber); // // After port is reset, hub establishes a signal path between // the device and host (DEFALUT state). Device's registers are // reset, use default address 0 (host enumerates one device at // a time) , and ready to respond to control transfer at EP 0. // // // Host assigns an address to the device. Device completes the // status stage with default address, then switches to new address. // ADDRESS state. Address zero is reserved for root hub. // // ASSERT (Bus->MaxDevices <= 256); for (Address = 1; Address < Bus->MaxDevices; Address++) { if (Bus->Devices[Address] == NULL) { break; } } if (Address >= Bus->MaxDevices) { // DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: address pool is full for port %d\n", Port)); DBG("UsbEnumerateNewDev: address pool is full for port %d\n", Port); Status = EFI_ACCESS_DENIED; goto ON_ERROR; } Status = UsbSetAddress (Child, (UINT8)Address); Child->Address = (UINT8)Address; Bus->Devices[Address] = Child; if (EFI_ERROR (Status)) { // DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to set device address - %r\n", Status)); goto ON_ERROR; } gBS->Stall (USB_SET_DEVICE_ADDRESS_STALL); // DEBUG ((EFI_D_INFO, "UsbEnumerateNewDev: device is now ADDRESSED at %d\n", Address)); DBG("UsbEnumerateNewDev: device is now ADDRESSED at %d\n", Address); // // Host sends a Get_Descriptor request to learn the max packet // size of default pipe (only part of the device's descriptor). // Status = UsbGetMaxPacketSize0 (Child); if (EFI_ERROR (Status)) { // DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to get max packet for EP 0 - %r\n", Status)); DBG("UsbEnumerateNewDev: failed to get max packet for EP 0 - %r\n", Status); goto ON_ERROR; } // DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: max packet size for EP 0 is %d\n", Child->MaxPacket0)); // // Host learns about the device's abilities by requesting device's // entire descriptions. // Status = UsbBuildDescTable (Child); if (EFI_ERROR (Status)) { // DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to build descriptor table - %r\n", Status)); DBG("UsbEnumerateNewDev: failed to build descriptor table - %r\n", Status); goto ON_ERROR; } // // Select a default configuration: UEFI must set the configuration // before the driver can connect to the device. // Config = Child->DevDesc->Configs[0]->Desc.ConfigurationValue; Status = UsbSetConfig (Child, Config); if (EFI_ERROR (Status)) { // DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to set configure %d - %r\n", Config, Status)); DBG("UsbEnumerateNewDev: failed to set configure %d - %r\n", Config, Status); goto ON_ERROR; } // DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: device %d is now in CONFIGED state\n", Address)); DBG("UsbEnumerateNewDev: device %d is now in CONFIGED state\n", Address); // // Host assigns and loads a device driver. // Status = UsbSelectConfig (Child, Config); if (EFI_ERROR (Status)) { // DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to create interfaces - %r\n", Status)); DBG("UsbEnumerateNewDev: failed to create interfaces - %r\n", Status); goto ON_ERROR; } // // Report Status Code to indicate USB device has been detected by hotplug // REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, (EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG), Bus->DevicePath ); return EFI_SUCCESS; ON_ERROR: // // If reach here, it means the enumeration process on a given port is interrupted due to error. // The s/w resources, including the assigned address(Address) and the allocated usb device data // structure(Bus->Devices[Address]), will NOT be freed here. These resources will be freed when // the device is unplugged from the port or DriverBindingStop() is invoked. // // This way is used to co-work with the lower layer EDKII UHCI/EHCI/XHCI host controller driver. // It's mainly because to keep UEFI spec unchanged EDKII XHCI driver have to maintain a state machine // to keep track of the mapping between actual address and request address. If the request address // (Address) is freed here, the Address value will be used by next enumerated device. Then EDKII XHCI // host controller driver will have wrong information, which will cause further transaction error. // // EDKII UHCI/EHCI doesn't get impacted as it's make sense to reserve s/w resource till it gets unplugged. // /* if (Address != Bus->MaxDevices) { Bus->Devices[Address] = NULL; } if (Child != NULL) { UsbFreeDevice (Child); } */ return Status; }
STATIC EFI_STATUS UsbEnumerateNewDev ( IN USB_INTERFACE *HubIf, IN UINT8 Port ) /*++ Routine Description: Enumerate and configure the new device on the port of this HUB interface. Arguments: HubIf - The HUB that has the device connected Port - The port index of the hub (started with zero) Returns: EFI_SUCCESS - The device is enumerated (added or removed) EFI_OUT_OF_RESOURCES - Failed to allocate resource for the device Others - Failed to enumerate the device --*/ { USB_BUS *Bus; USB_HUB_API *HubApi; USB_DEVICE *Child; USB_DEVICE *Parent; EFI_USB_PORT_STATUS PortState; UINT8 Address; UINT8 Config; EFI_STATUS Status; Address = USB_MAX_DEVICES; Parent = HubIf->Device; Bus = Parent->Bus; HubApi = HubIf->HubApi; gBS->Stall (USB_WAIT_PORT_STABLE_STALL); // // Hub resets the device for at least 10 milliseconds. // Host learns device speed. If device is of low/full speed // and the hub is a EHCI root hub, ResetPort will release // the device to its companion UHCI and return an error. // Status = HubApi->ResetPort (HubIf, Port); if (EFI_ERROR (Status)) { USB_ERROR (("UsbEnumerateNewDev: failed to reset port %d - %r\n", Port, Status)); return Status; } USB_DEBUG (("UsbEnumerateNewDev: hub port %d is reset\n", Port)); Child = UsbCreateDevice (HubIf, Port); if (Child == NULL) { return EFI_OUT_OF_RESOURCES; } // // OK, now identify the device speed. After reset, hub // fully knows the actual device speed. // Status = HubApi->GetPortStatus (HubIf, Port, &PortState); if (EFI_ERROR (Status)) { USB_ERROR (("UsbEnumerateNewDev: failed to get speed of port %d\n", Port)); goto ON_ERROR; } if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_LOW_SPEED)) { Child->Speed = EFI_USB_SPEED_LOW; } else if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_HIGH_SPEED)) { Child->Speed = EFI_USB_SPEED_HIGH; } else { Child->Speed = EFI_USB_SPEED_FULL; } USB_DEBUG (("UsbEnumerateNewDev: device is of %d speed\n", Child->Speed)); if (Child->Speed != EFI_USB_SPEED_HIGH) { // // If the child isn't a high speed device, it is necessary to // set the transaction translator. Port TT is 1-based. // This is quite simple: // 1. if parent is of high speed, then parent is our translator // 2. otherwise use parent's translator. // if (Parent->Speed == EFI_USB_SPEED_HIGH) { Child->Translator.TranslatorHubAddress = Parent->Address; Child->Translator.TranslatorPortNumber = Port + 1; } else { Child->Translator = Parent->Translator; } USB_DEBUG (("UsbEnumerateNewDev: device uses translator (%d, %d)\n", Child->Translator.TranslatorHubAddress, Child->Translator.TranslatorPortNumber)); } // // After port is reset, hub establishes a signal path between // the device and host (DEFALUT state). Device¡¯s registers are // reset, use default address 0 (host enumerates one device at // a time) , and ready to respond to control transfer at EP 0. // // // Host sends a Get_Descriptor request to learn the max packet // size of default pipe (only part of the device¡¯s descriptor). // Status = UsbGetMaxPacketSize0 (Child); if (EFI_ERROR (Status)) { USB_ERROR (("UsbEnumerateNewDev: failed to get max packet for EP 0 - %r\n", Status)); goto ON_ERROR; } USB_DEBUG (("UsbEnumerateNewDev: max packet size for EP 0 is %d\n", Child->MaxPacket0)); // // Host assigns an address to the device. Device completes the // status stage with default address, then switches to new address. // ADDRESS state. Address zero is reserved for root hub. // for (Address = 1; Address < USB_MAX_DEVICES; Address++) { if (Bus->Devices[Address] == NULL) { break; } } if (Address == USB_MAX_DEVICES) { USB_ERROR (("UsbEnumerateNewDev: address pool is full for port %d\n", Port)); Status = EFI_ACCESS_DENIED; goto ON_ERROR; } Bus->Devices[Address] = Child; Status = UsbSetAddress (Child, Address); Child->Address = Address; if (EFI_ERROR (Status)) { USB_ERROR (("UsbEnumerateNewDev: failed to set device address - %r\n", Status)); goto ON_ERROR; } gBS->Stall (USB_SET_DEVICE_ADDRESS_STALL); USB_DEBUG (("UsbEnumerateNewDev: device is now ADDRESSED at %d\n", Address)); // // Host learns about the device¡¯s abilities by requesting device's // entire descriptions. // Status = UsbBuildDescTable (Child); if (EFI_ERROR (Status)) { USB_ERROR (("UsbEnumerateNewDev: failed to build descriptor table - %r\n", Status)); goto ON_ERROR; } // // Select a default configuration: UEFI must set the configuration // before the driver can connect to the device. // Config = Child->DevDesc->Configs[0]->Desc.ConfigurationValue; Status = UsbSetConfig (Child, Config); if (EFI_ERROR (Status)) { USB_ERROR (("UsbEnumerateNewDev: failed to set configure %d - %r\n", Config, Status)); goto ON_ERROR; } USB_DEBUG (("UsbEnumerateNewDev: device %d is now in CONFIGED state\n", Address)); // // Host assigns and loads a device driver. // Status = UsbSelectConfig (Child, Config); if (EFI_ERROR (Status)) { USB_ERROR (("UsbEnumerateNewDev: failed to create interfaces - %r\n", Status)); goto ON_ERROR; } return EFI_SUCCESS; ON_ERROR: if (Address != USB_MAX_DEVICES) { Bus->Devices[Address] = NULL; } if (Child != NULL) { UsbFreeDevice (Child); } return Status; }
/************************************************************************* * Function Name: USB_SetupHandler * Parameters: void * * Return: none * * Description: Setup packet handler * *************************************************************************/ void USB_SetupHandler (void) { switch(UsbEp0SetupPacket.mRequestType.Type) { // Standard case UsbTypeStandart: // Decoding standard request switch (UsbEp0SetupPacket.bRequest) { case GET_STATUS: UsbGetStatus(); break; case CLEAR_FEATURE: UsbClearFeature(); break; case SET_FEATURE: UsbSetFeature(); break; case SET_ADDRESS: UsbSetAddress(); break; case GET_DESCRIPTOR: if(UsbEp0SetupPacket.mRequestType.Recipient == UsbRecipientDevice) { UsbGetDescriptor(); } // Only get descriptor for device is standard request else if ((UsbEp0SetupPacket.mRequestType.Dir == UsbDevice2Host) && (USB_GET_DESCRIPTOR_HOOK(&UsbEp0SetupPacket) == UsbPass)) { } else { USB_T9_ERROR_REQUEST(); } break; case SET_DESCRIPTOR: // Optional (only for configuration and string descriptors) UsbSetDescriptor(); break; case GET_CONFIGURATION: UsbGetConfiguration(); break; case SET_CONFIGURATION: UsbSetConfiguration(); break; case GET_INTERFACE: UsbGetInterface(); break; case SET_INTERFACE: UsbSetInterface(); break; case SYNCH_FRAME: UsbSynchFrame(); break; default: USB_T9_ERROR_REQUEST(); } break; // Class case UsbTypeClass: if(USB_CLASS_REQUEST_HOOK(&UsbEp0SetupPacket) != UsbPass) { USB_T9_ERROR_REQUEST(); } else { } break; // Vendor case UsbTypeVendor: if( USB_VENDOR_REQUEST_HOOK(&UsbEp0SetupPacket) != UsbPass) { USB_T9_ERROR_REQUEST(); } else { } break; // Other default: USB_T9_ERROR_REQUEST(); } }
//----------------------------------------------------------------------------------------// // // Main function // //----------------------------------------------------------------------------------------// int main(void) { alt_u16 intStat; alt_u16 usb_ctl_val; static alt_u16 ctl_reg = 0; static alt_u16 no_device = 0; alt_u16 fs_device = 0; int keycode = 0; alt_u8 toggle = 0; alt_u8 data_size; alt_u16 code; int i; printf("USB keyboard setup...\n\n"); //----------------------------------------SIE1 initial---------------------------------------------------// USB_HOT_PLUG: UsbSoftReset(); // STEP 1a: UsbWrite (HPI_SIE1_MSG_ADR, 0); UsbWrite (HOST1_STAT_REG, 0xFFFF); /* Set HUSB_pEOT time */ UsbWrite(HUSB_pEOT, 600); // adjust the according to your USB device speed usb_ctl_val = SOFEOP1_TO_CPU_EN | RESUME1_TO_HPI_EN;// | SOFEOP1_TO_HPI_EN; UsbWrite(HPI_IRQ_ROUTING_REG, usb_ctl_val); intStat = A_CHG_IRQ_EN | SOF_EOP_IRQ_EN ; UsbWrite(HOST1_IRQ_EN_REG, intStat); // STEP 1a end // STEP 1b begin UsbWrite(COMM_R0,0x0000);//reset time UsbWrite(COMM_R1,0x0000); //port number UsbWrite(COMM_R2,0x0000); //r1 UsbWrite(COMM_R3,0x0000); //r1 UsbWrite(COMM_R4,0x0000); //r1 UsbWrite(COMM_R5,0x0000); //r1 UsbWrite(COMM_R6,0x0000); //r1 UsbWrite(COMM_R7,0x0000); //r1 UsbWrite(COMM_R8,0x0000); //r1 UsbWrite(COMM_R9,0x0000); //r1 UsbWrite(COMM_R10,0x0000); //r1 UsbWrite(COMM_R11,0x0000); //r1 UsbWrite(COMM_R12,0x0000); //r1 UsbWrite(COMM_R13,0x0000); //r1 UsbWrite(COMM_INT_NUM,HUSB_SIE1_INIT_INT); //HUSB_SIE1_INIT_INT IOWR(CY7C67200_BASE,HPI_MAILBOX,COMM_EXEC_INT); while (!(IORD(CY7C67200_BASE,HPI_STATUS) & 0xFFFF) ) //read sie1 msg register { } while (IORD(CY7C67200_BASE,HPI_MAILBOX) != COMM_ACK) { printf("[ERROR]:routine mailbox data is %x\n",IORD(CY7C67200_BASE,HPI_MAILBOX)); goto USB_HOT_PLUG; } // STEP 1b end // STEP 2 begin //usleep(30*1000); UsbWrite(COMM_INT_NUM,HUSB_RESET_INT); //husb reset UsbWrite(COMM_R0,0x003c);//reset time UsbWrite(COMM_R1,0x0000); //port number UsbWrite(COMM_R2,0x0000); //r1 UsbWrite(COMM_R3,0x0000); //r1 UsbWrite(COMM_R4,0x0000); //r1 UsbWrite(COMM_R5,0x0000); //r1 UsbWrite(COMM_R6,0x0000); //r1 UsbWrite(COMM_R7,0x0000); //r1 UsbWrite(COMM_R8,0x0000); //r1 UsbWrite(COMM_R9,0x0000); //r1 UsbWrite(COMM_R10,0x0000); //r1 UsbWrite(COMM_R11,0x0000); //r1 UsbWrite(COMM_R12,0x0000); //r1 UsbWrite(COMM_R13,0x0000); //r1 IOWR(CY7C67200_BASE,HPI_MAILBOX,COMM_EXEC_INT); while (IORD(CY7C67200_BASE,HPI_MAILBOX) != COMM_ACK) { printf("[ERROR]:routine mailbox data is %x\n",IORD(CY7C67200_BASE,HPI_MAILBOX)); goto USB_HOT_PLUG; } // STEP 2 end //usleep(30*1000); ctl_reg = USB1_CTL_REG; no_device = (A_DP_STAT | A_DM_STAT); fs_device = A_DP_STAT; usb_ctl_val = UsbRead(ctl_reg); if (!(usb_ctl_val & no_device)) { printf("\n[INFO]: no device is present in SIE1!\n"); printf("[INFO]: please insert a USB keyboard in SIE1!\n"); while (!(usb_ctl_val & no_device)) { usb_ctl_val = UsbRead(ctl_reg); if(usb_ctl_val & no_device) goto USB_HOT_PLUG; usleep(2000); } } else { /* check for low speed or full speed by reading D+ and D- lines */ if (usb_ctl_val & fs_device) { printf("[INFO]: full speed device\n"); } else { printf("[INFO]: low speed device\n"); } } //printf("[SIE1 INIT]:USB 1 Control Register reg is %x\n",UsbRead(0xC08A)); // STEP 3 begin //------------------------------------------------------set address ----------------------------------------------------------------- UsbSetAddress(); while (!(IORD(CY7C67200_BASE,HPI_STATUS) & HPI_STATUS_SIE1msg_FLAG) ) //read sie1 msg register { UsbSetAddress(); usleep(10*1000); } UsbWaitTDListDone(); IOWR(CY7C67200_BASE,HPI_ADDR,0x0506); // i printf("[ENUM PROCESS]:step 3 TD Status Byte is %x\n",IORD(CY7C67200_BASE,HPI_DATA)); IOWR(CY7C67200_BASE,HPI_ADDR,0x0508); // n usb_ctl_val = IORD(CY7C67200_BASE,HPI_DATA); printf("[ENUM PROCESS]:step 3 TD Control Byte is %x\n",usb_ctl_val); while (usb_ctl_val != 0x03) // retries occurred { usb_ctl_val = UsbGetRetryCnt(); goto USB_HOT_PLUG; } printf("------------[ENUM PROCESS]:set address done!---------------\n"); // STEP 4 begin //-------------------------------get device descriptor-1 -----------------------------------// // TASK: Call the appropriate function for this step. UsbGetDeviceDesc1(); usleep(10*1000); while (!(IORD(CY7C67200_BASE,HPI_STATUS) & HPI_STATUS_SIE1msg_FLAG) ) //read sie1 msg register { // TASK: Call the appropriate function again if it wasn't processed successfully. UsbGetDeviceDesc1(); usleep(10*1000); } UsbWaitTDListDone(); IOWR(CY7C67200_BASE,HPI_ADDR,0x0506); printf("[ENUM PROCESS]:step 4 TD Status Byte is %x\n",IORD(CY7C67200_BASE,HPI_DATA)); IOWR(CY7C67200_BASE,HPI_ADDR,0x0508); usb_ctl_val = IORD(CY7C67200_BASE,HPI_DATA); printf("[ENUM PROCESS]:step 4 TD Control Byte is %x\n",usb_ctl_val); while (usb_ctl_val != 0x03) { usb_ctl_val = UsbGetRetryCnt(); } printf("---------------[ENUM PROCESS]:get device descriptor-1 done!-----------------\n"); //--------------------------------get device descriptor-2---------------------------------------------// //get device descriptor // TASK: Call the appropriate function for this step. UsbGetDeviceDesc2(); usleep(100*1000); //if no message while (!(IORD(CY7C67200_BASE,HPI_STATUS) & HPI_STATUS_SIE1msg_FLAG) ) //read sie1 msg register { //resend the get device descriptor //get device descriptor // TASK: Call the appropriate function again if it wasn't processed successfully. UsbGetDeviceDesc2(); usleep(10*1000); } UsbWaitTDListDone(); IOWR(CY7C67200_BASE,HPI_ADDR,0x0506); printf("[ENUM PROCESS]:step 4 TD Status Byte is %x\n",IORD(CY7C67200_BASE,HPI_DATA)); IOWR(CY7C67200_BASE,HPI_ADDR,0x0508); usb_ctl_val = IORD(CY7C67200_BASE,HPI_DATA); printf("[ENUM PROCESS]:step 4 TD Control Byte is %x\n",usb_ctl_val); while (usb_ctl_val != 0x03) { usb_ctl_val = UsbGetRetryCnt(); } printf("------------[ENUM PROCESS]:get device descriptor-2 done!--------------\n"); // STEP 5 begin //-----------------------------------get configuration descriptor -1 ----------------------------------// // TASK: Call the appropriate function for this step. UsbGetConfigDesc1(); usleep(10*1000); //if no message while (!(IORD(CY7C67200_BASE,HPI_STATUS) & HPI_STATUS_SIE1msg_FLAG) ) //read sie1 msg register { //resend the get device descriptor //get device descriptor // TASK: Call the appropriate function again if it wasn't processed successfully. UsbGetConfigDesc1(); usleep(10*1000); } UsbWaitTDListDone(); IOWR(CY7C67200_BASE,HPI_ADDR,0x0506); printf("[ENUM PROCESS]:step 5 TD Status Byte is %x\n",IORD(CY7C67200_BASE,HPI_DATA)); IOWR(CY7C67200_BASE,HPI_ADDR,0x0508); usb_ctl_val = IORD(CY7C67200_BASE,HPI_DATA); printf("[ENUM PROCESS]:step 5 TD Control Byte is %x\n",usb_ctl_val); while (usb_ctl_val != 0x03) { usb_ctl_val = UsbGetRetryCnt(); } printf("------------[ENUM PROCESS]:get configuration descriptor-1 pass------------\n"); // STEP 6 begin //-----------------------------------get configuration descriptor-2------------------------------------// //get device descriptor // TASK: Call the appropriate function for this step. UsbGetConfigDesc2(); usleep(100*1000); //if no message while (!(IORD(CY7C67200_BASE,HPI_STATUS) & HPI_STATUS_SIE1msg_FLAG) ) //read sie1 msg register { // TASK: Call the appropriate function again if it wasn't processed successfully. UsbGetConfigDesc2(); usleep(10*1000); } UsbWaitTDListDone(); IOWR(CY7C67200_BASE,HPI_ADDR,0x0506); printf("[ENUM PROCESS]:step 6 TD Status Byte is %x\n",IORD(CY7C67200_BASE,HPI_DATA)); IOWR(CY7C67200_BASE,HPI_ADDR,0x0508); usb_ctl_val = IORD(CY7C67200_BASE,HPI_DATA); printf("[ENUM PROCESS]:step 6 TD Control Byte is %x\n",usb_ctl_val); while (usb_ctl_val != 0x03) { usb_ctl_val = UsbGetRetryCnt(); } printf("-----------[ENUM PROCESS]:get configuration descriptor-2 done!------------\n"); // ---------------------------------get device info---------------------------------------------// UsbPrintMem(); // TASK: Write the address to read from the memory for byte 7 of the interface descriptor to HPI_ADDR. //UsbWrite(HPI_ADDR,0x056C); IOWR(CY7C67200_BASE,HPI_ADDR,0x56c); code = IORD(CY7C67200_BASE,HPI_DATA); printf("\ncode = %x\n", code); code = code & 0x0003; if (code == 0x01) { printf("\n[INFO]:check TD rec data7 \n[INFO]:Keyboard Detected!!!\n\n"); } else { //printf("\nvalue= %x\n", code); printf("\n[INFO]:Keyboard Not Detected!!! \n\n"); } // TASK: Write the address to read from the memory for the endpoint descriptor to HPI_ADDR. //UsbWrite(HPI_DATA,0x56C); //IOWR(CY7C67200_BASE,HPI_ADDR,0x0578); //data_size = (IORD(CY7C67200_BASE,HPI_DATA)>>8)&0x00ff; data_size=8; printf("[ENUM PROCESS]:data packet size is %d\n",data_size); // STEP 7 begin //------------------------------------set configuration -----------------------------------------// // TASK: Call the appropriate function for this step. usleep(10*1000); UsbSetConfig(); while (!(IORD(CY7C67200_BASE,HPI_STATUS) & HPI_STATUS_SIE1msg_FLAG) ) //read sie1 msg register { // TASK: Call the appropriate function again if it wasn't processed successfully. usleep(10*1000); UsbSetConfig(); } UsbWaitTDListDone(); IOWR(CY7C67200_BASE,HPI_ADDR,0x0506); printf("[ENUM PROCESS]:step 7 TD Status Byte is %x\n",IORD(CY7C67200_BASE,HPI_DATA)); IOWR(CY7C67200_BASE,HPI_ADDR,0x0508); usb_ctl_val = IORD(CY7C67200_BASE,HPI_DATA); printf("[ENUM PROCESS]:step 7 TD Control Byte is %x\n",usb_ctl_val); while (usb_ctl_val != 0x03) { usb_ctl_val = UsbGetRetryCnt(); } printf("------------[ENUM PROCESS]:set configuration done!-------------------\n"); //----------------------------------------------class request out ------------------------------------------// // TASK: Call the appropriate function for this step. UsbClassRequest(); usleep(10*1000); while (!(IORD(CY7C67200_BASE,HPI_STATUS) & HPI_STATUS_SIE1msg_FLAG) ) //read sie1 msg register { // TASK: Call the appropriate function again if it wasn't processed successfully. UsbClassRequest(); usleep(10*1000); } UsbWaitTDListDone(); IOWR(CY7C67200_BASE,HPI_ADDR,0x0506); printf("[ENUM PROCESS]:step 8 TD Status Byte is %x\n",IORD(CY7C67200_BASE,HPI_DATA)); IOWR(CY7C67200_BASE,HPI_ADDR,0x0508); usb_ctl_val = IORD(CY7C67200_BASE,HPI_DATA); printf("[ENUM PROCESS]:step 8 TD Control Byte is %x\n",usb_ctl_val); while (usb_ctl_val != 0x03) { usb_ctl_val = UsbGetRetryCnt(); } printf("------------[ENUM PROCESS]:class request out done!-------------------\n"); // STEP 8 begin //----------------------------------get descriptor(class 0x21 = HID) request out --------------------------------// // TASK: Call the appropriate function for this step. UsbGetHidDesc(); usleep(10*1000); while (!(IORD(CY7C67200_BASE,HPI_STATUS) & HPI_STATUS_SIE1msg_FLAG) ) //read sie1 msg register { // TASK: Call the appropriate function again if it wasn't processed successfully. UsbGetHidDesc(); usleep(10*1000); } UsbWaitTDListDone(); IOWR(CY7C67200_BASE,HPI_ADDR,0x0506); printf("[ENUM PROCESS]:step 8 TD Status Byte is %x\n",IORD(CY7C67200_BASE,HPI_DATA)); IOWR(CY7C67200_BASE,HPI_ADDR,0x0508); usb_ctl_val = IORD(CY7C67200_BASE,HPI_DATA); printf("[ENUM PROCESS]:step 8 TD Control Byte is %x\n",usb_ctl_val); while (usb_ctl_val != 0x03) { usb_ctl_val = UsbGetRetryCnt(); } printf("------------[ENUM PROCESS]:get descriptor (class 0x21) done!-------------------\n"); // STEP 9 begin //-------------------------------get descriptor (class 0x22 = report)-------------------------------------------// // TASK: Call the appropriate function for this step. UsbGetReportDesc(); usleep(100*1000); //if no message while (!(IORD(CY7C67200_BASE,HPI_STATUS) & HPI_STATUS_SIE1msg_FLAG) ) //read sie1 msg register { // TASK: Call the appropriate function again if it wasn't processed successfully. UsbGetReportDesc(); usleep(10*1000); } UsbWaitTDListDone(); IOWR(CY7C67200_BASE,HPI_ADDR,0x0506); printf("[ENUM PROCESS]: step 9 TD Status Byte is %x\n",IORD(CY7C67200_BASE,HPI_DATA)); IOWR(CY7C67200_BASE,HPI_ADDR,0x0508); usb_ctl_val = IORD(CY7C67200_BASE,HPI_DATA); printf("[ENUM PROCESS]: step 9 TD Control Byte is %x\n",usb_ctl_val); while (usb_ctl_val != 0x03) { usb_ctl_val = UsbGetRetryCnt(); } printf("---------------[ENUM PROCESS]:get descriptor (class 0x22) done!----------------\n"); //-----------------------------------get keycode value------------------------------------------------// usleep(10000); while(1) { toggle++; IOWR(CY7C67200_BASE,HPI_ADDR,0x0500); //the start address //data phase IN-1 IOWR(CY7C67200_BASE,HPI_DATA,0x051c); //500 IOWR(CY7C67200_BASE,HPI_DATA,0x000f & data_size);//2 data length IOWR(CY7C67200_BASE,HPI_DATA,0x0291);//4 //endpoint 1 if(toggle%2) { IOWR(CY7C67200_BASE,HPI_DATA,0x0001);//6 //data 1 } else { IOWR(CY7C67200_BASE,HPI_DATA,0x0041);//6 //data 1 } IOWR(CY7C67200_BASE,HPI_DATA,0x0013);//8 IOWR(CY7C67200_BASE,HPI_DATA,0x0000);//a UsbWrite(HUSB_SIE1_pCurrentTDPtr,0x0500); //HUSB_SIE1_pCurrentTDPtr //usleep(10*1000); while (!(IORD(CY7C67200_BASE,HPI_STATUS) & HPI_STATUS_SIE1msg_FLAG) ) //read sie1 msg register { IOWR(CY7C67200_BASE,HPI_ADDR,0x0500); //the start address //data phase IN-1 IOWR(CY7C67200_BASE,HPI_DATA,0x051c); //500 IOWR(CY7C67200_BASE,HPI_DATA,0x000f & data_size);//2 data length IOWR(CY7C67200_BASE,HPI_DATA,0x0291);//4 //endpoint 1 if(toggle%2) { IOWR(CY7C67200_BASE,HPI_DATA,0x0001);//6 //data 1 } else { IOWR(CY7C67200_BASE,HPI_DATA,0x0041);//6 //data 1 } IOWR(CY7C67200_BASE,HPI_DATA,0x0013);//8 IOWR(CY7C67200_BASE,HPI_DATA,0x0000);// UsbWrite(HUSB_SIE1_pCurrentTDPtr,0x0500); //HUSB_SIE1_pCurrentTDPtr usleep(10*1000); }//end while usb_ctl_val = UsbWaitTDListDone(); // packet starts from 0x051c, reading third byte // TASK: Write the address to read from the memory for byte 3 of the report descriptor to HPI_ADDR. IOWR(CY7C67200_BASE,HPI_ADDR,0x051E); keycode = IORD(CY7C67200_BASE,HPI_DATA); printf("\nfirst two keycode values are %04x\n",keycode); IOWR(KEYCODE_BASE, 0, keycode & 0xff); usleep(5*1000); //USB hot plug routine usb_ctl_val = UsbRead(ctl_reg); usleep(5*1000); usb_ctl_val = UsbRead(ctl_reg); usleep(5*1000); usb_ctl_val = UsbRead(ctl_reg); usleep(5*1000); usb_ctl_val = UsbRead(ctl_reg); usleep(5*1000); usb_ctl_val = UsbRead(ctl_reg); usleep(5*1000); usb_ctl_val = UsbRead(ctl_reg); usleep(5*1000); if(!(usb_ctl_val & no_device)) { printf("\n[INFO]: the keyboard has been removed!!! \n"); printf("[INFO]: please insert again!!! \n"); }; usleep(5000); usb_ctl_val = UsbRead(ctl_reg); while (!(usb_ctl_val & no_device)) { usb_ctl_val = UsbRead(ctl_reg); usleep(5*1000); usb_ctl_val = UsbRead(ctl_reg); usleep(5*1000); usb_ctl_val = UsbRead(ctl_reg); usleep(5*1000); if(usb_ctl_val & no_device) goto USB_HOT_PLUG; usleep(200); } }//end while return 0; }