AnsweredAssumed Answered

STM32F207 USB Device Lib HS core w/ Emedded PHY USBD_GetDescriptor() FS descriptor bugfix

Question asked by slaymaker.robert on Jun 18, 2014
After applying a number of bugfixes posted on the forum for the pre-Cube device libraries, I eventually found another one needed to get the HS core working in FS mode.

The issue is that, in file usbd_req.c, the USBD_GetDescriptor() function assumes that the internal core is HS only and only returns the FS descriptor if an external PHY is in FS mode.

The symptom is that, when implementing a CDC emulated serial port, at least, the device will enumerate, appear as a serial port on the host, allow the host to open a serial connection and set and get the line (UART) settings, but will not allow serial data to be sent or received. Data sent IN to the host will disappear, seemingly without error (I didn't see any error handling code being called in ST's library, anyway) and attempts to write OUT from a Windows host will garner a "serial write error" (USB specific errors aren't exposed via virtual serial ports on Windows AFAICS).

The fix I applied was to comment out the additional check for the external PHY as follows (I also moved the HS descriptor fetch into an else block). This enabled data to flow, though beware the numerous additional bugs! For performance's sake, you may wish to skip all high-speed related code when using the internal PHY.

The Cube code seems to be better designed and hopefully has fewer of these issues.

I suspect this particular issue escaped the lab because of ST not testing their code on an HS core with the embedded PHY, probably due to the fact that boards like their STM3220F-EVAL use an external PHY. I tripped over this porting code to IAR's STM32F207ZG-SK, which uses an embedded PHY.

I really hope ST ups their game--providing high quality reference code would make their chips even more popular and less likely to be associated with "oh, crap" moments when a bug of theirs causes field reliability issues (I know, it's only example code, but the reality is that a lot of it gets fielded).

Here's an example of how to fix the issue (feedback, related issues, suggestions welcome!).

      if((pdev->cfg.speed == USB_OTG_SPEED_FULL ) /*Bugfix: embedded "HS" PHY runs in FS mode &&
       (pdev->cfg.phy_itface  == USB_OTG_ULPI_PHY) */
      pbuf   = (uint8_t *)pdev->dev.class_cb->GetOtherConfigDescriptor(pdev->cfg.speed, &len);
      pbuf   = (uint8_t *)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len);

Here's the top-of-file comment below for reference.

  * @file    usbd_req.c
  * @author  MCD Application Team
  * @version V1.1.0
  * @date    19-March-2012