示例#1
0
/**
  * @brief  USBH_HandleEnum
  *         This function includes the complete enumeration process
  * @param  pdev: Selected device
  * @retval USBH_Status
  */
static USBH_Status USBH_HandleEnum(USB_OTG_CORE_HANDLE *pdev, USBH_HOST *phost)
{
  USBH_Status Status = USBH_BUSY;
  uint8_t Local_Buffer[64];

  switch (phost->EnumState)
  {
  case ENUM_IDLE:
    /* Get Device Desc for only 1st 8 bytes : To get EP0 MaxPacketSize */
    if ( USBH_Get_DevDesc(pdev , phost, 8) == USBH_OK)
    {
      phost->Control.ep0size = phost->device_prop.Dev_Desc.bMaxPacketSize;

      /* Issue Reset  */
      HCD_ResetPort(pdev);
      phost->EnumState = ENUM_GET_FULL_DEV_DESC;

      /* modify control channels configuration for MaxPacket size */
      USBH_Modify_Channel (pdev,
                           phost->Control.hc_num_out,
                           0,
                           0,
                           0,
                           phost->Control.ep0size);

      USBH_Modify_Channel (pdev,
                           phost->Control.hc_num_in,
                           0,
                           0,
                           0,
                           phost->Control.ep0size);
    }
    break;

  case ENUM_GET_FULL_DEV_DESC:
    /* Get FULL Device Desc  */
    if ( USBH_Get_DevDesc(pdev, phost, USB_DEVICE_DESC_SIZE)\
      == USBH_OK)
    {
      /* user callback for device descriptor available */
      phost->usr_cb->DeviceDescAvailable(&phost->device_prop.Dev_Desc);
      phost->EnumState = ENUM_SET_ADDR;
    }
    break;

  case ENUM_SET_ADDR:
    /* set address */
    if ( USBH_SetAddress(pdev, phost, USBH_DEVICE_ADDRESS) == USBH_OK)
    {
      USB_OTG_BSP_mDelay(2);
      phost->device_prop.address = USBH_DEVICE_ADDRESS;

      /* user callback for device address assigned */
      phost->usr_cb->DeviceAddressAssigned();
      phost->EnumState = ENUM_GET_CFG_DESC;

      /* modify control channels to update device address */
      USBH_Modify_Channel (pdev,
                           phost->Control.hc_num_in,
                           phost->device_prop.address,
                           0,
                           0,
                           0);

      USBH_Modify_Channel (pdev,
                           phost->Control.hc_num_out,
                           phost->device_prop.address,
                           0,
                           0,
                           0);
    }
    break;

  case ENUM_GET_CFG_DESC:
    /* get standard configuration descriptor */
    if ( USBH_Get_CfgDesc(pdev,
                          phost,
                          USB_CONFIGURATION_DESC_SIZE) == USBH_OK)
    {
      phost->EnumState = ENUM_GET_FULL_CFG_DESC;
    }
    break;

  case ENUM_GET_FULL_CFG_DESC:
    /* get FULL config descriptor (config, interface, endpoints) */
    if (USBH_Get_CfgDesc(pdev,
                         phost,
                         phost->device_prop.Cfg_Desc.wTotalLength) == USBH_OK)
    {
      /* User callback for configuration descriptors available */
      phost->usr_cb->ConfigurationDescAvailable(&phost->device_prop.Cfg_Desc,
                                                      phost->device_prop.Itf_Desc,
                                                      phost->device_prop.Ep_Desc[0]);

      phost->EnumState = ENUM_GET_MFC_STRING_DESC;
    }
    break;

  case ENUM_GET_MFC_STRING_DESC:
    if (phost->device_prop.Dev_Desc.iManufacturer != 0)
    { /* Check that Manufacturer String is available */

      if ( USBH_Get_StringDesc(pdev,
                               phost,
                               phost->device_prop.Dev_Desc.iManufacturer,
                               Local_Buffer ,
                               0xff) == USBH_OK)
      {
        /* User callback for Manufacturing string */
        phost->usr_cb->ManufacturerString(Local_Buffer);
        phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
      }
    }
    else
    {
      phost->usr_cb->ManufacturerString("N/A");
      phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
    }
    break;

  case ENUM_GET_PRODUCT_STRING_DESC:
    if (phost->device_prop.Dev_Desc.iProduct != 0)
    { /* Check that Product string is available */
      if ( USBH_Get_StringDesc(pdev,
                               phost,
                               phost->device_prop.Dev_Desc.iProduct,
                               Local_Buffer,
                               0xff) == USBH_OK)
      {
        /* User callback for Product string */
        phost->usr_cb->ProductString(Local_Buffer);
        phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
      }
    }
    else
    {
      phost->usr_cb->ProductString("N/A");
      phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
    }
    break;

  case ENUM_GET_SERIALNUM_STRING_DESC:
    if (phost->device_prop.Dev_Desc.iSerialNumber != 0)
    { /* Check that Serial number string is available */
      if ( USBH_Get_StringDesc(pdev,
                               phost,
                               phost->device_prop.Dev_Desc.iSerialNumber,
                               Local_Buffer,
                               0xff) == USBH_OK)
      {
        /* User callback for Serial number string */
        phost->usr_cb->SerialNumString(Local_Buffer);
        phost->EnumState = ENUM_SET_CONFIGURATION;
      }
    }
    else
    {
      phost->usr_cb->SerialNumString("N/A");
      phost->EnumState = ENUM_SET_CONFIGURATION;
    }
    break;

  case ENUM_SET_CONFIGURATION:
    /* set configuration  (default config) */
    if (USBH_SetCfg(pdev,
                    phost,
                    phost->device_prop.Cfg_Desc.bConfigurationValue) == USBH_OK)
    {
      phost->EnumState = ENUM_DEV_CONFIGURED;
    }
    break;


  case ENUM_DEV_CONFIGURED:
    /* user callback for enumeration done */
    Status = USBH_OK;
    break;

  default:
    break;
  }
  return Status;
}
示例#2
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;
  }

}
示例#3
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;
	}

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

}
示例#5
0
/* USB main task. Performs enumeration/cleanup */
void USB::Task(USB_OTG_CORE_HANDLE *pdev) //USB state machine
{
	uint8_t rcode;
	uint8_t tmpdata;
	static unsigned long delay = 0;
	bool lowspeed = false;

	STM32F2::Task();

	tmpdata = getVbusState();

	/* modify USB task state if Vbus changed */
	switch (tmpdata) {
		case SE1: //illegal state
			usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL;
			lowspeed = false;
			break;
		case SE0: //disconnected
			if ((usb_task_state & USB_STATE_MASK) != USB_STATE_DETACHED)
					usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;
			lowspeed = false;
			break;
		case LSHOST:
//        if ((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) {
			lowspeed = true;
//        }
		case FSHOST: //attached
			if ((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) {
				delay = millis() + USB_SETTLE_DELAY;
				usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE;
				STM_EVAL_LEDToggle(LED1);
			}
			break;
	}// switch( tmpdata

	for (uint8_t i = 0; i < USB_NUMDEVICES; i++)
		if (devConfig[i])
			rcode = devConfig[i]->Poll();

	switch (usb_task_state) {
		case USB_DETACHED_SUBSTATE_INITIALIZE:
				init();

				for (uint8_t i = 0; i < USB_NUMDEVICES; i++)
					if (devConfig[i])
							rcode = devConfig[i]->Release();

				usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE;
				break;
		case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here
				break;
		case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here
				break;
		case USB_ATTACHED_SUBSTATE_SETTLE: //settle time for just attached device
			if (delay < millis())
				usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
			break;
		case USB_ATTACHED_SUBSTATE_RESET_DEVICE:
			STM_EVAL_LEDToggle(LED1);
			//regWr(rHCTL, bmBUSRST); //issue bus reset
			// what if i want to reset the specified device? (need to survey usb hub feature later)
			pdev->host.SofHits = 0;
			HCD_ResetPort();

			//usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE;
			// the HCD_ResetPort() function will take care of a complete bus reset. so skip next phase.
			usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF;
			break;
/*			case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE:
				if ((regRd(rHCTL) & bmBUSRST) == 0) {
						tmpdata = regRd(rMODE) | bmSOFKAENAB; //start SOF generation
						regWr(rMODE, tmpdata);
						usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF;
						//delay = millis() + 20; //20ms wait after reset per USB spec
				}
				break;*/

		case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order
			if(pdev->host.port_need_reset) {
				usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
				pdev->host.port_need_reset = 0;
				printf("\nLS Dev, reset again");
				break;
			}
			STM_EVAL_LEDToggle(LED1);

			//if (regRd(rHIRQ) & bmFRAMEIRQ) {
			if(pdev->host.SofHits) {
				//when first SOF received _and_ 20ms has passed we can continue
				usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET;
				delay = millis() + 20;
			}
			break;
		case USB_ATTACHED_SUBSTATE_WAIT_RESET:
			if (delay < millis()) {
				usb_task_state = USB_STATE_CONFIGURING;
			}
			break;
		case USB_STATE_CONFIGURING:
			STM_EVAL_LEDToggle(LED1);
					//Serial.print("\r\nConf.LS: ");
					//Serial.println(lowspeed, HEX);
			printf("\nTODO:Support all 8 USB pipe?");
			rcode = Configuring(0, 0, lowspeed);

			if (rcode) {
				if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) {
					usb_error = rcode;
					usb_task_state = USB_STATE_ERROR;
				}
			} else
				usb_task_state = USB_STATE_RUNNING;
			break;
		case USB_STATE_RUNNING:
			break;
		case USB_STATE_ERROR:
				//MAX3421E::Init();
	        AddressPool &addrPool = GetAddressPool();
	        // Get pointer to pseudo device with address 0 assigned
	        UsbDevice *p = addrPool.GetUsbDevicePtr(0);

			USBH_Free_Channel(pdev, p->epinfo->hcNumOut);
			USBH_Free_Channel(pdev, p->epinfo->hcNumIn);
			break;
	} // switch( usb_task_state )
}
示例#6
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;
  }

}