Bug in cyfxusbdebug, doesnt work on USB 3

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

cross mob
LuTa_4642501
Level 3
Level 3
Welcome!

Hi,

The example cyfxusbdebug doesn't work with USB 3.0, only with USB 2.0.

Please provide a patch to fix it.

https://www.cypress.com/documentation/code-examples/ez-usb-fx3-usb-debug-example

Code to test:

#include <stdio.h>

#include <libusb-1.0/libusb.h>

#include <stdint.h>

#include <string.h>

int main(int argc, char*argv[])

{

    int res                      = 0;

    libusb_device_handle* handle = 0;

    int kernelDriverDetached     = 0;

    int numBytes                 = 0;

    uint8_t buffer[128];

    int a;

    res = libusb_init(0);

    if (res != 0) {

        fprintf(stderr, "Error initialising libusb.\n");

        return 1;

    }

    handle = libusb_open_device_with_vid_pid(0, 0x04b4, 0x00f0);

    if (!handle) {

        fprintf(stderr, "Unable to open device.\n");

        return 1;

    }

    if (libusb_kernel_driver_active(handle, 0)) {

        res = libusb_detach_kernel_driver(handle, 0);

        if (res == 0) {

          kernelDriverDetached = 1;

        } else {

          fprintf(stderr, "Error detaching kernel driver.\n");

          return 1;

        }

    }

    res = libusb_claim_interface(handle, 0);

    if (res != 0) {

        fprintf(stderr, "Error claiming interface.\n");

        return 1;

    }

    for (a=0;a<100;a++) {

        res = libusb_interrupt_transfer(handle, 0x81, buffer, 128, &numBytes, 5000);

        if (0 == res) {

            printf("Received %d bytes, expected 64.\n", numBytes);

        } else {

           fprintf(stderr, "Error receiving message %d.\n", a);

        }

    }

    res = libusb_release_interface(handle, 0);

    if (0 != res) {

      fprintf(stderr, "Error releasing interface.\n");

    }

    if (kernelDriverDetached) {

        libusb_attach_kernel_driver(handle, 0);

    }

    libusb_exit(0);

    return 0;

}

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.

Hello,

Please look into the firmware.

pastedImage_0.png

The firmware will log incremental data . That is what you are seeing on the control center.

If you want only the debug print data. Please replace the CyU3PDebuglog() line with the CyU3PDebugprint() line which is highlighted.

I have done it for you in the attached project. Use the debug image.

password: cypress

pastedImage_1.png

View solution in original post

0 Likes
22 Replies
YatheeshD_36
Moderator
Moderator
Moderator
750 replies posted 500 replies posted 250 solutions authored

Hello,

Please use the CyU3PDebugLogFlush() API in the firmware thread as soon as the CyU3PDebugLog() is called. This will flush the contents in the internal memory buffer to the target when when its not full. You will get the 8 bytes of data which incudes the message (2 bytes) and  parameter (4 bytes).

Thanks,

Yatheesh

0 Likes

Ok, this make it work over USB 3.

And now there is a lot of garbage being print.

root@raspberrypi ~ gcc int.c -o int -lusb-1.0 ; ./int 
8 #xV4#
8 #xV4"#
8 #xV42#
8 #xV4B#
8 #xV4R#
8 #xV4b#
8 #xV4r#
8 #xV4�#
8 #xV4�#
8 #xV4�#
8 #xV4�#
8 #xV4�#
8 #xV4�#
8 #xV4�#
8 #xV4�#
8 #xV4#
8 #!xV4#
8 #!xV4"#
8 #!xV42#
8 #!xV4B#
8 #!xV4R#
8 #!xV4b#
8 #!xV4r#
8 #!xV4�#
8 #!xV4�#
8 #!xV4�#
8 #!xV4�#
8 #!xV4�#
8 #!xV4�#
8 #!xV4�#

# Userspace code used for test:

#include <stdio.h>

#include <libusb-1.0/libusb.h>

#include <stdint.h>

#include <string.h>

int main(int argc, char*argv[])

