Not getting loopback response from FPGA via FX3 (AN84868)

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
agba_3844561
Level 3
Level 3
5 likes given First like given

I did on Windows what it said on AN84868 successfully.​ Now I want to implement the same on my own source code on linux (NEGU93/CYUSB3KIT-003_with_SP605_xilinx)

I am able to program the FX3 device and also send and receive bulk loopback messages as one will do on AN65974.​ (But with my same cpp code using cyfxbulksrcsink.img) I open a txt file and send it to 0x01 endpoint. I then try to read the same amount of bytes and I get the same exact response back on endpoint 0x81.

I try now to program the FPGA device. I first program the FX3 device with ConfigFpgaSlaveFifoSync.img then I program the FPGA with slaveFIFO2b_fpga_top.bin and it all seams to work correctly. The FX3 device reads the DONE signal and prints via UART that the FPGA was programmed successfully. I even tried with another .bin file that just play with some leds of the FPGA board to check it works fine and it does. However, when I try to send the file in the exact same way I did before (endpoing 0x01 and 0x81) I am able to send the files but I receive no answer.

Moreover, I tried after programming with my code, to use cyusb_linux program and I am able to send but not to receive the file I sent:

Screenshot from 2019-02-04 14-15-11.png

I tried both firmwares (the one for FX3 and the FPGA) using "FPGA Configuration Utility" to program both devices and "Control Center" to test the loopbacks on a windows machine and it works perfectly.

I have not many ideas on how to debug. Any advice?

Thank you very much.

0 Likes
1 Solution

Dear Hemanth,

Thank you very much for your response. Indeed, the key factor was the "Issue 0xB1" and not "send".

I changed my code from cyusb_control_write to cyusb_control_read and it worked.

So as summary:

  1. Send 0xB2
  2. Send fpga firmware file
  3. Read 0xB1

Final section of code:

unsigned short wLength = 16;
unsigned int timeout = 1000;
unsigned short wValue = 0, wIndex = 1;

printf("Programming FPGA\n");
// Start programming command
rStatus = cyusb_control_write(

  cyusb_gethandle(0)/* a handle for the device to communicate with */
   WRITE_REQUEST_TYPE/* bmRequestType: the request type field for the setup packet */
   VND_CMD_SLAVESER_CFGLOAD/* bRequest: the request field for the setup packet */
   wValue/* wValue: the value field for the setup packet */
   wIndex/* wIndex: the index field for the setup packet */
   (unsigned char *) &fpga_firmware_size/* *data: a suitably-sized data buffer */
   wLength/* wLength: the length field for the setup packet. The data buffer should be at least this size. */
   timeout)/* timeout (in millseconds) that this function should wait before giving up due to no response being received. For an unlimited timeout, use value 0. */
if (rStatus < 0) {  /* LIB_USB_ERROR */
   printf("rStatus = %d\n", rStatus);
   cyusb_error(rStatus);
   cyusb_close();
   return rStatus;
}

send_buffer(reinterpret_cast<unsigned char *>(buffer), fpga_firmware_size)// Send the FPGA firmware
//sleep(5);
rStatus = cyusb_control_read(

  cyusb_gethandle(0)/* a handle for the device to communicate with */
   0xC0/* bmRequestType: the request type field for the setup packet */
   VND_CMD_SLAVESER_CFGSTAT/* bRequest: the request field for the setup packet */
   wValue/* wValue: the value field for the setup packet */
   wIndex/* wIndex: the index field for the setup packet */
   (unsigned char *) &fpga_firmware_size/* *data: a suitably-sized data buffer */
   wLength/* wLength: the length field for the setup packet. The data buffer should be at least this size. */
   timeout)/* timeout (in millseconds) that this function should wait before giving up due to no response being received. For an unlimited timeout, use value 0. */
if (rStatus < 0) {  /* LIB_USB_ERROR */
   printf("rStatus = %d\n", rStatus);
   cyusb_error(rStatus);
   cyusb_close();
   return rStatus;
}

View solution in original post

0 Likes
4 Replies
agba_3844561
Level 3
Level 3
5 likes given First like given

I have further insight on the matter.

When I send the data to get the loopback with linux, the FX3 firmware keeps getting into the function CyFxSlFifoAppInUSBSetupCB(). However, on windows it does not. It seams that with my program the FX3 firmware is not switching to the SlaveFIFO state.

So far I had to reverse engineer the data I send to the FX3 device as I cannot see the source code of "FPGA Configuration Utility".

I did UART messages on the FX3 firmware to know what I am getting from the CPU but I'm stuck now as I don't see windows side sending anything else.

I will continue to debug now installing and learning to use WireShark. However, it will be grate to know what I have to send to the FX3 device and in what order (or a good documentation to look for).

So far I just send a B2 request with the FPGA firmware size and then a bulk transfer with the file itself as follows:

