Forum Discussion
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 #endifand also ensure to set it in your tusb_config.h:
#ifndef CFG_TUSB_MCU #define CFG_TUSB_MCU OPT_MCU_CV #endif
17 Replies
- ScottP_Altera
New Contributor
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?
- FabriceNs
New 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
New 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
New Contributor
Thank you for your comment. Let me check on my side, and I'll get back to you with an update.
- ScottP_Altera
New Contributor
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
New Contributor
It seems that the file attachment is not working. You can download the files using the following link:
"USB code" (USB_code.tar.gz) est disponible au téléchargement
Please let me know if you have any issues accessing the files.
- FabriceNs
New Contributor
The traffic capture file
- TruHy
New Contributor
In HWLIB, you will need to correct the file:
include\soc_cv_av\socal\alt_usb.hIt contains registers with incorrect offset. Search for OFST. The problem starts from this code, so all registers after this:
/* The byte offset of the ALT_USB_HOST_HCFG register from the beginning of the component. */ #define ALT_USB_HOST_HCFG_OFST 0x0The HCFG register should be at offset 0x400, as shown in document: https://docs.altera.com/v/u/resources/r642178/cyclone-v-hps-register-map