예제 #1
0
파일: usb_hcd.c 프로젝트: 1heinz/TauLabs
/**
  * @brief  HCD_ResetPort
  *         Issues the reset command to device
  * @param  pdev : Selected device
  * @retval Status
  */
uint32_t HCD_ResetPort(USB_OTG_CORE_HANDLE *pdev)
{
  /*
  Before starting to drive a USB reset, the application waits for the OTG 
  interrupt triggered by the debounce done bit (DBCDNE bit in OTG_FS_GOTGINT), 
  which indicates that the bus is stable again after the electrical debounce 
  caused by the attachment of a pull-up resistor on DP (FS) or DM (LS).
  */
  
  USB_OTG_ResetPort(pdev); 
  return 0;
}
예제 #2
0
/**
 * This function will control the roothub of susb host controller.
 *
 * @param port the port to be reset.
 * 
 * @return the error code, RT_EOK on successfully.
 */
static rt_err_t susb_hub_control(rt_uint16_t port, rt_uint8_t cmd, void* args)
{
    RT_ASSERT(port == 1);
    
    switch(cmd)
    {
    case RH_GET_PORT_STATUS:
        *(rt_uint32_t*)args = root_hub.port_status[port - 1];
        break;
    case RH_SET_PORT_STATUS:
        break;
    case RH_CLEAR_PORT_FEATURE:
        switch((rt_uint32_t)args & 0xFF)
        {
        case PORT_FEAT_C_RESET:
            root_hub.port_status[port - 1] &= ~PORT_PRSC;    
            ignore_disconnect = RT_FALSE;            
            break;
        case PORT_FEAT_C_CONNECTION:
            root_hub.port_status[port - 1] &= ~PORT_CCSC;            
            break;
        case PORT_FEAT_C_ENABLE:
            root_hub.port_status[port - 1] &= ~PORT_PESC;            
            break;
        default:
            break;
        }
        break;
    case RH_SET_PORT_FEATURE:
        switch((rt_uint32_t)args & 0xFF)
        {        
        case PORT_FEAT_POWER:
            root_hub.port_status[port - 1] |= PORT_PPS;
            break;
        case PORT_FEAT_RESET:            
            ignore_disconnect = RT_TRUE;            
            root_hub.port_status[port - 1] |= PORT_PRS;    
            USB_OTG_ResetPort(&USB_OTG_Core);             
            root_hub.port_status[port - 1] &= ~PORT_PRS;  
            break;
        case PORT_FEAT_ENABLE:
            root_hub.port_status[port - 1] |= PORT_PES;            
            break;
        }    
        break;
    default:
        break;
    }    

    return RT_EOK;
}
예제 #3
0
/**
  * @brief  USB_OTG_HandleOTG_ISR
  *         handles the OTG Interrupts
  * @param  None
  * @retval : status
  */
static uint32_t USB_OTG_HandleOTG_ISR(USB_OTG_CORE_HANDLE *pdev)
{
  USB_OTG_GOTGINT_TypeDef  gotgint;
  USB_OTG_GOTGCTL_TypeDef  gotgctl;


  gotgint.d32 = 0;
  gotgctl.d32 = 0;

  gotgint.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGINT);
  gotgctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGCTL);

  if (gotgint.b.sesenddet)
  {
    gotgctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGCTL);


    if (USB_OTG_IsDeviceMode(pdev))
    {

    }
    else if (USB_OTG_IsHostMode(pdev))
    {

    }
  }

  /* ----> SRP SUCCESS or FAILURE INTERRUPT <---- */
  if (gotgint.b.sesreqsucstschng)
  {
    gotgctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGCTL);
    if (gotgctl.b.sesreqscs) /* Session request success                                          */
    {
      if (USB_OTG_IsDeviceMode(pdev))
      {

      }
      /* Clear Session Request */
      gotgctl.d32 = 0;
      gotgctl.b.sesreq = 1;
      USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GOTGCTL, gotgctl.d32, 0);
    }
    else /* Session request failure                                          */
    {
      if (USB_OTG_IsDeviceMode(pdev))
      {

      }
    }
  }
  /* ----> HNP SUCCESS or FAILURE INTERRUPT <---- */
  if (gotgint.b.hstnegsucstschng)
  {
    gotgctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGCTL);

    if (gotgctl.b.hstnegscs)                                    /* Host negotiation success                                         */
    {
      if (USB_OTG_IsHostMode(pdev))                              /* The core AUTOMATICALLY sets the Host mode                        */
      {

      }
    }
    else                                                        /* Host negotiation failure */
    {

    }
    gotgint.b.hstnegsucstschng = 1;                             /* Ack "Host Negotiation Success Status Change" interrupt.          */
  }
  /* ----> HOST NEGOTIATION DETECTED INTERRUPT <---- */
  if (gotgint.b.hstnegdet)
  {
    if (USB_OTG_IsDeviceMode(pdev))                              /* The core AUTOMATICALLY sets the Host mode                        */
    {

    }
    else
    {

    }
  }
  if (gotgint.b.adevtoutchng)
  {}
  if (gotgint.b.debdone)
  {
    USB_OTG_ResetPort(pdev);
  }
  /* Clear OTG INT */
  USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGINT, gotgint.d32);
  return 1;
}
예제 #4
0
/**
 * @brief  USB_OTG_USBH_handle_port_ISR
 *         This function determines which interrupt conditions have occurred
 * @param  pdev: Selected device
 * @retval status
 */
