Esempio n. 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 ;

}
Esempio n. 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 ;
 
}
Esempio n. 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;
}
Esempio n. 5
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;
  }

}
Esempio n. 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;
  
}
Esempio n. 7
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;
  
}
/**
* @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;
  }

}
Esempio n. 9
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;
	}

}
Esempio n. 10
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;
  
}
Esempio n. 12
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);
}
Esempio n. 13
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 ;
 
}
Esempio n. 14
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;
  }

}