Пример #1
0
/*******************************************************************************
* Function Name  : Post0_Process
* Description    : Stall the Endpoint 0 in case of error.
* Input          : None.
* Output         : None.
* Return         : - 0 if the control State is in PAUSE
*                  - 1 if not.
*******************************************************************************/
uint8_t Post0_Process(void) {
#ifdef STM32F10X_CL
    USB_OTG_EP* ep;
#endif /* STM32F10X_CL */

    SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);

    if(pInformation->ControlState == STALLED) {
        vSetEPRxStatus(EP_RX_STALL);
        vSetEPTxStatus(EP_TX_STALL);
    }

#ifdef STM32F10X_CL
    else if((pInformation->ControlState == OUT_DATA) || (pInformation->ControlState == WAIT_STATUS_OUT)) {
        ep = PCD_GetInEP(0);
        ep->is_in = 0;
        OTGD_FS_EP0StartXfer(ep);

        vSetEPTxStatus(EP_TX_VALID);
    }

    else if((pInformation->ControlState == IN_DATA) || (pInformation->ControlState == WAIT_STATUS_IN)) {
        ep = PCD_GetInEP(0);
        ep->is_in = 1;
        OTGD_FS_EP0StartXfer(ep);
    }
#endif /* STM32F10X_CL */

    return (pInformation->ControlState == PAUSE);
}
Пример #2
0
/*******************************************************************************
* Function Name  : USBF_EP_Write
* Description    : Read data from Fifo
* Input          : ep
* Output         : None
* Return         : status
*******************************************************************************/
uint32_t  PCD_EP_Write (uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len)
{
  USB_OTG_EP *ep;

  ep = PCD_GetInEP(ep_addr & 0x7f);

  /* assign data to EP structure buffer */
  ep->xfer_buff = pbuf;

  /* Setup and start the Transfer */
  ep->xfer_count = 0;
  ep->xfer_len = buf_len;
  ep->is_in = 1;
  ep->num = ep_addr & 0x7F;
  
  if ( ep->num == 0 )
  {
    OTGD_FS_EP0StartXfer(ep);
  }
  else
  {
    OTGD_FS_EPStartXfer( ep );
  }

  return 0;
}
Пример #3
0
/*******************************************************************************
* Function Name  : PCD_EP_Open
* Description    : Configure an Endpoint
* Input          : None
* Output         : None
* Return         : status
*******************************************************************************/
uint32_t PCD_EP_Open(EP_DESCRIPTOR *epdesc)
{
  USB_OTG_EP *ep;


  if ((0x80 & epdesc->bEndpointAddress) != 0)
  {
    ep = PCD_GetInEP(epdesc->bEndpointAddress & 0x7F);
    ep->is_in = 1;
  }
  else
  {
    ep = PCD_GetOutEP(epdesc->bEndpointAddress & 0x7F);
    ep->is_in = 0;
  }

  ep->num   = epdesc->bEndpointAddress & 0x7F;
  ep->maxpacket = epdesc->wMaxPacketSize;
  ep->type = epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;

  if (ep->is_in)
  {
    /* Assign a Tx FIFO */
    ep->tx_fifo_num = ep->num;
  }

  OTGD_FS_EPActivate(ep );

  return 0;
}
Пример #4
0
/*******************************************************************************
* Function Name  : PCD_WriteEmptyTxFifo
* Description    : Checks Fifo for the next packet to be loaded.
* Input          : None
* Output         : None
* Return         : Status
*******************************************************************************/
static uint32_t PCD_WriteEmptyTxFifo(uint32_t epnum)
{
  USB_OTG_DTXFSTS_TypeDef txstatus;
  USB_OTG_EP *ep;
  uint32_t len = 0;
  uint32_t dwords = 0;
  uint32_t fifoemptymsk = 0;
  
  txstatus.d32 = 0;
  
  ep = PCD_GetInEP(epnum); 
  
  len = ep->xfer_len - ep->xfer_count;

  if (len > ep->maxpacket)
  {
    len = ep->maxpacket;
  }
  
  dwords = (len + 3) / 4;
  txstatus.d32 = USB_OTG_READ_REG32( &USB_OTG_FS_regs.DINEPS[epnum]->DTXFSTSx);

  
  while  ((txstatus.b.txfspcavail > dwords) &&
          (ep->xfer_count < ep->xfer_len) &&
          (ep->xfer_len) != 0)
  {
    len = ep->xfer_len - ep->xfer_count;

    if (len > ep->maxpacket)
    {
      len = ep->maxpacket;
    }
    dwords = (len + 3) / 4;

    OTGD_FS_WritePacket(ep->xfer_buff, epnum, len);    
    
    ep->xfer_count += len;
    ep->xfer_buff += len; 

    txstatus.d32 = USB_OTG_READ_REG32(&USB_OTG_FS_regs.DINEPS[epnum]->DTXFSTSx); 
    
    /* Mask the TxFIFOEmpty interrupt to prevent re-entring this routine */
    if (ep->xfer_len == ep->xfer_count)
    {
      fifoemptymsk = 0x1 << ep->num;
      USB_OTG_MODIFY_REG32(&USB_OTG_FS_regs.DEV->DIEPEMPMSK, fifoemptymsk, 0);    
    }
  }
  
  return 1;
}
Пример #5
0
/*******************************************************************************
* Function Name  : PCD_EP_Stall
* Description    : Stall an endpoint.
* Input          : Endpoint Address.
* Output         : None
* Return         : status
*******************************************************************************/
uint32_t  PCD_EP_Stall (uint8_t ep_addr)
{
  USB_OTG_EP *ep;

  if ((0x80 & ep_addr) != 0)
  {
    ep = PCD_GetInEP(ep_addr & 0x7F);
  }
  else
  {
    ep = PCD_GetOutEP(ep_addr & 0x7F);
  }

  ep->num   = ep_addr & 0x7F;
  ep->is_in = ((ep_addr & 0x80) == 0x80) ? 1 : 0;

  OTGD_FS_EPSetStall(ep);
  return (0);
}
Пример #6
0
/*******************************************************************************
* Function Name  : PCD_EP_Close
* Description    : Called when an EP is disabled
* Input          : Endpoint address.
* Output         : None
* Return         : status
*******************************************************************************/
uint32_t PCD_EP_Close(uint8_t  ep_addr)
{

  USB_OTG_EP *ep;

  if ((0x80 & ep_addr) != 0)
  {
    ep = PCD_GetInEP(ep_addr & 0x7F);
  }
  else
  {
    ep = PCD_GetOutEP(ep_addr & 0x7F);
  }

  ep->num   = ep_addr & 0x7F;
  ep->is_in = (0x80 & ep_addr) != 0;

  OTGD_FS_EPDeactivate(ep );
  return 0;
}
Пример #7
0
/*******************************************************************************
* Function Name  : OTGD_FS_Handle_InEP_ISR
* Description    : Handles all IN endpoints interrupts.
* Output         : None
* Return         : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_InEP_ISR(void)
{
  USB_OTG_DIEPINTx_TypeDef diepint;

  uint32_t ep_intr = 0;
  uint32_t epnum = 0;
  USB_OTG_EP *ep;
  uint32_t fifoemptymsk = 0;

  diepint.d32 = 0;  
  ep_intr = OTGD_FS_ReadDevAllInEPItr();
  while ( ep_intr )
  {
    if (ep_intr&0x1) /* In ITR */
    {
      ep = PCD_GetInEP(epnum);
      diepint.d32 = PCD_ReadDevInEP(ep); /* Get In ITR status */
      if ( diepint.b.xfercompl )
      {
        fifoemptymsk = 0x1 << ep->num;
        USB_OTG_MODIFY_REG32(&USB_OTG_FS_regs.DEV->DIEPEMPMSK, fifoemptymsk, 0);

        /* Clear the Interrupt flag */ 
        CLEAR_IN_EP_INTR(epnum, xfercompl);
        
        if (epnum == 0)  
        {        
          /* Call the core IN process for EP0 */ 
          In0_Process();
          
          /* before terminate set Tx & Rx status */
          OTG_DEV_SetEPRxStatus(epnum, SaveRState);
          OTG_DEV_SetEPTxStatus(epnum, SaveTState);
        }
        else
        {
          /* Call the relative IN endpoint callback */
          (*pEpInt_IN[epnum -1])();
        } 
      }
      if ( diepint.b.timeout )
      {
        CLEAR_IN_EP_INTR(epnum, timeout);
      }
      if (diepint.b.intktxfemp)
      {
        CLEAR_IN_EP_INTR(epnum, intktxfemp);
      }
      if (diepint.b.inepnakeff)
      {
        CLEAR_IN_EP_INTR(epnum, inepnakeff);
      }
      if (diepint.b.txfempty)
      {      
         if ((epnum == 0) || (OTG_DEV_GetEPTxStatus(epnum) == DEV_EP_TX_VALID))
        {
          PCD_WriteEmptyTxFifo(epnum);          
        }

        CLEAR_IN_EP_INTR(epnum, txfempty);          
      }
      if ( diepint.b.epdis)
      { 
        /* Reset Endpoint Frame ID to 0 */
        ep->even_odd_frame = 0;

        CLEAR_IN_EP_INTR(epnum, epdis);
      }      
    }
    epnum++;
    ep_intr >>= 1;
  }

  /* Call user function */
  INTR_INEPINTR_Callback();
  
  return 1;
}