2016-01-05 04:50 AM
When preparing to receive the data on OUT isochronous endpoint, the HAL sets up the even/odd flag once when you call the PrepareReceive for that specific frame that is active at that moment.
However the data may come on other odd/even frame than was expected and thus the first transfer will be lost 50% of the time.
In the EOPF interrupt the odd/even flag needs to be updated for all active endpoints.The EOPF should also be unmasked in init section as well.This change to HAL_PCD_IRQHandler is working for me: if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_EOPF)) { /* End of frame */ uint8_t i; for(i = 0; i < 16; i++) { ep = &hpcd->OUT_ep[i]; // Check if there are enabled endpoints if((USBx_OUTEP(ep->num)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) { if ((ep->type & EP_TYPE_ISOC) == EP_TYPE_ISOC) { if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0) { USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM; } else { USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; } } } } __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_EOPF); }2016-01-05 04:53 AM
Also in the rest of HAL code, the check for isochronous should be changed to & from strict ==.
This is because there are additional bits for isochronous endpoints and the attribute might be not 0x01 all the time.For example audio isochronous endpoint with feedback is 0x05 but still it is isochronous.Proposed check is:if ((ep->type & EP_TYPE_ISOC) == EP_TYPE_ISOC)
2016-01-06 02:01 AM
Hi shamaev.eugene,
Could you please precise the device you are using and the firmware version?-Mayla-To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2016-01-06 06:32 AM
Device is STM32F446RET6.
I am not sure what you mean by firmware version, the cubeMX is 4.12.0 and stm32f4xx_hal_pcd is version V1.4.3.I also see that cubeMX generates code this way for all F4 series.2016-01-06 08:03 AM
For your information as I am not sure if HAL developers read reference manual.
From page 1245 of RM0390 (reference manual):2. When an isochronous OUT endpoint is enabled by setting the Endpoint Enable andclearing the NAK bits, the Even/Odd frame bit must also be set appropriately. The corereceives data on an isochronous OUT endpoint in a particular frame only if thefollowing condition is met:– EONUM (in OTG_DOEPCTLx) = FNSOF[0] (in OTG_DSTS).From the HAL code it is clear that it is not done this way.And the MCU really works the way described in reference manual.2016-01-08 04:44 AM
Update. I have found one more solution that is in my case much better.
EndOfFrameCallback was implemented and if the endpoint needs to be working, then USBD_LL_PrepareReceive is called there.This also agrees with reference manual stating that endpoint must be enabled after end of frame and before start of frame interrupts.2017-06-13 04:59 AM
I think that
if ((ep->type & EP_TYPE_MASK) == EP_TYPE_ISOC)
is more correct.