{

    int res                      = 0;

    libusb_device_handle* handle = 0;

    int kernelDriverDetached     = 0;

    int numBytes                 = 0;

    int a,b;

    unsigned char str[128];

    res = libusb_init(0);

    if (res != 0) {

        fprintf(stderr, "Error initialising libusb.\n");

        return 1;

    }

    handle = libusb_open_device_with_vid_pid(0, 0x04b4, 0x00f0);

    if (!handle) {

        fprintf(stderr, "Unable to open device.\n");

        return 1;

    }

    if (libusb_kernel_driver_active(handle, 0)) {

        res = libusb_detach_kernel_driver(handle, 0);

        if (res == 0) {

          kernelDriverDetached = 1;

        } else {

          fprintf(stderr, "Error detaching kernel driver.\n");

          return 1;

        }

    }

    res = libusb_claim_interface(handle, 0);

    if (res != 0) {

        fprintf(stderr, "Error claiming interface.\n");

        return 1;

    }

    for (a=0;a<100;a++) {

        memset(str, 0, 128);

        res = libusb_interrupt_transfer(handle, 0x81, str, 128, &numBytes, 1000);

        if (0 == res)

            printf("%d #%s#\n", numBytes, str);

        else

           fprintf(stderr, "Error receiving message %d.\n", a);

    }

    res = libusb_release_interface(handle, 0);

    if (0 != res)

      fprintf(stderr, "Error releasing interface.\n");

    if (kernelDriverDetached)

        libusb_attach_kernel_driver(handle, 0);

    libusb_exit(0);

    return 0;

}

0 Likes

Now this issue has the same garbage as cyfxusbdebug gives garbage over usb

0 Likes

Hello,

Please use the latest FX3 1.3.4 Linux SDK: https://www.cypress.com/documentation/software-and-drivers/ez-usb-fx3-software-development-kit

The programmer's guide in the SDK will define all the available APIs.

Please use the cyusb_interrupt_transfer() API for interrupt transfer.

Let me know if this works?

Thanks,

Yatheesh

0 Likes

Hi,

Having a userspace software capable of reading this data is just one step in order of making sure the firmware is working.

The final solution needs to work inside the Linux kernel as a device driver, so using one library from cypress may work for userspace, but will not work for the kernel driver.

Please explain whats needs to be done to correctly receive this data without the use of the cypress library.

The device driver gets the same garbage:

[    6.575114] usb 2-1: new SuperSpeed Gen 1 USB device number 2 using xhci_hcd
[    6.605642] usb 2-1: LPM exit latency is zeroed, disabling LPM.
[    6.612271] usb 2-1: New USB device found, idVendor=04b4, idProduct=00f0, bcdDevice= 0.00
[    6.620532] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    6.627760] usb 2-1: Product: FY3
[    6.631092] usb 2-1: Manufacturer: TANURE3
[    6.676491] clubb_probe
[    6.676500] int_in
[    6.678988] max 128 addr 129 interval 1
[    6.715327] usbcore: registered new interface driver Clubb_Core
[    6.716188] clubb_complete ## xV4
[    6.778729] clubb_complete ## xV4"
[    6.876497] clubb_complete ## xV42
[    6.974133] clubb_complete ## xV4B
[    7.071771] clubb_complete ## xV4R
[    7.169414] clubb_complete ## xV4b
[    7.267052] clubb_complete ## xV4r
[    7.364822] clubb_complete ## xV4\x82
[    7.462424] clubb_complete ## xV4\x92
[    7.560095] clubb_complete ## xV4\xa2
[    7.657733] clubb_complete ## xV4\xb2
[    7.755500] clubb_complete ## xV4\xc2

Source Code for the device driver:

/*

  * This software is licensed under the terms of the GNU General Public

  * License version 2, as published by the Free Software Foundation, and

  * may be copied, distributed, and modified under those terms.

  *

  * This program is distributed in the hope that it will be useful,

  * but WITHOUT ANY WARRANTY; without even the implied warranty of

  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

  * GNU General Public License for more details.

  */

#define DEBUG

#include <linux/usb.h>

#include <linux/module.h>