static uint32_t USB_OTG_USBH_handle_port_ISR(USB_OTG_CORE_HANDLE *pdev)
{
	USB_OTG_HPRT0_TypeDef hprt0;
	USB_OTG_HPRT0_TypeDef hprt0_dup;
	USB_OTG_HCFG_TypeDef hcfg;
	uint32_t do_reset = 0;
	uint32_t retval = 0;

	hcfg.d32 = 0;
	hprt0.d32 = 0;
	hprt0_dup.d32 = 0;

	hprt0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);
	hprt0_dup.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);

	/* Clear the interrupt bits in GINTSTS */

	hprt0_dup.b.prtena = 0;
	hprt0_dup.b.prtconndet = 0;
	hprt0_dup.b.prtenchng = 0;
	hprt0_dup.b.prtovrcurrchng = 0;

	/* Port Connect Detected */
	if (hprt0.b.prtconndet)
	{
		//    pdev->host.port_cb->Connect(pdev);
		hprt0_dup.b.prtconndet = 1;
		do_reset = 1;
		retval |= 1;
	}

	/* Port Enable Changed */
	if (hprt0.b.prtenchng)
	{
		hprt0_dup.b.prtenchng = 1;
		if (hprt0.b.prtena == 1)
		{
			pdev->host.ConnSts = 1;

			if ((hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED) || (hprt0.b.prtspd ==
	HPRT0_PRTSPD_FULL_SPEED))
			{

				hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG);

				if (hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED)
				{
					USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 6000);
					if (hcfg.b.fslspclksel != HCFG_6_MHZ)
					{
						if (pdev->cfg.coreID == USB_OTG_FS_CORE_ID)
						{
							USB_OTG_InitFSLSPClkSel(pdev, HCFG_6_MHZ);
						}
						do_reset = 1;
					}
				}
				else
				{

					USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 48000);
					if (hcfg.b.fslspclksel != HCFG_48_MHZ)
					{
						USB_OTG_InitFSLSPClkSel(pdev, HCFG_48_MHZ);
						do_reset = 1;
					}
				}
			}
			else
			{
				do_reset = 1;
			}
		}
	}
	/* Overcurrent Change Interrupt */
	if (hprt0.b.prtovrcurrchng)
	{
		hprt0_dup.b.prtovrcurrchng = 1;
		retval |= 1;
	}
	if (do_reset)
	{
		USB_OTG_ResetPort(pdev);

	}
	/* Clear Port Interrupts */
	USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0_dup.d32);

	return retval;
}
//--------------------------------------------------------------
USB_OTG_STS USB_OTG_CoreInitHost(USB_OTG_CORE_HANDLE *pdev)
{
  USB_OTG_STS                     status = USB_OTG_OK;
  USB_OTG_FSIZ_TypeDef            nptxfifosize;
  USB_OTG_FSIZ_TypeDef            ptxfifosize;  
  USB_OTG_HCFG_TypeDef            hcfg;
  
  uint32_t                        i = 0;
  
  nptxfifosize.d32 = 0;  
  ptxfifosize.d32 = 0;
  hcfg.d32 = 0;
  
  
  /* configure charge pump IO */
  USB_OTG_BSP_ConfigVBUS(pdev);
  
  /* Restart the Phy Clock */
  USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, 0);
  
  /* Initialize Host Configuration Register */
  if (pdev->cfg.phy_itface == USB_OTG_ULPI_PHY)
  {
    USB_OTG_InitFSLSPClkSel(pdev , HCFG_30_60_MHZ); 
  }
  else
  {
    USB_OTG_InitFSLSPClkSel(pdev , HCFG_48_MHZ); 
  }
  USB_OTG_ResetPort(pdev);
  
  hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG);
  hcfg.b.fslssupp = 0;
  USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HCFG, hcfg.d32);
  
  /* Configure data FIFO sizes */
  /* Rx FIFO */
 
  if (pdev->cfg.coreID == USB_OTG_HS_CORE_ID)
  {
    /* set Rx FIFO size */
    USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_HS_SIZE);
    nptxfifosize.b.startaddr = RX_FIFO_HS_SIZE;   
    nptxfifosize.b.depth = TXH_NP_HS_FIFOSIZ;  
    USB_OTG_WRITE_REG32(&pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32);
    
    ptxfifosize.b.startaddr = RX_FIFO_HS_SIZE + TXH_NP_HS_FIFOSIZ;
    ptxfifosize.b.depth     = TXH_P_HS_FIFOSIZ;
    USB_OTG_WRITE_REG32(&pdev->regs.GREGS->HPTXFSIZ, ptxfifosize.d32);      
  }  
  
  /* Make sure the FIFOs are flushed. */
  USB_OTG_FlushTxFifo(pdev, 0x10 );         /* all Tx FIFOs */
  USB_OTG_FlushRxFifo(pdev);
  
  
  /* Clear all pending HC Interrupts */
  for (i = 0; i < pdev->cfg.host_channels; i++)
  {
    USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCINT, 0xFFFFFFFF );
    USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCINTMSK, 0 );
  }

  USB_OTG_DriveVbus(pdev, 1);

  
  USB_OTG_EnableHostInt(pdev);
  return status;
}
예제 #6
0
// This function determines which interrupt conditions have occurred
static void USB_OTG_USBH_handle_port_ISR (USB_OTG_CORE_HANDLE *pdev)
{
  USB_OTG_HPRT0_TypeDef  hprt0;
  USB_OTG_HPRT0_TypeDef  hprt0_dup;
  USB_OTG_HCFG_TypeDef   hcfg;    
  uint32_t do_reset = 0;
  
  hcfg.d32 = 0;
  hprt0.d32 = 0;
  hprt0_dup.d32 = 0;
  
  hprt0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);
  hprt0_dup.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);
  
  /* Clear the interrupt bits in GINTSTS */
  
  hprt0_dup.b.prtena = 0;
  hprt0_dup.b.prtconndet = 0;
  hprt0_dup.b.prtenchng = 0;
  hprt0_dup.b.prtovrcurrchng = 0;
  
  /* Port Connect Detected */
  if (hprt0.b.prtconndet)
  {

    hprt0_dup.b.prtconndet = 1;
    USBH_HCD_INT_fops->DevConnected(pdev);
  }
  
  /* Port Enable Changed */
  if (hprt0.b.prtenchng)
  {
    hprt0_dup.b.prtenchng = 1;
    
    if (hprt0.b.prtena == 1)
    {
      
      USBH_HCD_INT_fops->DevConnected(pdev);
      
      if ((hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED) ||
          (hprt0.b.prtspd == HPRT0_PRTSPD_FULL_SPEED))
      {
        
        hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG);
        
        if (hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED)
        {
          USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 6000 );
          if (hcfg.b.fslspclksel != HCFG_6_MHZ)
          {
            if(pdev->cfg.phy_itface  == USB_OTG_EMBEDDED_PHY)
            {
              USB_OTG_InitFSLSPClkSel(pdev ,HCFG_6_MHZ );
            }
            do_reset = 1;
          }
        }
        else
        {
          
          USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 48000 );            
          if (hcfg.b.fslspclksel != HCFG_48_MHZ)
          {
            USB_OTG_InitFSLSPClkSel(pdev ,HCFG_48_MHZ );
            do_reset = 1;
          }
        }
      }
      else
      {
        do_reset = 1;
      }
    }
  }
  /* Overcurrent Change Interrupt */
  if (hprt0.b.prtovrcurrchng)
  {
    hprt0_dup.b.prtovrcurrchng = 1;
  }

  if (do_reset)
  {
    USB_OTG_ResetPort(pdev);
  }
  /* Clear Port Interrupts */
  USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0_dup.d32);

}