/*******************************************************************************
* Function Name  : USB_SIL_Read
* Description    : Write a buffer of data to a selected endpoint.
* Input          : - bEpAddr: The address of the non control endpoint.
*                  - pBufferPointer: The pointer to which will be saved the 
*                     received data buffer.
* Output         : None.
* Return         : Number of received data (in Bytes).
*******************************************************************************/
uint32_t USB_SIL_Read(uint8_t bEpAddr, uint8_t* pBufferPointer)
{
  uint32_t DataLength = 0;

#ifndef STM32F10X_CL

  /* Get the number of received data on the selected Endpoint */
  DataLength = GetEPRxCount(bEpAddr & 0x7F);
  
  /* Use the memory interface function to write to the selected endpoint */
  PMAToUserBufferCopy(pBufferPointer, GetEPRxAddr(bEpAddr & 0x7F), DataLength);

#else
  
  USB_OTG_EP *ep;

  /* Get the structure pointer of the selected Endpoint */
  ep = PCD_GetOutEP(bEpAddr);
  
  /* Get the number of received data */
  DataLength = ep->xfer_len;
  
  /* Use the PCD interface layer function to read the selected endpoint */
  PCD_EP_Read (bEpAddr, pBufferPointer, DataLength);
  
#endif /* STM32F10X_CL */

  /* Return the number of received data */
  return DataLength;
}
Esempio n. 2
0
/*******************************************************************************
* Function Name  : PCD_EP_Read
* Description    : Read data from Fifo
* Input          : Endpoint address.
* Output         : None
* Return         : status
*******************************************************************************/
uint32_t PCD_EP_Read (uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len)
{
  USB_OTG_EP *ep;
  uint32_t i = 0;

  ep = PCD_GetOutEP(ep_addr & 0x7F);

  /* copy received data into application buffer */
  for (i = 0 ; i < buf_len ; i++)
  {
    pbuf[i] = ep->xfer_buff[i];
  }

  /*setup and start the Xfer */
  ep->xfer_buff = pbuf;
  ep->xfer_len = buf_len;
  ep->xfer_count = 0;
  ep->is_in = 0;
  ep->num = ep_addr & 0x7F;

  if ( ep->num == 0 )
  {
    OTGD_FS_EP0StartXfer(ep);
  }
  else
  {
    OTGD_FS_EPStartXfer( ep );
  }

  return 0;
}
Esempio n. 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;
}
Esempio n. 4
0
/*******************************************************************************
* Function Name  : EP1_OUT_Callback
* Description    : Endpoint 1 out callback routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void EP1_OUT_Callback(void)
{
  DMA_InitTypeDef DMA_InitStructure;

#ifdef USE_STM3210C_EVAL
  /* Get the Endpoint descriptor pointer */
  ep = PCD_GetOutEP(ENDP1 & 0x7F);

  /* Enable the Endpoint transfer (since the the Read Endpoint function is 
     not called) */
  OTGD_FS_EPStartXfer(ep);
  
  /* Toggle the data PID */
  if (ep->even_odd_frame != 0)
  {
    ep->even_odd_frame = 0;
  }
  else
  {
    ep->even_odd_frame = 1;    
  }
  
  /* If Half of global buffer has been filled and DMA is still not enabled, 
     Re-configure the DMA and unMute the codec */
#if (NUM_SUB_BUFFERS == 2)
  if (((DMA1_Channel5->CCR & 0x1) == 0) && (IsocBufferIdx == 1))
#else
  if (((DMA1_Channel5->CCR & 0x1) == 0) && (IsocBufferIdx == ((NUM_SUB_BUFFERS / 2) - 1)))
#endif /* NUM_SUB_BUFFERS */    
  {       
    /* Disable the mute mode */
    CODEC_Mute(MUTE_OFF);    
    
    /* Disable the I2S before starting configuration to avoid spurious transfer */
    SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE);
    I2S_Cmd(SPI2, DISABLE);
    
    /* Initialize the DMA1 Channel5 to its default values */
    DMA_DeInit(DMA1_Channel5);
    
    /* Configure the DMA parameters */
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)((uint16_t*)IsocBuff);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPI2_DR_Address;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = (ISOC_BUFFER_SZE * NUM_SUB_BUFFERS) / 2; /* Divided by 2 because USB data are 8 bit and I2S buffer is 16 bit */
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;        
    DMA_Init(DMA1_Channel5, &DMA_InitStructure);
  }  
