/** * @brief USBH_Connect * USB Connect callback function from the Interrupt. * @param selected device * @retval none */ rt_uint8_t susb_connect (USB_OTG_CORE_HANDLE *pdev) { struct uhost_msg msg; pdev->host.ConnSts = 1; rt_kprintf("susb_connect\n"); if(root_hub.port_status[0] & PORT_CCS) return 0; if(ignore_disconnect == RT_TRUE) return 0; USB_Host.Control.hc_num_out = USBH_Alloc_Channel(&USB_OTG_Core, 0x00); USB_Host.Control.hc_num_in = USBH_Alloc_Channel(&USB_OTG_Core, 0x80); /* Open Control pipes */ USBH_Open_Channel(&USB_OTG_Core, USB_Host.Control.hc_num_in, USB_Host.device_prop.address,USB_Host.device_prop.speed, EP_TYPE_CTRL, USB_Host.Control.ep0size); /* Open Control pipes */ USBH_Open_Channel(&USB_OTG_Core, USB_Host.Control.hc_num_out, USB_Host.device_prop.address, USB_Host.device_prop.speed, EP_TYPE_CTRL, USB_Host.Control.ep0size); root_hub.port_status[0] |= (PORT_CCS | PORT_CCSC); msg.type = USB_MSG_CONNECT_CHANGE; msg.content.uhub = &root_hub; rt_usb_post_event(&msg, sizeof(struct uhost_msg)); return 0; }
/** * @brief USBH_MSC_InterfaceInit * Interface initialization for MSC class. * @param pdev: Selected device * @param hdev: Selected device property * @retval USBH_Status : Status of class request handled. */ static USBH_Status USBH_MSC_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev, void *phost) { USBH_HOST *pphost = phost; if((pphost->device_prop.Itf_Desc[0].bInterfaceClass == MSC_CLASS) && \ (pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == MSC_PROTOCOL)) { if(pphost->device_prop.Ep_Desc[0][0].bEndpointAddress & 0x80) { MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress); MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize; } else { MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress); MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0] [0].wMaxPacketSize; } if(pphost->device_prop.Ep_Desc[0][1].bEndpointAddress & 0x80) { MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress); MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize; } else { MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress); MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize; } MSC_Machine.hc_num_out = USBH_Alloc_Channel(pdev, MSC_Machine.MSBulkOutEp); MSC_Machine.hc_num_in = USBH_Alloc_Channel(pdev, MSC_Machine.MSBulkInEp); /* Open the new channels */ USBH_Open_Channel (pdev, MSC_Machine.hc_num_out, pphost->device_prop.address, pphost->device_prop.speed, EP_TYPE_BULK, MSC_Machine.MSBulkOutEpSize); USBH_Open_Channel (pdev, MSC_Machine.hc_num_in, pphost->device_prop.address, pphost->device_prop.speed, EP_TYPE_BULK, MSC_Machine.MSBulkInEpSize); } else { pphost->usr_cb->DeviceNotSupported(); } return USBH_OK ; }
/** * @brief USBH_MSC_InterfaceInit * Interface initialization for MSC class. * @param pdev: Selected device * @param hdev: Selected device property * @retval USBH_Status : Status of class request handled. */ static USBH_Status USBH_MSC_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev, USBH_DeviceProp_TypeDef *hdev) { if((hdev->Itf_Desc.bInterfaceClass == MSC_CLASS) && \ (hdev->Itf_Desc.bInterfaceProtocol == MSC_PROTOCOL)) { if(hdev->Ep_Desc[0].bEndpointAddress & 0x80) { MSC_Machine.MSBulkInEp = (hdev->Ep_Desc[0].bEndpointAddress); MSC_Machine.MSBulkInEpSize = hdev->Ep_Desc[0].wMaxPacketSize; } else { MSC_Machine.MSBulkOutEp = (hdev->Ep_Desc[0].bEndpointAddress); MSC_Machine.MSBulkOutEpSize = hdev->Ep_Desc[0].wMaxPacketSize; } if(hdev->Ep_Desc[1].bEndpointAddress & 0x80) { MSC_Machine.MSBulkInEp = (hdev->Ep_Desc[1].bEndpointAddress); MSC_Machine.MSBulkInEpSize = hdev->Ep_Desc[1].wMaxPacketSize; } else { MSC_Machine.MSBulkOutEp = (hdev->Ep_Desc[1].bEndpointAddress); MSC_Machine.MSBulkOutEpSize = hdev->Ep_Desc[1].wMaxPacketSize; } MSC_Machine.hc_num_out = USBH_Alloc_Channel(&USB_OTG_FS_dev, MSC_Machine.MSBulkOutEp); MSC_Machine.hc_num_in = USBH_Alloc_Channel(&USB_OTG_FS_dev, MSC_Machine.MSBulkInEp); /* Open the new channels */ USBH_Open_Channel (pdev, MSC_Machine.hc_num_out, hdev->address, hdev->speed, EP_TYPE_BULK, MSC_Machine.MSBulkOutEpSize); USBH_Open_Channel (pdev, MSC_Machine.hc_num_in, hdev->address, hdev->speed, EP_TYPE_BULK, MSC_Machine.MSBulkInEpSize); } else { USBH_Machine.usr_cb->USBH_USR_DeviceNotSupported(); } return USBH_OK ; }
/** * This function will allocate a pipe for specified endpoint, it will be used to do transfer. * * @param pipe the pointer of pipe handle to be allocated. * @param ifinst the usb interface instance. * @param ep the endpoint descriptor. * @param func_callback callback function to be registed * * @return the error code, RT_EOK on successfully. */ static rt_err_t susb_alloc_pipe(upipe_t* pipe, uifinst_t ifinst, uep_desc_t ep, func_callback callback) { rt_uint32_t channel, speed; rt_uint8_t ep_type; upipe_t p; RT_ASSERT(ep != RT_NULL); p = (upipe_t)rt_malloc(sizeof(struct upipe)); p->ifinst = ifinst; p->callback = callback; p->status = UPIPE_STATUS_OK; rt_memcpy(&p->ep, ep, ep->bLength); speed = HCD_GetCurrentSpeed(&USB_OTG_Core); channel = USBH_Alloc_Channel(&USB_OTG_Core, p->ep.bEndpointAddress); if((ep->bmAttributes & USB_EP_ATTR_TYPE_MASK) == USB_EP_ATTR_BULK) ep_type = EP_TYPE_BULK; else if((ep->bmAttributes & USB_EP_ATTR_TYPE_MASK) == USB_EP_ATTR_INT) ep_type = EP_TYPE_INTR; else rt_kprintf("unsupported endpoint type\n"); /* Open the new channels */ USBH_Open_Channel(&USB_OTG_Core, channel, ifinst->uinst->address, speed, ep_type, p->ep.wMaxPacketSize); RT_DEBUG_LOG(1, ("susb_alloc_pipe : %d, chanel %d, max packet size %d\n", p->ep.bEndpointAddress, channel, p->ep.wMaxPacketSize)); p->user_data = (void*)channel; *pipe = p; return RT_EOK; }
/** * @brief USBH_Process * USB Host core main state machine process * @param None * @retval None */ void USBH_Process(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost) { volatile USBH_Status status = USBH_FAIL; /* check for Host port events */ if ((HCD_IsDeviceConnected(pdev) == 0)&& (phost->gState != HOST_IDLE)) { if(phost->gState != HOST_DEV_DISCONNECTED) { phost->gState = HOST_DEV_DISCONNECTED; } } switch (phost->gState) { case HOST_IDLE : if (HCD_IsDeviceConnected(pdev)) { phost->gState = HOST_DEV_ATTACHED; USB_OTG_BSP_mDelay(100); } break; case HOST_DEV_ATTACHED : phost->usr_cb->DeviceAttached(); phost->Control.hc_num_out = USBH_Alloc_Channel(pdev, 0x00); phost->Control.hc_num_in = USBH_Alloc_Channel(pdev, 0x80); /* Reset USB Device */ if ( HCD_ResetPort(pdev) == 0) { phost->usr_cb->ResetDevice(); /* Wait for USB USBH_ISR_PrtEnDisableChange() Host is Now ready to start the Enumeration */ phost->device_prop.speed = HCD_GetCurrentSpeed(pdev); phost->gState = HOST_ENUMERATION; phost->usr_cb->DeviceSpeedDetected(phost->device_prop.speed); /* Open Control pipes */ USBH_Open_Channel (pdev, phost->Control.hc_num_in, phost->device_prop.address, phost->device_prop.speed, EP_TYPE_CTRL, phost->Control.ep0size); /* Open Control pipes */ USBH_Open_Channel (pdev, phost->Control.hc_num_out, phost->device_prop.address, phost->device_prop.speed, EP_TYPE_CTRL, phost->Control.ep0size); } break; case HOST_ENUMERATION: /* Check for enumeration status */ if ( USBH_HandleEnum(pdev , phost) == USBH_OK) { /* The function shall return USBH_OK when full enumeration is complete */ /* user callback for end of device basic enumeration */ phost->usr_cb->EnumerationDone(); phost->gState = HOST_USR_INPUT; } break; case HOST_USR_INPUT: /*The function should return user response true to move to class state */ if ( phost->usr_cb->UserInput() == USBH_USR_RESP_OK) { if((phost->class_cb->Init(pdev, phost))\ == USBH_OK) { phost->gState = HOST_CLASS_REQUEST; } } break; case HOST_CLASS_REQUEST: /* process class standard contol requests state machine */ status = phost->class_cb->Requests(pdev, phost); if(status == USBH_OK) { phost->gState = HOST_CLASS; } else { USBH_ErrorHandle(phost, status); } break; case HOST_CLASS: /* process class state machine */ status = phost->class_cb->Machine(pdev, phost); USBH_ErrorHandle(phost, status); break; case HOST_CTRL_XFER: /* process control transfer state machine */ USBH_HandleControl(pdev, phost); break; case HOST_SUSPENDED: break; case HOST_ERROR_STATE: /* Re-Initilaize Host for new Enumeration */ USBH_DeInit(pdev, phost); phost->usr_cb->DeInit(); phost->class_cb->DeInit(pdev, &phost->device_prop); break; case HOST_DEV_DISCONNECTED : /* Manage User disconnect operations*/ phost->usr_cb->DeviceDisconnected(); /* Re-Initilaize Host for new Enumeration */ USBH_DeInit(pdev, phost); phost->usr_cb->DeInit(); phost->class_cb->DeInit(pdev, &phost->device_prop); USBH_DeAllocate_AllChannel(pdev); phost->gState = HOST_IDLE; break; default : break; } }
/** * @brief USBH_HID_InterfaceInit * The function init the HID class. * @param pdev: Selected device * @param hdev: Selected device property * @retval USBH_Status :Response for USB HID driver intialization */ static USBH_Status USBH_HID_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev, void *phost) { uint8_t maxEP; USBH_HOST *pphost = phost; HID_Machine_TypeDef *HID_Machine = &HID_Machines[pdev->cfg.coreID]; uint8_t num =0; USBH_Status status = USBH_BUSY ; HID_Machine->state = HID_ERROR; // should always be the case, no need to detect //if (HID_GAMEPAD_cb.Detect(pphost->device_prop.Dev_Desc.idVendor, pphost->device_prop.Dev_Desc.idProduct) || (pphost->device_prop.Itf_Desc[0].bInterfaceSubClass == HID_BOOT_CODE)) { /*Decode Bootclass Protocl: Mouse or Keyboard*/ if(pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == HID_KEYBRD_BOOT_CODE) { HID_Machine->cb = &HID_KEYBRD_cb; } else if(pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == HID_MOUSE_BOOT_CODE) { HID_Machine->cb = &HID_MOUSE_cb; } else { HID_Machine->cb = &HID_GAMEPAD_cb; } HID_Machine->state = HID_IDLE; HID_Machine->ctl_state = HID_REQ_IDLE; HID_Machine->ep_addr = pphost->device_prop.Ep_Desc[0][0].bEndpointAddress; HID_Machine->length = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize; HID_Machine->poll = pphost->device_prop.Ep_Desc[0][0].bInterval ; if (HID_Machine->poll < HID_MIN_POLL) { HID_Machine->poll = HID_MIN_POLL; } /* Check fo available number of endpoints */ /* Find the number of EPs in the Interface Descriptor */ /* Choose the lower number in order not to overrun the buffer allocated */ maxEP = ( (pphost->device_prop.Itf_Desc[0].bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS) ? pphost->device_prop.Itf_Desc[0].bNumEndpoints : USBH_MAX_NUM_ENDPOINTS); /* Decode endpoint IN and OUT address from interface descriptor */ for (num=0; num < maxEP; num++) { if(pphost->device_prop.Ep_Desc[0][num].bEndpointAddress & 0x80) { HID_Machine->HIDIntInEp = (pphost->device_prop.Ep_Desc[0][num].bEndpointAddress); HID_Machine->hc_num_in =\ USBH_Alloc_Channel(pdev, pphost->device_prop.Ep_Desc[0][num].bEndpointAddress); /* Open channel for IN endpoint */ USBH_Open_Channel (pdev, HID_Machine->hc_num_in, pphost->device_prop.address, pphost->device_prop.speed, EP_TYPE_INTR, HID_Machine->length); } else { HID_Machine->HIDIntOutEp = (pphost->device_prop.Ep_Desc[0][num].bEndpointAddress); HID_Machine->hc_num_out =\ USBH_Alloc_Channel(pdev, pphost->device_prop.Ep_Desc[0][num].bEndpointAddress); /* Open channel for OUT endpoint */ USBH_Open_Channel (pdev, HID_Machine->hc_num_out, pphost->device_prop.address, pphost->device_prop.speed, EP_TYPE_INTR, HID_Machine->length); } } start_toggles[pdev->cfg.coreID] =0; status = USBH_OK; } /* else { // pphost->usr_cb->DeviceNotSupported(); } */ return status; }
/** * @brief USBH_HID_InterfaceInit * The function init the HID class. * @param pdev: Selected device * @param hdev: Selected device property * @retval USBH_Status :Response for USB HID driver intialization */ static USBH_Status USBH_HID_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev, void *phost) { uint8_t maxEP; USBH_HOST *pphost = phost; uint8_t num =0; USBH_Status status = USBH_BUSY ; HID_Machine.state = HID_ERROR; //printf("USBH_HID_InterfaceInit\n"); if(pphost->device_prop.Itf_Desc[0].bInterfaceSubClass == HID_BOOT_CODE) { /*Decode Bootclass Protocl: Mouse or Keyboard*/ if(pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == HID_KEYBRD_BOOT_CODE) { HID_Machine.cb = &HID_KEYBRD_cb; } else if(pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == HID_MOUSE_BOOT_CODE) { HID_Machine.cb = &HID_MOUSE_cb; } //printf("USBH_HID_InterfaceInit %x %x\n", pphost->device_prop.Itf_Desc[0].bInterfaceSubClass, pphost->device_prop.Itf_Desc[0].bInterfaceProtocol); HID_Machine.state = HID_IDLE; HID_Machine.ctl_state = HID_REQ_IDLE; HID_Machine.ep_addr = pphost->device_prop.Ep_Desc[0][0].bEndpointAddress; HID_Machine.length = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize; HID_Machine.poll = pphost->device_prop.Ep_Desc[0][0].bInterval ; if (HID_Machine.poll < HID_MIN_POLL) { HID_Machine.poll = HID_MIN_POLL; } /* Check fo available number of endpoints */ /* Find the number of EPs in the Interface Descriptor */ /* Choose the lower number in order not to overrun the buffer allocated */ maxEP = ( (pphost->device_prop.Itf_Desc[0].bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS) ? pphost->device_prop.Itf_Desc[0].bNumEndpoints : USBH_MAX_NUM_ENDPOINTS); /* Decode endpoint IN and OUT address from interface descriptor */ for (num=0; num < maxEP; num++) { if(pphost->device_prop.Ep_Desc[0][num].bEndpointAddress & 0x80) { HID_Machine.HIDIntInEp = (pphost->device_prop.Ep_Desc[0][num].bEndpointAddress); HID_Machine.hc_num_in =\ USBH_Alloc_Channel(pdev, pphost->device_prop.Ep_Desc[0][num].bEndpointAddress); /* Open channel for IN endpoint */ USBH_Open_Channel (pdev, HID_Machine.hc_num_in, pphost->device_prop.address, pphost->device_prop.speed, EP_TYPE_INTR, HID_Machine.length); } else { HID_Machine.HIDIntOutEp = (pphost->device_prop.Ep_Desc[0][num].bEndpointAddress); HID_Machine.hc_num_out =\ USBH_Alloc_Channel(pdev, pphost->device_prop.Ep_Desc[0][num].bEndpointAddress); /* Open channel for OUT endpoint */ USBH_Open_Channel (pdev, HID_Machine.hc_num_out, pphost->device_prop.address, pphost->device_prop.speed, EP_TYPE_INTR, HID_Machine.length); } } start_toggle =0; status = USBH_OK; } else { pphost->usr_cb->DeviceNotSupported(); } return status; }
/** * @brief USBH_Process * USB Host core main state machine process * @param None * @retval None */ void USBH_Process(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost) { volatile USBH_Status status = USBH_FAIL; /* check for Host port events */ if (((HCD_IsDeviceConnected(pdev) == 0)|| (HCD_IsPortEnabled(pdev) == 0))&& (phost->gState != HOST_IDLE)) { if(phost->gState != HOST_DEV_DISCONNECTED) { phost->gState = HOST_DEV_DISCONNECTED; } } switch (phost->gState) { case HOST_IDLE : if (HCD_IsDeviceConnected(pdev)) { phost->gState = HOST_WAIT_PRT_ENABLED; /*wait denounce delay */ USB_OTG_BSP_mDelay(100); /* Apply a port RESET */ HCD_ResetPort(pdev); /* User RESET callback*/ phost->usr_cb->ResetDevice(); } break; case HOST_WAIT_PRT_ENABLED: if (pdev->host.PortEnabled == 1) { phost->gState = HOST_DEV_ATTACHED; USB_OTG_BSP_mDelay(50); } break; case HOST_DEV_ATTACHED : phost->usr_cb->DeviceAttached(); phost->Control.hc_num_out = USBH_Alloc_Channel(pdev, 0x00); phost->Control.hc_num_in = USBH_Alloc_Channel(pdev, 0x80); /* Reset USB Device */ if ( HCD_ResetPort(pdev) == 0) { phost->usr_cb->ResetDevice(); /* Host is Now ready to start the Enumeration */ phost->device_prop.speed = HCD_GetCurrentSpeed(pdev); phost->gState = HOST_ENUMERATION; phost->usr_cb->DeviceSpeedDetected(phost->device_prop.speed); /* Open Control pipes */ USBH_Open_Channel (pdev, phost->Control.hc_num_in, phost->device_prop.address, phost->device_prop.speed, EP_TYPE_CTRL, phost->Control.ep0size); /* Open Control pipes */ USBH_Open_Channel (pdev, phost->Control.hc_num_out, phost->device_prop.address, phost->device_prop.speed, EP_TYPE_CTRL, phost->Control.ep0size); } break; case HOST_ENUMERATION: /* Check for enumeration status */ if ( USBH_HandleEnum(pdev , phost) == USBH_OK) { /* The function shall return USBH_OK when full enumeration is complete */ /* user callback for end of device basic enumeration */ phost->usr_cb->EnumerationDone(); #if defined (USB_OTG_FS_LOW_PWR_MGMT_SUPPORT) || defined (USB_OTG_HS_LOW_PWR_MGMT_SUPPORT) phost->gState = HOST_SUSPENDED; #else phost->gState = HOST_USR_INPUT; #endif /* LOW_PWR_MGMT_SUPPORT*/ } break; case HOST_USR_INPUT: /*The function should return user response true to move to class state */ if ( phost->usr_cb->UserInput() == USBH_USR_RESP_OK) { if((phost->class_cb->Init(pdev, phost))\ == USBH_OK) { phost->gState = HOST_CLASS_REQUEST; } } break; case HOST_CLASS_REQUEST: /* process class standard control requests state machine */ status = phost->class_cb->Requests(pdev, phost); if(status == USBH_OK) { phost->gState = HOST_CLASS; } else { USBH_ErrorHandle(phost, status); } break; case HOST_CLASS: /* process class state machine */ status = phost->class_cb->Machine(pdev, phost); USBH_ErrorHandle(phost, status); break; case HOST_CTRL_XFER: /* process control transfer state machine */ USBH_HandleControl(pdev, phost); break; #if defined (USB_OTG_FS_LOW_PWR_MGMT_SUPPORT) || defined (USB_OTG_HS_LOW_PWR_MGMT_SUPPORT) case HOST_SUSPENDED: if (USBH_SetDeviceFeature(pdev, phost, FEATURE_SELECTOR_DEVICE, 0)==USBH_OK) { suspend_flag = 1; USB_OTG_BSP_Suspend(pdev); phost->usr_cb->UserInput(); PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); /* After wakeup got to HOST_WAKEUP state */ phost->gState = HOST_WAKEUP; } break; case HOST_WAKEUP: /* issue a ClearDeviceFeature request */ if (USBH_ClearDeviceFeature(pdev, phost, FEATURE_SELECTOR_DEVICE, 0)==USBH_OK) { phost->gState = HOST_USR_INPUT; } break; #endif /* USE_HOST_MODE */ case HOST_ERROR_STATE: /* Re-Initialize Host for new Enumeration */ USBH_DeInit(pdev, phost); phost->usr_cb->DeInit(); phost->class_cb->DeInit(pdev, &phost->device_prop); break; case HOST_DEV_DISCONNECTED : /* Manage User disconnect operations*/ phost->usr_cb->DeviceDisconnected(); /* Re-Initialize Host for new Enumeration */ USBH_DeInit(pdev, phost); phost->usr_cb->DeInit(); phost->class_cb->DeInit(pdev, &phost->device_prop); USBH_DeAllocate_AllChannel(pdev); phost->gState = HOST_IDLE; /* Re-Initialize Host for new Enumeration */ HCD_Init(pdev, #ifdef USE_USB_OTG_FS USB_OTG_FS_CORE_ID #else USB_OTG_HS_CORE_ID #endif ); break; default : break; } }
/** * @brief USBH_Process * USB Host core main state machine process * @param None * @retval None */ void USBH_Process(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost) { volatile USBH_Status status = USBH_FAIL; // if (USB_DEBUG) { // USB_debugEvent(); // xprintf("USBH_Process phost->gState = %d\n", phost->gState); // } /* check for Host port events */ if (((HCD_IsDeviceConnected(pdev) == 0) || (HCD_IsPortEnabled(pdev) == 0)) && (phost->gState != HOST_IDLE)) { if (phost->gState != HOST_DEV_DISCONNECTED) { phost->gState = HOST_DEV_DISCONNECTED; // if (USB_DEBUG){ // USB_debugEvent(); // } } } switch (phost->gState) { case HOST_IDLE: if (HCD_IsDeviceConnected(pdev)) { phost->gState = HOST_WAIT_PRT_ENABLED; /*wait debounce delay */ USB_OTG_BSP_mDelay(200); // was 100 // if (USB_DEBUG){ // USB_debugEvent(); // } /* Apply a port RESET */ HCD_ResetPort(pdev); /* User RESET callback*/ phost->usr_cb->ResetDevice(); } break; case HOST_WAIT_PRT_ENABLED: if (pdev->host.PortEnabled == 1) { phost->gState = HOST_DEV_ATTACHED; } break; case HOST_DEV_ATTACHED: phost->usr_cb->DeviceAttached(); phost->Control.hc_num_out = USBH_Alloc_Channel(pdev, 0x00); phost->Control.hc_num_in = USBH_Alloc_Channel(pdev, 0x80); // if (USB_DEBUG){ // USB_debugEvent(); // } phost->device_prop.speed = HCD_GetCurrentSpeed(pdev); phost->gState = HOST_ENUMERATION; phost->usr_cb->DeviceSpeedDetected(phost->device_prop.speed); // if (USB_DEBUG){ // USB_debugEvent(); // } /* Open Control pipes */ USBH_Open_Channel(pdev, phost->Control.hc_num_in, phost->device_prop.address, phost->device_prop.speed, EP_TYPE_CTRL, phost->Control.ep0size); // if (USB_DEBUG){ // USB_debugEvent(); // } /* Open Control pipes */ USBH_Open_Channel(pdev, phost->Control.hc_num_out, phost->device_prop.address, phost->device_prop.speed, EP_TYPE_CTRL, phost->Control.ep0size); // if (USB_DEBUG){ // USB_debugEvent(); // } break; case HOST_ENUMERATION: /* Check for enumeration status */ if (USBH_HandleEnum(pdev, phost) == USBH_OK) { /* The function shall return USBH_OK when full enumeration is complete */ /* user callback for end of device basic enumeration */ phost->usr_cb->EnumerationDone(); phost->gState = HOST_USR_INPUT; // if (USB_DEBUG){ // USB_debugEvent(); // } } break; case HOST_USR_INPUT: /*The function should return user response true to move to class state */ if (phost->usr_cb->UserInput() == USBH_USR_RESP_OK) { if ((phost->class_cb->Init(pdev, phost))\ == USBH_OK) { phost->gState = HOST_CLASS_REQUEST; } // if (USB_DEBUG){ // USB_debugEvent(); // } } break; case HOST_CLASS_REQUEST: /* process class standard contol requests state machine */ // if (USB_DEBUG){ // USB_debugEvent(); // } status = phost->class_cb->Requests(pdev, phost); if (status == USBH_OK) { phost->gState = HOST_CLASS; // if (USB_DEBUG){ // USB_debugEvent(); // } } else { // if (USB_DEBUG){ // USB_debugEvent(); // } USBH_ErrorHandle(phost, status); } break; case HOST_CLASS: /* process class state machine */ status = phost->class_cb->Machine(pdev, phost); // if (USB_DEBUG){ // USB_debugEvent(); // } USBH_ErrorHandle(phost, status); break; case HOST_CTRL_XFER: /* process control transfer state machine */ // if (USB_DEBUG){ // USB_debugEvent(); // } USBH_HandleControl(pdev, phost); break; case HOST_SUSPENDED: break; case HOST_ERROR_STATE: /* Re-Initilaize Host for new Enumeration */ // if (USB_DEBUG){ // USB_debugEvent(); // } USBH_DeInit(pdev, phost); phost->usr_cb->DeInit(); phost->class_cb->DeInit(pdev, &phost->device_prop); break; case HOST_DEV_DISCONNECTED: // if (USB_DEBUG){ // USB_debugEvent(); // } /* Manage User disconnect operations*/ phost->usr_cb->DeviceDisconnected(); /* Re-Initilaize Host for new Enumeration */ USBH_DeInit(pdev, phost); phost->usr_cb->DeInit(); phost->class_cb->DeInit(pdev, &phost->device_prop); USBH_DeAllocate_AllChannel(pdev); phost->gState = HOST_IDLE; /* Re-Initilaize Host for new Enumeration */ HCD_Init(pdev, #ifdef USE_USB_OTG_FS USB_OTG_FS_CORE_ID #else USB_OTG_HS_CORE_ID #endif ); break; default: break; } }
/* * This is broken. We need to enumerate differently. * It causes major problems with several devices if detected in an unexpected order. * * * Oleg - I wouldn't do anything before the newly connected device is considered sane. * i.e.(delays are not indicated for brevity): * 1. reset * 2. GetDevDescr(); * 3a. If ACK, continue with allocating address, addressing, etc. * 3b. Else reset again, count resets, stop at some number (5?). * 4. When max.number of resets is reached, toggle power/fail * If desired, this could be modified by performing two resets with GetDevDescr() in the middle - however, from my experience, if a device answers to GDD() * it doesn't need to be reset again * New steps proposal: * 1: get address pool instance. exit on fail * 2: pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf). exit on fail. * 3: bus reset, 100ms delay * 4: set address * 5: pUsb->setEpInfoEntry(bAddress, 1, epInfo), exit on fail * 6: while (configurations) { * for(each configuration) { * for (each driver) { * 6a: Ask device if it likes configuration. Returns 0 on OK. * If successful, the driver configured device. * The driver now owns the endpoints, and takes over managing them. * The following will need codes: * Everything went well, instance consumed, exit with success. * Instance already in use, ignore it, try next driver. * Not a supported device, ignore it, try next driver. * Not a supported configuration for this device, ignore it, try next driver. * Could not configure device, fatal, exit with fail. * } * } * } * 7: for(each driver) { * 7a: Ask device if it knows this VID/PID. Acts exactly like 6a, but using VID/PID * 8: if we get here, no driver likes the device plugged in, so exit failure. * */ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) { //uint8_t bAddress = 0; //printf("Configuring: parent = %i, port = %i\r\n", parent, port); uint8_t devConfigIndex; uint8_t rcode = 0; uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)]; UsbDevice *p = NULL; EpInfo *oldep_ptr = NULL; EpInfo epInfo; USB_OTG_CORE_HANDLE *pdev = coreConfig; epInfo.epAddr = 0; epInfo.maxPktSize = 8; epInfo.epAttribs = 0; epInfo.bmNakPower = USB_NAK_MAX_POWER; // assume: // HC0 for control - out // HC1 for control - in //uint8_t hcnum = USBH_GetFreeChannel(pdev); //if(hcnum > 1) { // USBH_Free_Channel(pdev, epInfo.hcNumOut); // USBH_Free_Channel(pdev, epInfo.hcNumIn); //} USBH_Free_Channel(pdev, 0); USBH_Free_Channel(pdev, 1); epInfo.hcNumOut = USBH_Alloc_Channel(pdev, 0x00); // ep_addr = 0 epInfo.hcNumIn = USBH_Alloc_Channel(pdev, 0x80); USBH_Open_Channel(pdev, epInfo.hcNumOut, 0x0, (lowspeed)?bmLOWSPEED:bmFULLSPEED, EP_TYPE_CTRL, 0x8); USBH_Open_Channel(pdev, epInfo.hcNumIn, 0x0, (lowspeed)?bmLOWSPEED:bmFULLSPEED, EP_TYPE_CTRL, 0x8); printf("\nControl Pipe: out = %d (0), in = %d (1)", epInfo.hcNumOut, epInfo.hcNumIn); delay_ms(1000); AddressPool &addrPool = GetAddressPool(); // Get pointer to pseudo device with address 0 assigned p = addrPool.GetUsbDevicePtr(0); if (!p) { printf("Configuring error: USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL\r\n"); return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; } // Save old pointer to EP_RECORD of address 0 // oldep_ptr = p->epinfo; // Temporary assign new pointer to epInfo to p->epinfo in order to // avoid toggle inconsistence p->epinfo = &epInfo; p->lowspeed = lowspeed; // Get device descriptor rcode = getDevDescr(0, 0, 8, (uint8_t*)buf); // 8 should be enough, sizeof (USB_DEVICE_DESCRIPTOR) printf("\nControl - Got 1st 8 bytes desc"); // Extract Max Packet Size from the device descriptor epInfo.maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; //USB::USBH_Modify_Channel (pdev, epInfo.hcNumOut, 0, 0, 0, 0, epInfo.maxPktSize); //USB::USBH_Modify_Channel (pdev, epInfo.hcNumIn, 0, 0, 0, 0, epInfo.maxPktSize); // Restore p->epinfo // keep CtrlXfer's hcNumOut/In in p->epinfo. p->epinfo = oldep_ptr; if (rcode) { printf("Configuring error: Can't get USB_DEVICE_DESCRIPTOR\r\n"); return rcode; } // to-do? // Allocate new address according to device class //bAddress = addrPool.AllocAddress(parent, false, port); //if (!bAddress) // return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; rcode = getDevDescr(0, 0, sizeof(USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); printf("\nControl - Got 2nd 18 bytes desc."); uint16_t vid = (uint16_t)((USB_DEVICE_DESCRIPTOR*)buf)->idVendor; uint16_t pid = (uint16_t)((USB_DEVICE_DESCRIPTOR*)buf)->idProduct; uint8_t klass = ((USB_DEVICE_DESCRIPTOR*)buf)->bDeviceClass; // Attempt to configure if VID/PID or device class matches with a driver for (devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) { if (!devConfig[devConfigIndex]) continue; // no driver if (devConfig[devConfigIndex]->GetAddress()) continue; // consumed if (devConfig[devConfigIndex]->VIDPIDOK(vid, pid)) { rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed); break; } else if (devConfig[devConfigIndex]->DEVCLASSOK(klass)) { rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed); if (!rcode) break; } } if (devConfigIndex < USB_NUMDEVICES) { return rcode; } // blindly attempt to configure for (devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) { if (!devConfig[devConfigIndex]) continue; if (devConfig[devConfigIndex]->GetAddress()) continue; // consumed rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed); //printf("ERROR ENUMERATING %2.2x\r\n", rcode); if (!(rcode == USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED || rcode == USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE)) { // in case of an error dev_index should be reset to 0 // in order to start from the very beginning the // next time the program gets here //if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) // devConfigIndex = 0; return rcode; } } // if we get here that means that the device class is not supported by any of registered classes rcode = DefaultAddressing(parent, port, lowspeed); return rcode; }
/** * @brief CDC_InterfaceInit * The function init the CDC class. * @param pdev: Selected device * @param hdev: Selected device property * @retval USBH_Status :Response for USB CDC driver intialization */ static USBH_Status CDC_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev, void *phost) { USBH_HOST *pphost = phost; USBH_Status status = USBH_OK ; /* Communication Interface */ if((pphost->device_prop.Itf_Desc[0].bInterfaceClass == COMMUNICATION_DEVICE_CLASS_CODE)&& \ (pphost->device_prop.Itf_Desc[0].bInterfaceSubClass == ABSTRACT_CONTROL_MODEL) && \ (pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == COMMON_AT_COMMAND)) { /*Collect the notification endpoint address and length*/ CDC_Machine.CDC_CommItf.ep_addr = pphost->device_prop.Ep_Desc[0][0].bEndpointAddress; CDC_Machine.CDC_CommItf.length = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize; if(pphost->device_prop.Ep_Desc[0][0].bEndpointAddress & 0x80) { CDC_Machine.CDC_CommItf.notificationEp =\ (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress); } /*Allocate the length for host channel number in*/ CDC_Machine.CDC_CommItf.hc_num_in = USBH_Alloc_Channel(pdev, CDC_Machine.CDC_CommItf.notificationEp ); /* Open channel for IN endpoint */ USBH_Open_Channel (pdev, CDC_Machine.CDC_CommItf.hc_num_in, pphost->device_prop.address, pphost->device_prop.speed, EP_TYPE_INTR, CDC_Machine.CDC_CommItf.length); } else { pphost->usr_cb->DeviceNotSupported(); } /* Data Interface */ if((pphost->device_prop.Itf_Desc[1].bInterfaceClass == DATA_INTERFACE_CLASS_CODE)&& \ (pphost->device_prop.Itf_Desc[1].bInterfaceSubClass == RESERVED) && \ (pphost->device_prop.Itf_Desc[1].bInterfaceProtocol == NO_CLASS_SPECIFIC_PROTOCOL_CODE)) { /*Collect the class specific endpoint address and length*/ CDC_Machine.CDC_DataItf.ep_addr = pphost->device_prop.Ep_Desc[1][0].bEndpointAddress; CDC_Machine.CDC_DataItf.length = pphost->device_prop.Ep_Desc[1][0].wMaxPacketSize; if(pphost->device_prop.Ep_Desc[1][0].bEndpointAddress & 0x80) { CDC_Machine.CDC_DataItf.cdcInEp = (pphost->device_prop.Ep_Desc[1][0].bEndpointAddress); } else { CDC_Machine.CDC_DataItf.cdcOutEp = (pphost->device_prop.Ep_Desc[1][0].bEndpointAddress); } if(pphost->device_prop.Ep_Desc[1][1].bEndpointAddress & 0x80) { CDC_Machine.CDC_DataItf.cdcInEp = (pphost->device_prop.Ep_Desc[1][1].bEndpointAddress); } else { CDC_Machine.CDC_DataItf.cdcOutEp = (pphost->device_prop.Ep_Desc[1][1].bEndpointAddress); } /*Allocate the length for host channel number out*/ CDC_Machine.CDC_DataItf.hc_num_out = USBH_Alloc_Channel(pdev, CDC_Machine.CDC_DataItf.cdcOutEp); /*Allocate the length for host channel number in*/ CDC_Machine.CDC_DataItf.hc_num_in = USBH_Alloc_Channel(pdev, CDC_Machine.CDC_DataItf.cdcInEp); /* Open channel for OUT endpoint */ USBH_Open_Channel (pdev, CDC_Machine.CDC_DataItf.hc_num_out, pphost->device_prop.address, pphost->device_prop.speed, EP_TYPE_BULK, CDC_Machine.CDC_DataItf.length); /* Open channel for IN endpoint */ USBH_Open_Channel (pdev, CDC_Machine.CDC_DataItf.hc_num_in, pphost->device_prop.address, pphost->device_prop.speed, EP_TYPE_BULK, CDC_Machine.CDC_DataItf.length); /*Initilise the Tx/Rx Params*/ CDC_InitTxRxParam(); /*Initialize the class specific request with "GET_LINE_CODING"*/ CDC_ReqState = CDC_GET_LINE_CODING_RQUEST ; } else { pphost->usr_cb->DeviceNotSupported(); } return status; }
static void _dev_probe_entry(void *parameter) { wifi_usb_adapter_t *adapter = (wifi_usb_adapter_t *)&wifi_usb_adapter; USB_OTG_CORE_HANDLE *pdev = &USB_OTG_Core_dev; USBH_HOST *pphost = &USB_Host; DBGPRINT(WHED_DEBUG_TRACE, "%s: ---->\n", __FUNCTION__); DBGPRINT(WHED_DEBUG_TRACE, "VID:%x, PID:%x.\n",\ pphost->device_prop.Dev_Desc.idVendor, pphost->device_prop.Dev_Desc.idProduct); if (!adapter->device_matched) { DBGPRINT(WHED_DEBUG_ERROR, "Device is not supported.\n"); return; } /* Control channel */ adapter->usb_ctrl_req.ep0size = pphost->Control.ep0size; /* no use */ adapter->usb_ctrl_req.hc_num_in = pphost->Control.hc_num_in; adapter->usb_ctrl_req.hc_num_out = pphost->Control.hc_num_out; DBGPRINT(WHED_DEBUG_TRACE, "Control in pipe - 0x%x\n", adapter->usb_ctrl_req.hc_num_in); DBGPRINT(WHED_DEBUG_TRACE, "Control out pipe - 0x%x\n", adapter->usb_ctrl_req.hc_num_out); /* Data IN channel */ adapter->hc_num_in = USBH_Alloc_Channel(pdev, adapter->bulk_in_ep); USBH_Open_Channel(pdev, adapter->hc_num_in, pphost->device_prop.address, pphost->device_prop.speed, EP_TYPE_BULK, adapter->bulk_in_ep_size); DBGPRINT(WHED_DEBUG_TRACE, "Bulk in pipe - 0x%x\n", adapter->hc_num_in); /* Data OUT channel */ adapter->hc_num_out = USBH_Alloc_Channel(pdev, adapter->bulk_out_ep); USBH_Open_Channel(pdev, adapter->hc_num_out, pphost->device_prop.address, pphost->device_prop.speed, EP_TYPE_BULK, adapter->bulk_out_ep_size); DBGPRINT(WHED_DEBUG_TRACE, "Bulk out pipe - 0x%x\n", adapter->hc_num_out); /* Initialize the usb request state machine. */ adapter->usb_ctrl_req.state = CTRL_IDLE; adapter->usb_tx_req.state = USB_BULK_STATE_IDLE; adapter->usb_rx_req.state = USB_BULK_STATE_IDLE; adapter->usb_ctrl_req.retry = 3; adapter->usb_tx_req.retry = 3; adapter->usb_rx_req.retry = 3; /* Initialize the Wifi module, */ rt2870_probe(adapter, &adapter->pAdapter); /* Inform to the system */ sys_add_event_queue(&p_cms_envar->sys, SYS_MSG_INITED, 0, 0, 0); }
/** * @brief USBH_MSC_InterfaceInit * Interface initialization for MSC class. * @param pdev: Selected device * @param hdev: Selected device property * @retval USBH_Status : Status of class request handled. */ static USBH_Status USBH_MSC_InterfaceInit ( USB_OTG_CORE_HANDLE *pdev, void *phost) { USBH_HOST *pphost = phost; if((pphost->device_prop.Itf_Desc[0].bInterfaceClass == MSC_CLASS) && \ (pphost->device_prop.Itf_Desc[0].bInterfaceProtocol == MSC_PROTOCOL)) { if(pphost->device_prop.Ep_Desc[0][0].bEndpointAddress & 0x80) { MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress); MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][0].wMaxPacketSize; } else { MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][0].bEndpointAddress); MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0] [0].wMaxPacketSize; } if(pphost->device_prop.Ep_Desc[0][1].bEndpointAddress & 0x80) { MSC_Machine.MSBulkInEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress); MSC_Machine.MSBulkInEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize; } else { MSC_Machine.MSBulkOutEp = (pphost->device_prop.Ep_Desc[0][1].bEndpointAddress); MSC_Machine.MSBulkOutEpSize = pphost->device_prop.Ep_Desc[0][1].wMaxPacketSize; } MSC_Machine.hc_num_out = USBH_Alloc_Channel(pdev, MSC_Machine.MSBulkOutEp); MSC_Machine.hc_num_in = USBH_Alloc_Channel(pdev, MSC_Machine.MSBulkInEp); /* Open the new channels */ USBH_Open_Channel (pdev, MSC_Machine.hc_num_out, pphost->device_prop.address, pphost->device_prop.speed, EP_TYPE_BULK, MSC_Machine.MSBulkOutEpSize); USBH_Open_Channel (pdev, MSC_Machine.hc_num_in, pphost->device_prop.address, pphost->device_prop.speed, EP_TYPE_BULK, MSC_Machine.MSBulkInEpSize); } else { if (pphost->device_prop.Itf_Desc[0].bInterfaceClass == USB_HUB) { LCD_ErrLog("Hub is not supported.\n"); } else if (pphost->device_prop.Itf_Desc[0].bInterfaceClass == USB_CDCC) { LCD_ErrLog("Communications and CDC Control device is not supported.\n"); } else if (pphost->device_prop.Itf_Desc[0].bInterfaceClass == USB_HID) { LCD_ErrLog("HID device is not supported.\n"); } else if (pphost->device_prop.Itf_Desc[0].bInterfaceClass == USB_PRINTER) { LCD_ErrLog("Printer device is not supported.\n"); } else if (pphost->device_prop.Itf_Desc[0].bInterfaceClass == USB_SMARTCARD) { LCD_ErrLog("Smart Card device is not supported.\n"); } else if (pphost->device_prop.Itf_Desc[0].bInterfaceClass == USB_VIDEO) { LCD_ErrLog("Video device is not supported.\n"); } else if (pphost->device_prop.Itf_Desc[0].bInterfaceClass == USB_AVD) { LCD_ErrLog("Audio/Video Devices is not supported.\n"); } else { LCD_ErrLog ("The attached device is not supported. \n"); } pphost->usr_cb->DeviceNotSupported(); } return USBH_OK ; }
/** * @brief USBH_Process * USB Host core main state machine process * @param None * @retval None */ void USBH_Process(USB_OTG_CORE_HANDLE *pdev , USBH_HOST *phost) { volatile USBH_Status status = USBH_FAIL; /* check for Host port events */ if ((HCD_IsDeviceConnected(pdev) == 0)&& (phost->gState != HOST_IDLE)) { printf("check for Host port events\r\n"); if(phost->gState != HOST_DEV_DISCONNECTED) { phost->gState = HOST_DEV_DISCONNECTED; } } switch (phost->gState) { case HOST_IDLE : if (HCD_IsDeviceConnected(pdev)) { printf("HOST_DEV_ATTACHED is enter\r\n"); phost->gState = HOST_DEV_ATTACHED; USB_OTG_BSP_mDelay(100); } break; case HOST_DEV_ATTACHED : phost->usr_cb->DeviceAttached(); phost->Control.hc_num_out = USBH_Alloc_Channel(pdev, 0x00); phost->Control.hc_num_in = USBH_Alloc_Channel(pdev, 0x80); /* Reset USB Device */ if ( HCD_ResetPort(pdev) == 0) { printf("HOST_DEV_ATTACHED state reset device"); phost->usr_cb->ResetDevice(); /* Wait for USB USBH_ISR_PrtEnDisableChange() Host is Now ready to start the Enumeration */ phost->device_prop.speed = HCD_GetCurrentSpeed(pdev); phost->gState = HOST_ENUMERATION; phost->usr_cb->DeviceSpeedDetected(phost->device_prop.speed); /* Open Control pipes */ USBH_Open_Channel (pdev, phost->Control.hc_num_in, phost->device_prop.address, phost->device_prop.speed, EP_TYPE_CTRL, phost->Control.ep0size); /* Open Control pipes */ USBH_Open_Channel (pdev, phost->Control.hc_num_out, phost->device_prop.address, phost->device_prop.speed, EP_TYPE_CTRL, phost->Control.ep0size); } // printfpdev_reg(pdev); break; case HOST_ENUMERATION: // printfpdev_reg(pdev); // printf(" in HOST_ENUMERATION state\r\n "); /* Check for enumeration status */ if ( USBH_HandleEnum(pdev , phost) == USBH_OK) { printf("HOST_ENUMERATION state enumeration is ok"); /* The function shall return USBH_OK when full enumeration is complete */ /* user callback for end of device basic enumeration */ phost->usr_cb->EnumerationDone(); phost->gState = HOST_USR_INPUT; } break; case HOST_USR_INPUT: /*The function should return user response true to move to class state */ if ( phost->usr_cb->UserInput() == USBH_USR_RESP_OK) { printf("HOST_USR_INPUT state : user_input is ok\r\n"); if((phost->class_cb->Init(pdev, phost))\ == USBH_OK) { phost->gState = HOST_CLASS_REQUEST; } } // printf("GINTSTS :%X\r\n",(pdev->regs.GREGS->GINTSTS)); break; case HOST_CLASS_REQUEST: /* process class standard contol requests state machine */ status = phost->class_cb->Requests(pdev, phost); if(status == USBH_OK) { printf("HOST_CLASS_REQUEST state : contol requests is ok and host class is enter\r\n"); phost->gState = HOST_CLASS; #if 0 // USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFNUM,0X43FD039B); printf("GRXSTSR: %X\r\n", USB_OTG_READ_REG32(&pdev->regs.GREGS->GRXSTSR)); printf("HNPTXSTS: %X\r\n", USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS)); printf("HFNUM: %X\r\n", USB_OTG_READ_REG32(&pdev->regs.HREGS->HFNUM)); printf("HNPTXSTS: %X\r\n", USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS)); printf("DIEPTSIZ: %X\r\n", USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[8]->DIEPCTL )); printf("DIEPDMA: %X\r\n", USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[8]->DIEPDMA )); printfpdev_reg(pdev); #endif } else { USBH_ErrorHandle(phost, status); } break; case HOST_CLASS: /* process class state machine */ status = phost->class_cb->Machine(pdev, phost); USBH_ErrorHandle(phost, status); break; case HOST_CTRL_XFER: /* process control transfer state machine */ printf("HOST_CTRL_XFER\r\n"); USBH_HandleControl(pdev, phost); break; case HOST_SUSPENDED: printf("HOST_SUSPENDED\r\n"); break; case HOST_ERROR_STATE: /* Re-Initilaize Host for new Enumeration */ USBH_DeInit(pdev, phost); phost->usr_cb->DeInit(); phost->class_cb->DeInit(pdev, &phost->device_prop); break; case HOST_DEV_DISCONNECTED : /* Manage User disconnect operations*/ phost->usr_cb->DeviceDisconnected();//user µ÷ÓÃ /* Re-Initilaize Host for new Enumeration */ USBH_DeInit(pdev, phost); phost->usr_cb->DeInit(); phost->class_cb->DeInit(pdev, &phost->device_prop); USBH_DeAllocate_AllChannel(pdev); phost->gState = HOST_IDLE; // NVIC_SystemReset(); break; default : break; } }