#include <linux/slab.h>

/* Structure to hold all of our device specific stuff */

struct clubb_data {

     struct usb_device *udev; /* usb device */

     struct urb *urb; /* usb request block */

     u8 *urbdata; /* interrupt URB data buffer */

};

static void clubb_complete(struct urb *urb)

{

     int status = urb->status;

     char* str;

     if (status && !(status == -ENOENT || status == -ECONNRESET || status == -ESHUTDOWN)) {

          pr_err("Error! urb=%p bulk status: %d\n", urb, status);

     }

     str = (char*)urb->transfer_buffer;

     pr_info("%s ## %s", __func__, str);

     if (usb_submit_urb(urb, GFP_KERNEL)){

          pr_info("BAD usb_submit_urb");

     }

}

static int clubb_probe(struct usb_interface *intf, const struct usb_device_id *id)

{

     struct usb_device *udev = interface_to_usbdev(intf);

     struct clubb_data* clubb;

     struct usb_host_interface *iface_desc;

     struct usb_endpoint_descriptor *int_in;

     int r     et = 0;

     pr_info("%s", __func__);

     clubb = devm_kzalloc(&udev->dev, sizeof(struct clubb_data), GFP_KERNEL);

     if (!clubb){

          pr_info("BAD devm_kzalloc");

          return -ENOMEM;

     }

     clubb->udev = udev;

     usb_set_intfdata(intf, clubb);

     iface_desc = intf->cur_altsetting;

     ret = usb_find_common_endpoints(iface_desc, NULL, NULL, &int_in, NULL);

     if (ret) {

          dev_err(&udev->dev, "Could not find endpoints\n");

     }

     if (int_in)

          pr_info("int_in");

     pr_info("max %d addr %u interval %u\n" , usb_endpoint_maxp(int_in), int_in->bEndpointAddress, int_in->bInterval);

     clubb->urb = usb_alloc_urb(0, GFP_KERNEL);

     if (!clubb->urb) {

     pr_info("BAD usb_alloc_urb");

     return -ENOMEM;

     }

     clubb->urbdata = usb_alloc_coherent(udev, 128, GFP_KERNEL, &clubb->urb->transfer_dma);

     if (!clubb->urbdata) {

          usb_free_urb(clubb->urb);

          pr_info("BAD usb_alloc_coherent");

          return -ENOMEM;

     }    

     usb_fill_int_urb(clubb->urb, udev, usb_rcvintpipe(udev, int_in->bEndpointAddress), clubb->urbdata, usb_endpoint_maxp(int_in), clubb_complete,

                         clubb, int_in->bInterval);

     clubb->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;

     if (usb_submit_urb(clubb->urb, GFP_KERNEL)){

     pr_info("BAD usb_submit_urb");

     return -EIO;

     }

     return ret;

}

static void clubb_disconnect(struct usb_interface *intf)

{

     struct clubb_data *clubb = usb_get_intfdata(intf);

     usb_kill_urb(clubb->urb);

     usb_free_coherent(clubb->udev, 128, clubb->urbdata, clubb->urb->transfer_dma);

     usb_free_urb(clubb->urb);

     devm_kfree(&clubb->udev->dev, clubb);

}

static const struct usb_device_id clubb_id_table[] = {

{ USB_DEVICE(0x04b4, 0x00f0) },

     {}

};

MODULE_DEVICE_TABLE(usb, clubb_id_table);

static struct usb_driver clubb_driver = {

     .name = "Clubb_Core",

     .probe = clubb_probe,

     .disconnect = clubb_disconnect,

     .id_table = clubb_id_table,

};

module_usb_driver(clubb_driver);

MODULE_AUTHOR("Lucas Tanure <tanureal@opensource.cirrus.com>");

MODULE_DESCRIPTION("Driver for Testing Interrupt communication");

MODULE_LICENSE("GPL v2");

         

0 Likes

Hello,

Can you please print the data as hex values that is received from the libusb_interrupt_transfer().

Also,  please try using the control center to do interrupt IN transfer in Windows or Linux and compare the hex data received with your application output.

Let me know the results.

