cancel
Showing results for 
Search instead for 
Did you mean: 

HAL USB odd/even issue for OUT endpoints

eugene239955_st
Associate II
Posted on January 05, 2016 at 13:50

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);

}
6 REPLIES 6
eugene239955_st
Associate II
Posted on January 05, 2016 at 13:53

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)

Amel NASRI
ST Employee
Posted on January 06, 2016 at 11:01

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.

eugene239955_st
Associate II
Posted on January 06, 2016 at 15:32

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.

eugene239955_st
Associate II
Posted on January 06, 2016 at 17:03

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.

eugene239955_st
Associate II
Posted on January 08, 2016 at 13:44

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.

Posted on June 13, 2017 at 11:59

I think that

if ((ep->type & EP_TYPE_MASK) == EP_TYPE_ISOC)

is more correct.