#endif /* USE_STM3210C_EVAL */
}
Esempio n. 5
0
/*******************************************************************************
* Function Name  : Setup0_Process
* Description    : Get the device request data and dispatch to individual process.
* Input          : None.
* Output         : None.
* Return         : Post0_Process.
*******************************************************************************/
uint8_t Setup0_Process(void)
{

  union
  {
    uint8_t* b;
    uint16_t* w;
  } pBuf;

#ifdef STM32F10X_CL
  USB_OTG_EP *ep;
  uint16_t offset = 0;
 
  ep = PCD_GetOutEP(ENDP0);
  pBuf.b = ep->xfer_buff;
  
  OTGD_FS_EP0StartXfer(ep);
#else  
  uint16_t offset = 1;
  
  pBuf.b = PMAAddr + (uint8_t *)(_GetEPRxAddr(ENDP0) * 2); /* *2 for 32 bits addr */
#endif /* STM32F10X_CL */

  if (pInformation->ControlState != PAUSE)
  {
    pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */
    pInformation->USBbRequest = *pBuf.b++; /* bRequest */
    pBuf.w += offset;  /* word not accessed because of 32 bits addressing */
    pInformation->USBwValue = ByteSwap(*pBuf.w++); /* wValue */
    pBuf.w += offset;  /* word not accessed because of 32 bits addressing */
    pInformation->USBwIndex  = ByteSwap(*pBuf.w++); /* wIndex */
    pBuf.w += offset;  /* word not accessed because of 32 bits addressing */
    pInformation->USBwLength = *pBuf.w; /* wLength */
  }

  pInformation->ControlState = SETTING_UP;
  if (pInformation->USBwLength == 0)
  {
    /* Setup with no data stage */
    NoData_Setup0();
  }
  else
  {
    /* Setup with data stage */
    Data_Setup0();
  }
  return Post0_Process();
}
Esempio n. 6
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);
}
Esempio n. 7
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;
}
Esempio n. 8
0
/*******************************************************************************
* Function Name  : OTGD_FS_Handle_RxStatusQueueLevel_ISR
* Description    : Handles the Rx Status Queue Level Interrupt.
* Input          : None
* Output         : None
* Return         : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_RxStatusQueueLevel_ISR(void)
{
  USB_OTG_GINTMSK_TypeDef int_mask;
  USB_OTG_GRXSTSP_TypeDef status;
  USB_OTG_EP *ep;

  int_mask.d32 = 0;
  status.d32 = 0;
  
  /* Disable the Rx Status Queue Level interrupt */
  int_mask.b.rxstsqlvl = 1;
  USB_OTG_MODIFY_REG32( &USB_OTG_FS_regs.GREGS->GINTMSK, int_mask.d32, 0);

  /* Get the Status from the top of the FIFO */
  status.d32 = USB_OTG_READ_REG32( &USB_OTG_FS_regs.GREGS->GRXSTSP );

  /* Get the related endpoint structure */
  ep = PCD_GetOutEP(status.b.epnum);

  switch (status.b.pktsts)
  {
    case STS_GOUT_NAK:
      break;
    case STS_DATA_UPDT:
      if (status.b.bcnt)
      {
        if (ep->type == EP_TYPE_ISOC)
        {
          /* Call user function */
          INTR_RXSTSQLVL_ISODU_Callback();         
          
          /* Copy the received buffer to the RAM */
          OTGD_FS_ReadPacket((uint8_t*)(IsocBuff + (ISOC_BUFFER_SZE * IsocBufferIdx)), status.b.bcnt);
          ep->xfer_buff = (uint8_t*)(IsocBuff + (ISOC_BUFFER_SZE * IsocBufferIdx));  
          
          /* Check if the end of the global buffer has been reached */
          if (IsocBufferIdx == (NUM_SUB_BUFFERS - 1))
          {
            /* Reset the buffer index */
            IsocBufferIdx = 0;                         
          }
          else
          {
            /* Increment the buffer index */
            IsocBufferIdx ++;
          }          
        }
        else
        {
          /* Copy the received buffer to the RAM */
          OTGD_FS_ReadPacket(USBD_Data_Buffer, status.b.bcnt);
          ep->xfer_buff = USBD_Data_Buffer;
        }
        
        /* Update the endpoint structure */
        ep->xfer_len  = status.b.bcnt;
        ep->xfer_count += status.b.bcnt;        
      }
      else
      {
        ep->xfer_len  = status.b.bcnt;
      }
      break;
    case STS_XFER_COMP:
      break;
    case STS_SETUP_COMP:
      break;
    case STS_SETUP_UPDT:
      /* Copy the setup packet received in Fifo into the setup buffer in RAM */
      OTGD_FS_ReadPacket(USBD_Data_Buffer, 8); 
      ep->xfer_buff = USBD_Data_Buffer;
      ep->xfer_count += status.b.bcnt;
      ep->xfer_len  = status.b.bcnt;
      break;
    default:
      break;
  }

  /* Call the user function */
  INTR_RXSTSQLVL_Callback();
  
  /* Enable the Rx Status Queue Level interrupt */
  USB_OTG_MODIFY_REG32( &USB_OTG_FS_regs.GREGS->GINTMSK, 0, int_mask.d32);
  
  /* Clear interrupt: this is a read only bit, it cannot be cleared by register 
     access */

  return 1;
}
Esempio n. 9
0
/*******************************************************************************
* Function Name  : OTGD_FS_Handle_OutEP_ISR
* Description    : Handles all OUT endpoints interrupts.
* Input          : None
* Output         : None
* Return         : Status
*******************************************************************************/
uint32_t OTGD_FS_Handle_OutEP_ISR(void)
{
  uint32_t ep_intr = 0;
  USB_OTG_DOEPINTx_TypeDef doepint;
  uint32_t epnum = 0;
  USB_OTG_EP *ep;
  
  doepint.d32 = 0;

  /* Read in the device interrupt bits */
  ep_intr = OTGD_FS_ReadDevAllOutEp_itr();
  
  while ( ep_intr )
  {
    if (ep_intr&0x1)
    {
      /* Get EP pointer */
      ep = PCD_GetOutEP(epnum);
      doepint.d32 = OTGD_FS_ReadDevOutEP_itr(ep);

      /* Transfer complete */
      if ( doepint.b.xfercompl )
      {
        /* Clear the bit in DOEPINTn for this interrupt */
        CLEAR_OUT_EP_INTR(epnum, xfercompl);
        
        if (epnum == 0)  
        { 
          /* Call the OUT process for the EP0 */
          Out0_Process();
        }
        else
        {
          (*pEpInt_OUT[epnum-1])();
        }
      }
      /* Endpoint disable  */
      if ( doepint.b.epdis)
      {
        /* Clear the bit in DOEPINTn for this interrupt */
        CLEAR_OUT_EP_INTR(epnum, epdis);
      }
      /* Setup Phase Done (control EPs) */
      if ( doepint.b.setup )
      {
        if (epnum == 0)  
        {        
          /* Call the SETUP process for the EP0 */
          Setup0_Process();  

          /* Before exit, update the Tx status */
          OTG_DEV_SetEPTxStatus(0x80, SaveTState); 
        }
        else
        {
          /* Other control endpoints */
        }  
        
        /* Clear the EP Interrupt */
        CLEAR_OUT_EP_INTR(epnum, setup);
      }
      /* Back to back setup received */
      if ( doepint.b.b2bsetup )
      {
        if (epnum == 0)  
        {        
          /* Call the SETUP process for the EP0 */
          Setup0_Process();  

          /* Before exit, update the Tx status */
          OTG_DEV_SetEPTxStatus(0x80, SaveTState);  
        }
      }
    }
    epnum++;
    ep_intr >>= 1;
  }

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