Thanks,

Yatheesh

0 Likes

Hi,

New userspace code with the modifications:

cypress usbdebug userspace test - Pastebin.com

New output that printds the first 32 bytes from usb:

root@raspberrypi ~ gcc int.c -o int -lusb-1.0 ; ./int     
01 15 11 c1 78 56 34 82 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 c1 78 56 34 92 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 c1 78 56 34 a2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 c1 78 56 34 b2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 c1 78 56 34 c2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 c1 78 56 34 d2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 c1 78 56 34 e2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 c1 78 56 34 f2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 c1 78 56 34 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 d1 78 56 34 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 d1 78 56 34 22 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 d1 78 56 34 32 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 d1 78 56 34 42 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 d1 78 56 34 52 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 d1 78 56 34 62 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 d1 78 56 34 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 d1 78 56 34 82 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 d1 78 56 34 92 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 d1 78 56 34 a2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
01 15 11 d1 78 56 34 b2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

0 Likes

There is another way to execute the test you want without running the control center?

because the control center is very old software that doesn't build anymore, it needs qt5 and some icui18n library that my system doesn't have.

0 Likes

Top image is the hex dump file.

The bottom image is what the control center shows

Capture.PNG

0 Likes

Hello,

Looks like your application is working fine !

Thanks,

Yatheesh

0 Likes

Hello,

Please let me know what data was expected from the interrupt transfer?

The control center (windows and linux) will display the data received in hex format when the interrupt transfer is successful, else it returns an error.

If you are expecting ASCII characters then the appropriate conversion needs to be done on the application and the firmware side.

Thanks,

Yatheesh

0 Likes

Hi,

The data expected is the debug string sent by the firmware.

CyU3PDebugPrint (2, "USB Debug logger: time from start in ticks: %d\n", CyU3PGetTime ());

Please read the README from Cypress cyfxusbdebug example:

"This example illustrates the use of the FX3 firmware APIs to implement a debug log mechanism over the USB interface.

The device enumerates as a vendor-specific USB device with a single interrupt endpoint (EP1-IN). The application sends out periodic log information out on the USB interface. The length of log can be up to 128 bytes. So the user should never request for data transfer of size less than 128 bytes."

So, it seems this firmware Cypress offer doesn't work and there is no userspace application to be used with.

Can please provide a way to get this data that the firmware is sending in Linux userspace?

Thanks

Lucas

0 Likes

Please use the CyU3PDebugLogFlush() after the API CyU3PDebugPrint (2, "USB Debug logger: time from start in ticks: %d\n", CyU3PGetTime ());

pastedImage_2.png

Please let me know what issue you are facing?

Regards,

Yatheesh

0 Likes

Hi,

The issue is the same as the begging of this conversation, the cyfxusbdebug demo doesn't work or USB3 and USB2, where it only outputs garbage.

Please share your full source code as what you are saying doesn't work on my side:

Capture.PNG

0 Likes

My full source code being used for the firmware:

usb_lessons.tar.gz - Google Drive

My make output:

