예제 #1
0
/**
  * @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 ;

}
예제 #3
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, 
                                     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 ;
 
}
예제 #4
0
/**
 * 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;
}
예제 #5
0
/**
* @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;
  
}
예제 #6
0
/**
* @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;
  
}
예제 #7
0
/**
 * @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;
	}

}
예제 #8
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 ;
 
}
예제 #9
0
void USBPT_Work()
{
	if (USBPT_Has_Dev == 0)
	{
		if (HCD_IsDeviceConnected(&USB_OTG_Core_host) != 0)
		{
			USBPT_printf("USBPT Device Connecting \r\n");

			if (USBH_Open_Channel(	&USB_OTG_Core_host,
					&(USBPT_Dev->Control.hc_num_in),
					0x80,
					USBPT_Dev->device_prop.address, // still 0 at this point
					USBPT_Dev->device_prop.speed,
					EP_TYPE_CTRL,
					USBPT_Dev->Control.ep0size) == HC_OK
				&&
				USBH_Open_Channel(	&USB_OTG_Core_host,
					&(USBPT_Dev->Control.hc_num_out),
					0x00,
					USBPT_Dev->device_prop.address, // still 0 at this point
					USBPT_Dev->device_prop.speed,
					EP_TYPE_CTRL,
					USBPT_Dev->Control.ep0size) == HC_OK
			) {
				DCD_DevConnect(&USB_OTG_Core_dev);
				USBPT_Has_Dev = 1;
			}
			else
			{
				dbg_printf(DBGMODE_ERR, "USBPT Unable to allocate control EP HC \r\n");
			}
		}
		else
		{
			return;
		}
	}
	else
	{
		if (HCD_IsDeviceConnected(&USB_OTG_Core_host) == 0)
		{
			USBPT_printf("USBPT Device Disconnecting \r\n");
			USBD_DeInit(&USB_OTG_Core_dev);
			DCD_DevDisconnect(&USB_OTG_Core_dev);
			USBPT_Has_Dev = 0;

			for (uint8_t i = 0; i < USBPTH_MAX_LISTENERS; i++)
			{
				USBH_Free_Channel(&USB_OTG_Core_host, &(USBPTH_Listeners[i].hc));
			}

			USBH_Free_Channel(&USB_OTG_Core_host, &(USBPT_Dev->Control.hc_num_out));
			USBH_Free_Channel(&USB_OTG_Core_host, &(USBPT_Dev->Control.hc_num_in));
		}
	}

	for (uint8_t i = 0; i < USBPTH_MAX_LISTENERS; i++)
	{
		USBPTH_HC_EP_t* pl = &USBPTH_Listeners[i];
		int8_t hc = USBPTH_Listeners[i].hc;
		if (hc >= 0) // if listener is actually allocated
		{
			USBH_EpDesc_TypeDef* epDesc = pl->epDesc;
			uint8_t epnum = epDesc->bEndpointAddress;
			uint8_t epType = 0;
			USBPT_GeneralInDataLen = epDesc->wMaxPacketSize;

			// try to send read tokens only on even frames
			if (USB_OTG_IsEvenFrame(&USB_OTG_Core_host) == 0) continue;

			dbg_trace();

			// attempt to start the read, check the read type first
			if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_INTR) {
				epType = EP_TYPE_INTR;
				USBH_InterruptReceiveData(&USB_OTG_Core_host, USBPT_GeneralInData, USBPT_GeneralInDataLen, hc);
			}
			else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_BULK) {
				epType = EP_TYPE_BULK;
				USBH_BulkReceiveData(&USB_OTG_Core_host, USBPT_GeneralInData, USBPT_GeneralInDataLen, hc);
			}
			else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_ISOC) {
				epType = EP_TYPE_ISOC;
				USBH_IsocReceiveData(&USB_OTG_Core_host, USBPT_GeneralInData, USBPT_GeneralInDataLen, hc);
			}

			// now we wait for a reply, or maybe there isn't one
			USBH_Status status;
			char sent = 0;
			delay_1ms_cnt = 100;
			do
			{
				URB_STATE us = HCD_GetURB_State(&USB_OTG_Core_host, hc);
				if (us == URB_DONE)
				{
					// data was indeed received

					// print it to the serial port for monitoring
					USBPT_printf("USBPT:IN:EP0x%02X:", epnum);
					for (uint16_t c = 0; c < USBPT_GeneralInDataLen; c++) {
						USBPT_printf(" 0x%02X", USBPT_GeneralInData[c]);
					}
					USBPT_printf("\r\n");

					// relay the data to the host
					DCD_EP_Tx(&USB_OTG_Core_dev, epnum, USBPT_GeneralInData, USBPT_GeneralInDataLen);
					sent = 1;
					break;
				}
				else if (us == URB_ERROR) {
					dbg_printf(DBGMODE_ERR, "DataIn Error on EP 0x%02X \r\n", epnum);
					break;
				}
				else if (us == URB_STALL) {
					dbg_printf(DBGMODE_ERR, "DataIn Stalled EP 0x%02X \r\n", epnum);
					break;
				}
				else if (us == URB_NOTREADY) {
					// NAK, no data
					break;
				}
			}
			while (delay_1ms_cnt > 0);

			if (delay_1ms_cnt == 0) {
				dbg_printf(DBGMODE_ERR, "DataIn Read Timed Out EP 0x%02X \r\n", epnum);
			}
		}
	}
}
예제 #10
0
uint8_t USBPTD_DataOut           (void *pcore , uint8_t epnum)
{
	USB_OTG_CORE_HANDLE* pcore_ = (USB_OTG_CORE_HANDLE*)pcore;
	DCD_DEV* pdev = &(pcore_->dev);
	uint8_t* data;
	uint16_t wLength;

	if (epnum == 0x00)
	{ // CTRL REQ
		wLength = USBPT_CtrlDataLen;
		data = USBPT_CtrlData;
	}
	else
	{
		wLength = pdev->out_ep[epnum].xfer_count;
		data = pdev->out_ep[epnum].xfer_buff;
	}

	// print to monitor
	USBPT_printf("USBPT:OUT:EP0x%02X:", epnum);
	for (uint16_t i = 0; i < wLength; i++) {
		USBPT_printf(" 0x%02X", data[i]);
	}
	USBPT_printf("\r\n");

	if (epnum == 0x00)
	{ // CTRL REQ

		USBH_Status status;
		delay_1ms_cnt = 100;

		// wait for transfer complete
		do
		{
			status = USBH_CtlReq(&USB_OTG_Core_host, USBPT_Dev, USBPT_CtrlData , USBPT_CtrlDataLen );
			if (status == USBH_OK || status == USBH_FAIL || status == USBH_STALL || status == USBH_NOT_SUPPORTED) {
				break;
			}
			else
			{
				status = USBH_HandleControl(&USB_OTG_Core_host, USBPT_Dev);
				if (status == USBH_FAIL || status == USBH_STALL || status == USBH_NOT_SUPPORTED) {
					break;
				}
			}
		}
		while (delay_1ms_cnt > 0);

		if (delay_1ms_cnt == 0) {
			dbg_printf(DBGMODE_ERR, "USBPTD_DataOut timed out while sending to device, status: 0x%04X \r\n", status);
			USBD_CtlError(pcore , 0);
			return USBD_FAIL;
		}
		else if (status != USBH_OK) {
			dbg_printf(DBGMODE_ERR, "USBPTD_DataOut failed to send to device, status: 0x%04X \r\n", status);
			USBD_CtlError(pcore , 0);
			return USBD_FAIL;
		}
		else { // everything is OK
			USBD_CtlSendStatus(pcore);
			return USBD_OK;
		}
	}
	else
	{
		wLength = pdev->out_ep[epnum].xfer_count;
		data = pdev->out_ep[epnum].xfer_buff;

		// allocate memory needed
		if (USBPT_GeneralOutData != 0) free(USBPT_GeneralOutData);
		USBPT_GeneralOutDataLen = wLength;
		USBPT_GeneralOutData = malloc(wLength);
		memcpy(USBPT_GeneralOutData, data, USBPT_GeneralOutDataLen);

		USBH_EpDesc_TypeDef* epDesc = 0;
		for (uint8_t i = 0; i < USBPTH_OutEPCnt; i++)
		{
			// look for appropriate EP
			if (USBPTH_OutEP[i]->bEndpointAddress == epnum) {
				epDesc = USBPTH_OutEP[i];
				break;
			}
		}

		if (epDesc != 0) // EP found
		{
			uint8_t epType = 0;
			int8_t hc = -1;
			if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_INTR) {
				epType = EP_TYPE_INTR;
			}
			else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_BULK) {
				epType = EP_TYPE_BULK;
			}
			else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_ISOC) {
				epType = EP_TYPE_ISOC;
			}

			// dynamically allocate host channel for use
			if (USBH_Open_Channel(	&USB_OTG_Core_host,
									&hc,
									epnum,
									USBPT_Dev->device_prop.address,
									USBPT_Dev->device_prop.speed,
									epType,
									epDesc->wMaxPacketSize) == HC_OK)
			{

				// try to only send on even frame
				volatile uint32_t syncTries = 0x7FFFFFFF;
				while (USB_OTG_IsEvenFrame(&USB_OTG_Core_host) == 0 && syncTries--) __NOP();

				// send using appropriate method
				switch (epType)
				{
					case EP_TYPE_INTR:
						USBH_InterruptSendData(&USB_OTG_Core_host, USBPT_GeneralOutData, USBPT_GeneralOutDataLen, hc);
						break;
					case EP_TYPE_BULK:
						USBH_BulkSendData(&USB_OTG_Core_host, USBPT_GeneralOutData, USBPT_GeneralOutDataLen, hc);
						break;
					case EP_TYPE_ISOC:
						USBH_IsocSendData(&USB_OTG_Core_host, USBPT_GeneralOutData, USBPT_GeneralOutDataLen, hc);
						break;
					default:
						break;
				}

				// wait until done sending
				USBH_Status status;
				delay_1ms_cnt = 100;
				do
				{
					URB_STATE us = HCD_GetURB_State(&USB_OTG_Core_host, hc);
					if (us == URB_DONE) {
						break;
					}
					else if (us == URB_ERROR) {
						dbg_printf(DBGMODE_ERR, "USBPTD_DataOut Send Error on EP 0x%02X \r\n", epnum);
						DCD_EP_Stall(pcore, epnum);
						break;
					}
					else if (us == URB_STALL) {
						dbg_printf(DBGMODE_ERR, "USBPTD_DataOut Stalled EP 0x%02X \r\n", epnum);
						DCD_EP_Stall(pcore, epnum);
						break;
					}
				}
				while (delay_1ms_cnt > 0);

				if (delay_1ms_cnt == 0) {
					dbg_printf(DBGMODE_ERR, "USBPTD_DataOut Send Timed Out EP 0x%02X \r\n", epnum);
				}

				// free the channel to be used by something else later
				USBH_Free_Channel(&USB_OTG_Core_host, &hc);
			}
			else
			{
				dbg_printf(DBGMODE_ERR, "USBPTD_DataOut Failed to Alloc HC for EP 0x%02X \r\n", epnum);
			}

		}
		else
		{
			dbg_printf(DBGMODE_ERR, "USBPTD_DataOut No Such EP 0x%02X \r\n", epnum);
		}

		return USBD_OK;
	}

	return USBD_OK;
}
예제 #11
0
uint8_t USBPTD_SetupStage(USB_OTG_CORE_HANDLE* pcore, USB_SETUP_REQ* req)
{
	// store for later use from another function
	memcpy(USBPT_LastSetupPacket, pcore->dev.setup_packet, 24);

	// print for monitoring
	USBPT_printf("\b\r\n USBPT:SETUP:");
	for (uint8_t i = 0; i < 8; i++) {
		USBPT_printf(" 0x%02X", USBPT_LastSetupPacket[i]);
	}
	USBPT_printf("\r\n");

	// prepare to be sent to the device
	memcpy(USBPT_Dev->Control.setup.d8, USBPT_LastSetupPacket, 8);

	// set address must be handled explicitly
	if ((req->bmRequest & 0x7F) == (USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD) && req->bRequest == USB_REQ_SET_ADDRESS)
	{
		// let the internal code handle it for the device interface
		USBD_StdDevReq(pcore, req);

		// pass it to the downstream device
		USBH_CtlReq_Blocking(&USB_OTG_Core_host, USBPT_Dev, 0, 0, 100);
		USBD_CtlSendStatus(pcore);

		// modifiy our host channel to match
		USBPT_Dev->device_prop.address = (uint8_t)(req->wValue) & 0x7F;
		USBH_Modify_Channel (&USB_OTG_Core_host,
							USBPT_Dev->Control.hc_num_in,
							USBPT_Dev->device_prop.address,
							0,
							0,
							0);
		USBH_Modify_Channel (&USB_OTG_Core_host,
							USBPT_Dev->Control.hc_num_out,
							USBPT_Dev->device_prop.address,
							0,
							0,
							0);

		// modify all other channels to match
		for (uint8_t i = 0; i < USBPTH_MAX_LISTENERS; i++)
		{
			USBPTH_HC_EP_t* pl = &USBPTH_Listeners[i];
			uint8_t hc = pl->hc;
			if (hc != 0 && hc != HC_ERROR) // if listener is actually allocated
			{
				USBH_EpDesc_TypeDef* epDesc = pl->epDesc;
				uint8_t epType = 0;
				if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_INTR) {
					epType = EP_TYPE_INTR;
				}
				else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_BULK) {
					epType = EP_TYPE_BULK;
				}
				else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_ISOC) {
					epType = EP_TYPE_ISOC;
				}
				else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_CTRL) {
					epType = EP_TYPE_CTRL;
				}

				USBH_Modify_Channel(	&USB_OTG_Core_host,
										USBPTH_Listeners[i].hc,
										USBPT_Dev->device_prop.address,
										USBPT_Dev->device_prop.speed,
										epType,
										USBPTH_Listeners[i].epDesc->wMaxPacketSize);
			}
		}
		// note: out direction channels are dynamically allocated only when needed
		// so we don't need to modify those channel addresses

		return USBD_OK;
	}

	// no data means we can just directly relay the data
	if (req->wLength == 0) {
		USBH_CtlReq_Blocking(&USB_OTG_Core_host, USBPT_Dev, 0, 0, 100);
		USBD_CtlSendStatus(pcore);
		return USBD_OK;
	}

	// there is extra data later
	USBPT_CtrlDataLen = req->wLength;
	if (USBPT_CtrlData != 0) free(USBPT_CtrlData);
	USBPT_CtrlData = malloc(USBPT_CtrlDataLen);

	USBH_Status status;

	// wait until previous req is finished
	delay_1ms_cnt = 100;
	while (delay_1ms_cnt > 0 &&
			USBPT_Dev->Control.state != CTRL_COMPLETE &&
			USBPT_Dev->Control.state != CTRL_IDLE &&
			USBPT_Dev->Control.state != CTRL_ERROR &&
			USBPT_Dev->Control.state != CTRL_STALLED);
	{
		status = USBH_HandleControl(&USB_OTG_Core_host, USBPT_Dev);
	}

	// finalize previous ctrl req
	if (USBPT_Dev->RequestState == CMD_WAIT) {
		USBH_CtlReq(&USB_OTG_Core_host, USBPT_Dev, 0 , 0 );
	}

	// prepare new setup
	USBH_SubmitSetupRequest(USBPT_Dev, USBPT_CtrlData, USBPT_CtrlDataLen);
	USBPT_Dev->RequestState = CMD_WAIT;
	USBH_CtlSendSetup (&USB_OTG_Core_host, USBPT_Dev->Control.setup.d8, USBPT_Dev->Control.hc_num_out);
	USBPT_Dev->Control.state = CTRL_SETUP_WAIT;
	USBPT_Dev->Control.timer = HCD_GetCurrentFrame(pcore);
	USBPT_Dev->Control.timeout = 50;

	if ((req->bmRequest & 0x80) == 0)
	{ // H2D
		// we need to obtain the data from EP0_RxReady first
		USBD_CtlPrepareRx (pcore, USBPT_CtrlData, USBPT_CtrlDataLen);
		return USBD_OK;
	}
	else
	{ // D2H

		// wait for request to finish
		delay_1ms_cnt = 100;
		do
		{
			status = USBH_CtlReq(&USB_OTG_Core_host, USBPT_Dev, USBPT_CtrlData , USBPT_CtrlDataLen );
			if (status == USBH_OK || status == USBH_FAIL || status == USBH_STALL || status == USBH_NOT_SUPPORTED) {
				break;
			}
			else
			{
				status = USBH_HandleControl(&USB_OTG_Core_host, USBPT_Dev);
				if (status == USBH_FAIL || status == USBH_STALL || status == USBH_NOT_SUPPORTED) {
					break;
				}
			}
		}
		while (delay_1ms_cnt > 0);

		if (delay_1ms_cnt == 0)
		{
			// timeout
			dbg_printf(DBGMODE_ERR, "USBPT Setup Timed Out \r\n");
			USBD_CtlSendStatus(pcore); // we reply with nothing to simulate a timeout
			return USBH_OK;
		}
		else if (status == USBH_OK)
		{
			// all good, send back the data
			USBD_CtlSendData (pcore, USBPT_CtrlData, USBPT_CtrlDataLen);

			// handle config descriptors specially, we need to know what channels to open based on endpoints
			if ((req->bmRequest & 0x7F) == (USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD) &&
					req->bRequest == USB_REQ_GET_DESCRIPTOR &&
					req->wValue == USB_DESC_CONFIGURATION &&
					req->wLength > USB_CONFIGURATION_DESC_SIZE)
			{
				// this is a full length configuration descriptor
				// we need this info to open as many D2H endpoints to channels
				USBH_ParseCfgDesc(&USBPT_Dev->device_prop.Cfg_Desc,
									USBPT_Dev->device_prop.Itf_Desc,
									USBPT_Dev->device_prop.Ep_Desc,
									USBPT_CtrlData,
									USBPT_CtrlDataLen);

				USBPTH_OutEPCnt = 0;
				USBPT_GeneralInDataLen = 0;
				for (uint8_t i = 0; i < USBPT_Dev->device_prop.Cfg_Desc.bNumInterfaces && i < USBH_MAX_NUM_INTERFACES; i++)
				{
					for (uint8_t j = 0; j < USBPT_Dev->device_prop.Itf_Desc[i].bNumEndpoints && j < USBH_MAX_NUM_ENDPOINTS; j++)
					{
						USBH_EpDesc_TypeDef* epDesc = &USBPT_Dev->device_prop.Ep_Desc[i][j];
						for (uint8_t k = 0; k < USBPTH_MAX_LISTENERS; k++)
						{
							if ((epDesc->bEndpointAddress & USB_EP_DIR_MSK) == USB_D2H && USBPTH_Listeners[k].used == 0)
							{
								USBPTH_Listeners[k].epDesc = epDesc;
								uint8_t epType = 0;
								if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_INTR) {
									epType = EP_TYPE_INTR;
								}
								else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_BULK) {
									epType = EP_TYPE_BULK;
								}
								else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_ISOC) {
									epType = EP_TYPE_ISOC;
								}
								else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_CTRL) {
									epType = EP_TYPE_CTRL;
								}

								USBH_Open_Channel(	&USB_OTG_Core_host,
													&(USBPTH_Listeners[k].hc),
													epDesc->bEndpointAddress,
													USBPT_Dev->device_prop.address,
													USBPT_Dev->device_prop.speed,
													epType,
													USBPTH_Listeners[k].epDesc->wMaxPacketSize);

								if (USBPTH_Listeners[k].hc >= 0)
								{
									USBPTH_Listeners[k].used = 1;
									DCD_EP_Open(&USB_OTG_Core_dev, epDesc->bEndpointAddress, epDesc->wMaxPacketSize, epType);

									if (epDesc->wMaxPacketSize > USBPT_GeneralInDataMax) {
										USBPT_GeneralInDataMax = epDesc->wMaxPacketSize;
									}
								}
							}
						}

						if ((epDesc->bEndpointAddress & 0x80) == USB_H2D)
						{
							USBPTH_OutEPCnt++;
						}
					}
				}

				if (USBPT_GeneralInData != 0) free(USBPT_GeneralInData); // release memory if previously allocated
				USBPT_GeneralInData = malloc(USBPT_GeneralInDataMax); // only allocate the memory we need

				if (USBPTH_OutEP != 0) free(USBPTH_OutEP); // release memory if previously allocated
				USBPTH_OutEP = malloc(sizeof(USBH_EpDesc_TypeDef*) * USBPTH_OutEPCnt); // only allocate the memory we need

				uint8_t ec = 0;
				for (uint8_t i = 0; i < USBPT_Dev->device_prop.Cfg_Desc.bNumInterfaces && i < USBH_MAX_NUM_INTERFACES; i++)
				{
					for (uint8_t j = 0; j < USBPT_Dev->device_prop.Itf_Desc[i].bNumEndpoints && j < USBH_MAX_NUM_ENDPOINTS; j++)
					{
						USBH_EpDesc_TypeDef* epDesc = &USBPT_Dev->device_prop.Ep_Desc[i][j];
						if ((epDesc->bEndpointAddress & 0x80) == USB_H2D) {
							// only save the H2D direction endpoints
							USBPTH_OutEP[ec] = epDesc;
							ec++;
						}
					}
				}
			}
			return USBH_OK;
		}
		else
		{
			if (status == USBH_STALL || status == USBH_NOT_SUPPORTED) {
				dbg_printf(DBGMODE_ERR, "USBPT Setup Stalled \r\n");
				USBD_CtlError(pcore , req);
				return USBH_OK;
			}
		}

		return USBD_OK;
	}

	dbg_printf(DBGMODE_ERR, "USBPT Setup Unhandled Error \r\n");
	USBD_CtlError(pcore , req);

	return USBD_OK;
}
예제 #12
0
/*
 * 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;
  
}
예제 #14
0
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_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;
  }

}
예제 #16
0
/**
* @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;
  }

}
예제 #17
0
/**
* @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;
  }

}