2011-09-19 02:45 AM
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; }