cancel
Showing results for 
Search instead for 
Did you mean: 

stm32 usb library

yujiu
Associate
Posted on September 19, 2011 at 11:45

  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;

}

0 REPLIES 0