rm -f ./cyfxusbdebug.elf
rm -f ./cyfxusbdebug.map
rm -f ./*.o
rm -f cyfxtx.c cyfx_startup.S cyfx_gcc_startup.S
rm -rf ../elf2img/elf2img
rm -rf cyusb3kit-003.bin
arm-none-eabi-gcc -g -DTX_ENABLE_EVENT_TRACE -DDEBUG -DCYU3P_FX3=1 -D__CYU3P_TX__=1 -I. -I../fw_lib/1_3_4/inc  -O0 -Wall -mcpu=arm926ej-s -mthumb-interwork -ffunction-sections -fdata-sections -c
-o cyfxusbdebug.o cyfxusbdebug.c 
arm-none-eabi-gcc -g -DTX_ENABLE_EVENT_TRACE -DDEBUG -DCYU3P_FX3=1 -D__CYU3P_TX__=1 -I. -I../fw_lib/1_3_4/inc  -O0 -Wall -mcpu=arm926ej-s -mthumb-interwork -ffunction-sections -fdata-sections -c
-o cyfxusbdscr.o cyfxusbdscr.c 
cp ../fw_build/fx3_fw/cyfxtx.c .
arm-none-eabi-gcc -g -DTX_ENABLE_EVENT_TRACE -DDEBUG -DCYU3P_FX3=1 -D__CYU3P_TX__=1 -I. -I../fw_lib/1_3_4/inc  -O0 -Wall -mcpu=arm926ej-s -mthumb-interwork -ffunction-sections -fdata-sections -c
-o cyfxtx.o cyfxtx.c 
cp ../fw_build/fx3_fw/cyfx_gcc_startup.S .
arm-none-eabi-gcc  -Wall -c -mcpu=arm926ej-s -mthumb-interwork -o cyfx_gcc_startup.o cyfx_gcc_startup.S
arm-none-eabi-ld cyfx_gcc_startup.o cyfxusbdebug.o cyfxusbdscr.o cyfxtx.o --entry CyU3PFirmwareEntry -L ../fw_lib/1_3_4/fx3_debug -lcyu3sport -lcyu3lpp -lcyfxapi -lcyu3threadx "$ARMGCC_INSTALL_P
ATH"/arm-none-eabi/lib/libc.a "$ARMGCC_INSTALL_PATH"/lib/gcc/arm-none-eabi/4.8.1/libgcc.a  -T ../fw_build/fx3_fw/fx3_512k.ld -d --gc-sections --no-wchar-size-warning -Map cyfxusbdebug.map -o cyf
xusbdebug.elf
gcc ../elf2img/elf2img.c -o ../elf2img/elf2img 
../elf2img/elf2img -i cyfxusbdebug.elf -o cyusb3kit-003.bin
Note: 256 bytes of interrupt vector code have been removed from the image.
      Use the "-vectorload yes" option to retain this code.

0 Likes
lock attach
Attachments are accessible only for community members.

Hello,

Attached is the source.

I have added two lines to the original source. Both of which are CyU3PDebugLogFlush() after calling the CyU3PDebugLog() and CyU3PDebugPrint().

Please let me know if you still face issues.

password: cypress

Thanks,

Yatheesh

0 Likes

Hi,

Using Windows 10 with this control center:

Capture.PNG

And the images I received by the last post.

USBDebug from release folder SHA-256  9E5C54A9DE1246EE36BA3CC2EB75EC35E2F9D593703DC8C497967189949C8AEB

USB2 and 3 continue to not work, Tested with two different CYUSB3KIT-003.

How to reproduce the issue:

1 - Open control center

2 - Plug the CYUSB3KIT-003 with the PMODE J4 mode shorted with a jumper

3 - Flash to RAM the USBDebug image received

4 - Click Transfer Data-In

Result: USB3 gets zero transfers or error 997

usb3.PNG

USB2 Result:

Receives garbage over USB2

usb2.PNG

0 Likes

Adding more info about the hardware, the images for MouseDemo and BootLedBlink works fine, so the hardware CYUSB3KIT-003 is working fine.

0 Likes
lock attach
Attachments are accessible only for community members.

Please use the img file from the Debug folder.

I have attached the image file to this response.

The below shown data is not garbage values. They are set in the firmware.

usb2.PNG

0 Likes

Hi,

This image has the same result, not the expected data:

Expected:  USB Debug logger: time from start in ticks

Got:     xV4"

Results are the same for USB3 and USB2.

If it working for you your hardware must be different in some way. Are you using cyusb3kit-003?

usb3.PNG

0 Likes
lock attach
Attachments are accessible only for community members.

Hello,

Please look into the firmware.

pastedImage_0.png

The firmware will log incremental data . That is what you are seeing on the control center.

If you want only the debug print data. Please replace the CyU3PDebuglog() line with the CyU3PDebugprint() line which is highlighted.

I have done it for you in the attached project. Use the debug image.

password: cypress

pastedImage_1.png

0 Likes

Thanks!

Looking at the previous code I assumed CyU3PDebugPrint would be called at some point.

But, yes, I'm more interested in the string data.

Thanks for your help

0 Likes