BulkOutEndPt->XferData returning STATUS_NO_SUCH_DEVICE after device opened successfully

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

cross mob
Anonymous
Not applicable

I am using a Cypress FX3 device with USB 2 and bulk transfers, and my device works fine when I use it normally. However, if I configure our software to run at boot, then I run into two problems that occur at random. First, it may have trouble opening the device. However, if I configure the software to make multiple attempts, with a one second delay in between, then it eventually succeeds in opening the device (usually on the first retry). Second, once the device is opened (whether it opened on the first try or not), sometimes it fails to write to the device and the only error returned is in BulkOutEndPt->NtStatus, with either 0xC0000001 (STATUS_UNSUCCESSFUL) or 0xC000000E (STATUS_NO_SUCH_DEVICE) or both, if I continue to try writing to the device. This only happens during a fresh boot (as opposed to a reboot) on Windows 10 and does not always happen (maybe once every three boots).

I'm trying to sort out if this is a software issue, or a hardware issue. If I interact with the device as a service at boot, are there dependencies I need to add to the service to ensure it doesn't run too soon for the Cypress driver or FX3 API (what are their dependencies)? If the device opens successfully, what potential causes could there be for it not to be able to write to the device at boot when it always works fine after boot? Are there tools I could use to debug this further?

Any suggestions would be appreciated. Thanks.

Dan

0 Likes
1 Solution

Hello,

The host application API function, Open()  returns the handle to the respective device only if the device is enumerated properly and is bound to the CyUsb3.sys driver.

You can use the DeviceCount() function before calling the Open(). The DeviceCount() will return the number of devices connected to the cyusb3 driver. If this function returns the one, then you can call the Open(device number) . If only one cypress device is connected the device number should be 0.

Once the Open() function returns true, you can confirm if a valid handle is returned using the function IsOpen( ). If Open() returns false, please reset the device using Reset() function and then perform Open() again.

If IsOpen( ) returns true, then IO operations via the Endpoints can be initiated,  else if it returns false please use the reset function again Reset() and try opening the device.

Please use the example snippet given under the Open() function description in your application.

Let me know if IsOpen() function returned true, and still you are not able to perform IO operations.

Thanks,

Yatheesh

View solution in original post

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

Hello,

At boot, the descriptors of the device and hence the endpoints of the device will not be configured.

Only the control endpoint will be initialized for certain operations like loading the firmware on to the RAM of the device.

You can verify this using the control center.

Please use a firmware and initialize the endpoints of the device before accessing the device endpoints.

Thanks,

Yatheesh

0 Likes
Anonymous
Not applicable

The device is configured to load firmware from an EEPROM, IIRC. We don't have to download firmware from the PC. The Cypress firmware initializes the endpoints on its end, which I assume occurs much faster than the PC boot sequence. Micros tend to power up very quickly. On the PC side we are using the Cypress FX3 API so the bulk endpoints on the PC end are initialized by the Open() call, as per the documentation:

Open( ) calls the driver to gather the device, interface, endpoint and string descriptors.

Open( ) results in the EndPoints array getting properly initialized to pointers of the default interface's endpoints.

Open( ) initializes the ControlEndPt member to point to an instance of CCyControlEndPoint that represents the device's endpoint zero.

Open( ) initializes the BulkInEndPt member to point to an instance of CCyBulkEndPoint representing the first Bulk-IN endpoint that was found. Similarly, the BulkOutEndPt,InterruptInEndPt,InterruptOutEndPt,IsocInEndPt and IsocOutEndPt members are intialized to point to instances of their respective endpoint classes if such endpoints were found.

After Open( ) returns true, all the properties and methods of CCyUSBDevice are legitimate.

As I said, when our software is run after PC boot everything works fine so clearly the firmware and endpoints are properly initialized at that point. When I say "at boot" in the previous post I don't mean booting of the Cypress chip I mean booting of the PC which is connected by a USB cable to the Cypress chip.

Sincerely,

Dan

0 Likes

Hello,

The host application API function, Open()  returns the handle to the respective device only if the device is enumerated properly and is bound to the CyUsb3.sys driver.

You can use the DeviceCount() function before calling the Open(). The DeviceCount() will return the number of devices connected to the cyusb3 driver. If this function returns the one, then you can call the Open(device number) . If only one cypress device is connected the device number should be 0.

Once the Open() function returns true, you can confirm if a valid handle is returned using the function IsOpen( ). If Open() returns false, please reset the device using Reset() function and then perform Open() again.

If IsOpen( ) returns true, then IO operations via the Endpoints can be initiated,  else if it returns false please use the reset function again Reset() and try opening the device.

Please use the example snippet given under the Open() function description in your application.

Let me know if IsOpen() function returned true, and still you are not able to perform IO operations.

Thanks,

Yatheesh

0 Likes