Forum Discussion

FabriceNs's avatar
FabriceNs
Icon for New Contributor rankNew Contributor
1 month ago
Solved

USB Device Issue on Cyclone V / HPS

Hello,

Please find below a description of the USB issue we are experiencing with our Cyclone V / HPS board.

To test our USB interface, we integrated the TinyUSB library into our existing firmware and enabled FreeRTOS support.

Since the Cyclone V is not natively supported, I implemented the missing functions using Altera's hwlib, which we already use in our project (source file attached).

The USB is used only in Device mode. I tested the following four configurations:

  • Full-Speed with Slave mode
  • Full-Speed with Simple DMA
  • High-Speed with Slave mode
  • High-Speed with Simple DMA

The behavior is identical in all four cases:

  • Connecting our board to a Windows or Linux host is correctly detected.
  • The SETUP transaction is successfully received, and the host receives the device descriptor in response.
  • When the IN transfer complete interrupt is triggered, the USB controller is configured to receive a zero-length packet on OUT0. However, the USB protocol analyzer shows that the device continuously responds with NAK to this packet.
  • The host retries for approximately 5 seconds, but the device keeps responding with NAK.

The register values immediately after configuring the reception of the OUT0 packet are:

  • Gotgctl = 0xd00c0
  • Gintsts = 0x4000020 (PTxFEmp, NPTxFEmp)
  • Gdfifocfg = 0x1f802000
  • Dctl = 0
  • Dcfg = 0x8100001
  • Dsts = 0x18702
  • Doepctl0 = 0x80008000
  • Doepint0 = 0
  • Doeptsiz0 = 0x80000
  • Grxfsiz = 0x50

After a few milliseconds, I observe that DOEPINT0.NAKINTRPT = 1, which seems to confirm that the device is sending NAKs. However, I do not understand why the OUT packet is not being accepted, since the receive FIFO is not full and both DCTL.GOUTNAKSTS = 0 and DOEPCTL0.NAKSTS = 0.

  • @FabricNS

    Please ignore above issue that wasn't it.

    I played some more with the tinyusb code and finally found the problem.  It seems the old dwc2 USB controller receive fifo size must be set to a minimum of 119 words.  The fix is to edit the tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c file at the function calc_device_grxfsiz().

    The original code is:

    TU_ATTR_ALWAYS_INLINE static inline uint16_t calc_device_grxfsiz(uint16_t largest_ep_size, uint8_t ep_count) {
      return (uint16_t)(13 + 1 + 2 * ((largest_ep_size / 4) + 1) + 2 * ep_count);
    }

    I changed it to this:

    TU_ATTR_ALWAYS_INLINE static inline uint16_t calc_device_grxfsiz(uint16_t largest_ep_size, uint8_t ep_count) {
      // Altera Cyclone V SoC DWC2 bug, the minimum grzfsiz is 119 words, i.e. 4*119 = 476 bytes
    #if defined(TUP_USBIP_DWC2_CV) && TU_CHECK_MCU(OPT_MCU_CV)
      uint16_t words = (uint16_t)(13 + 1 + 2 * ((largest_ep_size / 4) + 1) + 2 * ep_count);
      if(words < 119) words = 119;
      return words;
    #else
      return (uint16_t)(13 + 1 + 2 * ((largest_ep_size / 4) + 1) + 2 * ep_count);
    #endif
    }

    You will also need to add OPT_MCU_CV into tinyusb/src/common/tusb_mcu.h:

    ......
    //--------------------------------------------------------------------+
    // Geehy
    //--------------------------------------------------------------------+
    #elif TU_CHECK_MCU(OPT_MCU_APM32F0XX)
      #define TUP_USBIP_FSDEV
      #define TUP_USBIP_FSDEV_APM32
      #define CFG_TUSB_FSDEV_PMA_SIZE 1024u
    
    //--------------------------------------------------------------------+
    // Altera Cyclone V SoC
    //--------------------------------------------------------------------+
    #elif TU_CHECK_MCU(OPT_MCU_CV)
      #define TUP_USBIP_DWC2
      #define TUP_USBIP_DWC2_CV
    
      #define TUP_DCD_ENDPOINT_MAX 16
    #endif

    and also ensure to set it in your tusb_config.h:

    #ifndef CFG_TUSB_MCU
    #define CFG_TUSB_MCU          OPT_MCU_CV
    #endif

     

17 Replies

  • It can't hurt to check the header file against the Cyclone V HPS register map.  An AI could check this quickly for you.   If you are using a recent copy of alt_usb.h, you are probably good.  

    The dwc2_cv.h header file seems OK.  Can you share the code that manages the endpoint?  

    • FabriceNs's avatar
      FabriceNs
      Icon for New Contributor rankNew Contributor

      I need to request the code from our development team first. I'll get back to you as soon as I receive it.

      • FabriceNs's avatar
        FabriceNs
        Icon for New Contributor rankNew Contributor

        I have now received the files. Please find them attached for your reference.

  • FabriceNs's avatar
    FabriceNs
    Icon for New Contributor rankNew Contributor

    I have attached the requested files. Please rename the dwc2_cv.txt file to dwc2_cv.h.

    Regarding the USB analyzer trace, I still need to verify whether I have the required setup and capability to provide it.

    I will confirm this as soon as possible.

    • TruHy's avatar
      TruHy
      Icon for New Contributor rankNew Contributor

      I think the problem might be the hwlib alt_usb.h file.  If I remember from many years ago, I noticed that some (but not all) registers have the wrong address offset.  Perhaps these registers are affected DOEPCTL0 and DOEPTSIZ0 , so basically you could be writing to incorrect registers.

      • FabriceNs's avatar
        FabriceNs
        Icon for New Contributor rankNew Contributor

        Thank you for your comment. Let me check on my side, and I'll get back to you with an update.

  • I don't see the source file you mentioned.  Can you attach it?  Also, do you have the ability to provide a USB analyzer trace?