AnsweredAssumed Answered

stm32 usb library

Question asked by yujiu.ha on Sep 19, 2011
  function as following,  if xfer_len> hnptxsts.b.nptxfspcavail, then fifo space isn't enough

/**
* @brief  USB_OTG_HC_StartXfer : Start transfer
* @param  pdev : Selected device
* @param  hc_num : channel number
* @retval USB_OTG_STS : status
*/
USB_OTG_STS USB_OTG_HC_StartXfer(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
{
  USB_OTG_STS status = USB_OTG_OK;
  USB_OTG_HCCHAR_TypeDef   hcchar;
  USB_OTG_HCTSIZn_TypeDef  hctsiz;
  USB_OTG_GNPTXSTS_TypeDef hnptxsts;
  USB_OTG_HPTXSTS_TypeDef  hptxsts;
  USB_OTG_GINTMSK_TypeDef  intmsk;
  uint16_t                 len_words = 0;  
 
  uint16_t num_packets;
  uint16_t max_hc_pkt_count;
 
  max_hc_pkt_count = 256;
  hctsiz.d32 = 0;
  hcchar.d32 = 0;
  intmsk.d32 = 0;
 
  /* Compute the expected number of packets associated to the transfer */
  if (pdev->host.hc[hc_num].xfer_len > 0)
  {
    num_packets = (pdev->host.hc[hc_num].xfer_len + \
      pdev->host.hc[hc_num].max_packet - 1) / pdev->host.hc[hc_num].max_packet;
   
    if (num_packets > max_hc_pkt_count)
    {
      num_packets = max_hc_pkt_count;
      pdev->host.hc[hc_num].xfer_len = num_packets * \
        pdev->host.hc[hc_num].max_packet;
    }
  }
  else
  {
    num_packets = 1;
  }
  if (pdev->host.hc[hc_num].ep_is_in)
  {
    pdev->host.hc[hc_num].xfer_len = num_packets * \
      pdev->host.hc[hc_num].max_packet;
  }
  /* Initialize the HCTSIZn register */
  hctsiz.b.xfersize = pdev->host.hc[hc_num].xfer_len;
  hctsiz.b.pktcnt = num_packets;
  hctsiz.b.pid = pdev->host.hc[hc_num].data_pid;
  USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCTSIZ, hctsiz.d32);
 
 
  hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR);
  hcchar.b.oddfrm = USB_OTG_IsEvenFrame(pdev);
 
  /* Set host channel enable */
  hcchar.b.chen = 1;
  hcchar.b.chdis = 0;
  USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32);
 
  if (!pdev->host.hc[hc_num].ep_is_in && pdev->host.hc[hc_num].xfer_len > 0)
  {
    switch(pdev->host.hc[hc_num].ep_type)
    {
      /* Non periodic transfer */
    case EP_TYPE_CTRL:
    case EP_TYPE_BULK:
      hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GNPTXSTS);
      len_words = (pdev->host.hc[hc_num].max_packet + 3) / 4;
     
      /* check if at least 1 MPS FIFO space available */
      if(len_words > hnptxsts.b.nptxfspcavail)
      {
        /* need to process data in nptxfempty interrupt */
        intmsk.b.nptxfempty = 1;
        USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, intmsk.d32); 
      }
      else
      {
        /*write packet into the Tx FIFO. */
        USB_OTG_WritePacket(pdev,
                            pdev->host.hc[hc_num].xfer_buff ,
                            hc_num, pdev->host.hc[hc_num].xfer_len);
   //if xfer_len> hnptxsts.b.nptxfspcavail, then fifo space isn't enough
      }
     
      break;
      /* Periodic transfer */
    case EP_TYPE_INTR:
    case EP_TYPE_ISOC:
      hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS);
      len_words = (pdev->host.hc[hc_num].max_packet + 3) / 4;
      /* check if at least 1 MPS FIFO space available */
      if(len_words > hptxsts.b.ptxfspcavail)
      {
        /* need to process data in ptxfempty interrupt */
        intmsk.b.ptxfempty = 1;
        USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, intmsk.d32); 
      }
      else
      {
       
        /* Write packet into the Tx FIFO. */
        USB_OTG_WritePacket(pdev,
                            pdev->host.hc[hc_num].xfer_buff ,
                            hc_num, pdev->host.hc[hc_num].xfer_len);
      }
      break;
     
    default:
      break;
    }
   
  }
  return status;
}


Outcomes