Interrupt тут не причем я жду прерывания по готовности данных в приемном FIFO, вот часть рекомендуемой последовательности в RM0090(стр. 1205):
3. In Slave mode, wait for the RXFLVL interrupt (in OTG_HS_GINTSTS) and empty the
data packets from the receive FIFO
– This step can be repeated many times, depending on the transfer size.
4. The assertion of the XFRC interrupt (in OTG_HS_DOEPINTx) marks the completion of
the isochronous OUT data transfer. This interrupt does not necessarily mean that the
data in memory are good.
Таймер запустить и синхронизировать с SOF не проблема, но зачем, надо будет к тому же ждать пока весь кадр ляжет в FIFO, да и ведь уже есть прерывания SOF/EOPF, можно забирать данные по тому же принципу по SOF, или в крайнем случае по EOPF, хотя последнее противоречит доке. Да и это не работает, такое впечатление что что то не так с самим Iso OUT EP в HS или проблема с организацией самой изохронной передачи в HS core, но это только впечатление. Возможно также я не правильно читаю FIFO, но тут тоже не до конца понятно, в FS где тот же проект(естественно сконфигурированный под FS) работает правильно

, и когда приходит прерывание XFRC данные уже лежат в буфере который я указал при инициализации EP(эти функции собственно часть библиотеки STM):
CODE
uint8_t usbd_audio_Init (void *pdev, uint8_t cfgidx)
{
/* Open EP OUT */
DCD_EP_Open((USB_OTG_CORE_HANDLE*)&USB_OTG_dev, AUDIO_OUT_EP, AUDIO_OUT_PACKET, USB_OTG_EP_ISOC);
/* Initialize the Audio output Hardware layer */
if (AUDIO_OUT_fops.Init(AUDIO_FREQUENCY, DEFAULT_VOLUME, 0) != USBD_OK)
{
return USBD_FAIL;
}
/* Prepare Out endpoint to receive audio data */
DCD_EP_PrepareRx((USB_OTG_CORE_HANDLE*)&USB_OTG_dev, AUDIO_OUT_EP, (uint8_t*)IsocOutWrPtr, AUDIO_OUT_PACKET);
return USBD_OK;
}
uint32_t DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev ,
uint8_t ep_addr,
uint16_t ep_mps,
uint8_t ep_type)
{
USB_OTG_EP *ep;
if ((ep_addr & 0x80) == 0x80)
{
ep = &pdev->dev.in_ep[ep_addr & 0x7F];
}
else
{
ep = &pdev->dev.out_ep[ep_addr & 0x7F];
}
ep->num = ep_addr & 0x7F;
ep->is_in = (0x80 & ep_addr) != 0;
ep->maxpacket = ep_mps;
ep->type = ep_type;
if (ep->is_in)
{
/* Assign a Tx FIFO */
ep->tx_fifo_num = ep->num;
}
/* Set initial data PID. */
if (ep_type == USB_OTG_EP_BULK )
{
ep->data_pid_start = 0;
}
USB_OTG_EPActivate(pdev , ep );
return 0;
}
uint32_t DCD_EP_PrepareRx( USB_OTG_CORE_HANDLE *pdev,
uint8_t ep_addr,
uint8_t *pbuf,
uint16_t buf_len)
{
USB_OTG_EP *ep;
ep = &pdev->dev.out_ep[ep_addr & 0x7F];
/*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 (pdev->cfg.dma_enable == 1)
{
ep->dma_addr = (uint32_t)pbuf;
}
if ( ep->num == 0 )
{
USB_OTG_EP0StartXfer(pdev , ep);
}
else
{
USB_OTG_EPStartXfer(pdev, ep );
}
return 0;
}
USB_OTG_STS USB_OTG_EPActivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
{
USB_OTG_STS status = USB_OTG_OK;
USB_OTG_DEPCTL_TypeDef depctl;
USB_OTG_DAINT_TypeDef daintmsk;
__IO uint32_t *addr;
depctl.d32 = 0;
daintmsk.d32 = 0;
/* Read DEPCTLn register */
if (ep->is_in == 1)
{
addr = &pdev->regs.INEP_REGS[ep->num]->DIEPCTL;
daintmsk.ep.in = 1 << ep->num;
}
else
{
addr = &pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL;
daintmsk.ep.out = 1 << ep->num;
}
/* If the EP is already active don't change the EP Control
* register. */
depctl.d32 = USB_OTG_READ_REG32(addr);
if (!depctl.b.usbactep)
{
depctl.b.mps = ep->maxpacket;
depctl.b.eptype = ep->type;
depctl.b.txfnum = ep->tx_fifo_num;
depctl.b.setd0pid = 1;
depctl.b.usbactep = 1;
USB_OTG_WRITE_REG32(addr, depctl.d32);
}
/* Enable the Interrupt for this EP */
#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
if((ep->num == 1)&&(pdev->cfg.coreID == USB_OTG_HS_CORE_ID))
{
USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DEACHMSK, 0, daintmsk.d32);
}
else
#endif
USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DAINTMSK, 0, daintmsk.d32);
return status;
}
USB_OTG_STS USB_OTG_EPStartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
{
USB_OTG_STS status = USB_OTG_OK;
USB_OTG_DEPCTL_TypeDef depctl;
USB_OTG_DEPXFRSIZ_TypeDef deptsiz;
USB_OTG_DSTS_TypeDef dsts;
uint32_t fifoemptymsk = 0;
depctl.d32 = 0;
deptsiz.d32 = 0;
/* IN endpoint */
if (ep->is_in == 1)
{
depctl.d32 = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPCTL));
deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ));
/* Zero Length Packet? */
if (ep->xfer_len == 0)
{
deptsiz.b.xfersize = 0;
deptsiz.b.pktcnt = 1;
}
else
{
/* Program the transfer size and packet count
* as follows: xfersize = N * maxpacket +
* short_packet pktcnt = N + (short_packet
* exist ? 1 : 0)
*/
deptsiz.b.xfersize = ep->xfer_len;
deptsiz.b.pktcnt = (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket;
if (ep->type == EP_TYPE_ISOC)
{
deptsiz.b.mc = 1;
}
}
USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ, deptsiz.d32);
if (pdev->cfg.dma_enable == 1)
{
USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPDMA, ep->dma_addr);
}
else
{
if (ep->type != EP_TYPE_ISOC)
{
/* Enable the Tx FIFO Empty Interrupt for this EP */
if (ep->xfer_len > 0)
{
fifoemptymsk = 1 << ep->num;
USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, 0, fifoemptymsk);
}
}
}
if (ep->type == EP_TYPE_ISOC)
{
dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
if (((dsts.b.soffn)&0x1) == 0)
{
depctl.b.setd1pid = 1;
}
else
{
depctl.b.setd0pid = 1;
}
}
/* EP enable, IN data in FIFO */
depctl.b.cnak = 1;
depctl.b.epena = 1;
USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPCTL, depctl.d32);
if (ep->type == EP_TYPE_ISOC)
{
USB_OTG_WritePacket(pdev, ep->xfer_buff, ep->num, ep->xfer_len);
}
}
else
{
/* OUT endpoint */
depctl.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL));
deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ));
/* Program the transfer size and packet count as follows:
* pktcnt = N
* xfersize = N * maxpacket
*/
if (ep->xfer_len == 0)
{
deptsiz.b.xfersize = ep->maxpacket;
deptsiz.b.pktcnt = 1;
}
else
{
deptsiz.b.pktcnt = (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket;
deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
}
USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ, deptsiz.d32);
if (pdev->cfg.dma_enable == 1)
{
USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPDMA, ep->dma_addr);
}
if (ep->type == EP_TYPE_ISOC)
{
if (ep->even_odd_frame)
{
depctl.b.setd1pid = 1;
}
else
{
depctl.b.setd0pid = 1;
}
}
/* EP enable */
depctl.b.cnak = 1;
depctl.b.epena = 1;
USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL, depctl.d32);
}
return status;
}
А значит вычитка FIFO произошла до прерывания XFRC, скорее всего по прерываниям RXFLVL как и рекомендовано в доке. И все это прекрасно работает в FS режиме, а после переконфигурации на HS ядро, внешний PHY, и правки дескрипторов, начинаются вот такие чудеса с прерываниями IINCOMPISOOUT и как следствие блокированием прерываний RXFLVL и XFRC

, возможно есть какие либо особенности при работе isochronous в HS по сравнению с FS не знаю, пока ничего такого не нашел.
Но это все может оказаться бесполезным, так как не ясен источник IINCOMPISOOUT, если это искажение данных пакетов и/или неверный CRC, то как бы не читать будет явно не нормально

, как выяснить источник этого прерывания так и остается неясным. Как вариант можно заподозрить и аппаратную часть если бы не нормальная работа в VCP HS режиме, о чем писал раньше, наигрался я с этим примером достаточно, начинаются проблемы только когда сбиваю кварц МК или кварц USB3300

.
Сообщение отредактировал Left Radio - Oct 1 2014, 22:20