// Start programming command
rStatus = cyusb_control_write(

  cyusb_gethandle(0)/* a handle for the device to communicate with */
   WRITE_REQUEST_TYPE/* bmRequestType: the request type field for the setup packet */
   VND_CMD_SLAVESER_CFGLOAD/* bRequest: the request field for the setup packet */
   wValue/* wValue: the value field for the setup packet */
   wIndex/* wIndex: the index field for the setup packet */
   (unsigned char *) &fpga_firmware_size/* *data: a suitably-sized data buffer */
   wLength/* wLength: the length field for the setup packet. The data buffer should be at least this size. */
   timeout)/* timeout (in millseconds) that this function should wait before giving up due to no response being received. */
printf("rStatus = %d\n", rStatus);
if (rStatus < 0) {  /* LIB_USB_ERROR */
   cyusb_error(rStatus);
   cyusb_close();
   return rStatus;
}

send_buffer(reinterpret_cast<unsigned char *>(buffer), fpga_firmware_size)// Send the FPGA firmware

0 Likes

Although strange because UART messages never enter under the command 0xB1, the documentation says:

"

The FPGA Configuration Utility sends the vendor command 0xB1 automatically after all the configuration data has been sent to FX3.

"

This is strange for 2 reasons.

  1. I don't keep entering the CyFxSlFifoAppInUSBSetupCB() when sending the fpga firmware itself so it may be before that.
  2. I have added some lines of code on CyFxSlFifoAppInUSBSetupCB() to see if I receive the B1 command but I don't.

However I added it (didn't know what to put on wValue, wLength, *data, etc so I just added same info as with the B2 command) and got:

```

rStatus = -9

Pipe error

```

0 Likes
Hemanth
Moderator
Moderator
Moderator
First like given First question asked 750 replies posted

Hi,

The flow of AN84868 is:

1. Program FX3 with ConfigFpgaSlaveFifoSync.img

2. Then send Vendor command 0xB2 to transfer FPGA configuration file to FX3 (which thereby configures the FPGA)

3. Then issue the Vendor command 0xB1 to switch the GPIF interface of FX3 (only after which you can test the data loop back transfers)

    When you issue 0xB1 request, FX3 along with doing the GPIF configuration switch, sends one byte to to the Host indicating the status(success/failure) of FPGA programming.

FYI:

1. Please refer to Figure 4 in AN84868 for the above mentioned flow.

2. For your reference to your Host application code in Linux, you can refer to the source code of Windows "FPGA Configuration Utility" in the following path of AN84868 attachment:

"AN84868 - Source files for FX3 Firmware\AN84868 - Source files for FX3 Firmware\AN84868_Project_files\FPGA Configuration Utility"

3. Also refer to the following section in CyFxSlFifoApplnUSBSetupCB() of ConfigFpgaSlaveFifoSync.img:

else if (bType == CY_U3P_USB_VENDOR_RQT)

           {

            if (bRequest == VND_CMD_SLAVESER_CFGLOAD)

Regards,

Hemanth.

Hemanth
0 Likes

Dear Hemanth,

Thank you very much for your response. Indeed, the key factor was the "Issue 0xB1" and not "send".

I changed my code from cyusb_control_write to cyusb_control_read and it worked.

So as summary:

  1. Send 0xB2
  2. Send fpga firmware file
  3. Read 0xB1

Final section of code:

unsigned short wLength = 16;
unsigned int timeout = 1000;
unsigned short wValue = 0, wIndex = 1;

printf("Programming FPGA\n");
// Start programming command
rStatus = cyusb_control_write(

  cyusb_gethandle(0)/* a handle for the device to communicate with */
   WRITE_REQUEST_TYPE/* bmRequestType: the request type field for the setup packet */
   VND_CMD_SLAVESER_CFGLOAD/* bRequest: the request field for the setup packet */
   wValue/* wValue: the value field for the setup packet */
   wIndex/* wIndex: the index field for the setup packet */
   (unsigned char *) &fpga_firmware_size/* *data: a suitably-sized data buffer */
   wLength/* wLength: the length field for the setup packet. The data buffer should be at least this size. */
   timeout)/* timeout (in millseconds) that this function should wait before giving up due to no response being received. For an unlimited timeout, use value 0. */
if (rStatus < 0) {  /* LIB_USB_ERROR */
   printf("rStatus = %d\n", rStatus);
   cyusb_error(rStatus);
   cyusb_close();
   return rStatus;
}

send_buffer(reinterpret_cast<unsigned char *>(buffer), fpga_firmware_size)// Send the FPGA firmware
//sleep(5);
rStatus = cyusb_control_read(

  cyusb_gethandle(0)/* a handle for the device to communicate with */
   0xC0/* bmRequestType: the request type field for the setup packet */
   VND_CMD_SLAVESER_CFGSTAT/* bRequest: the request field for the setup packet */
   wValue/* wValue: the value field for the setup packet */
   wIndex/* wIndex: the index field for the setup packet */
   (unsigned char *) &fpga_firmware_size/* *data: a suitably-sized data buffer */
   wLength/* wLength: the length field for the setup packet. The data buffer should be at least this size. */
   timeout)/* timeout (in millseconds) that this function should wait before giving up due to no response being received. For an unlimited timeout, use value 0. */
if (rStatus < 0) {  /* LIB_USB_ERROR */
   printf("rStatus = %d\n", rStatus);
   cyusb_error(rStatus);
   cyusb_close();
   return rStatus;
}

0 Likes