Sign In | Register |
0

USBD_Write returning ACCESS_DENIED from a transfer pending signal that never clears

Technical Question - Created by Lane on 9/21/2018 7:03:55 PM
Actions

Lane

Posted
5 years ago

I'm dealing with a USB issue that has me pretty stumped on the LPC18xx MCU series.  I have created 2 endpoints for the WinUSB device as well as the interface for the mass storage device which has its 2 endpoints. I am talking to the device through a .NET app using the DZX.Devices DLL. If I keep the device powered up with another power source and constantly connect and disconnect USB, sometimes the device will not connect after awhile and on some computers it just never seems to connect at all.

status = USBD_CreateEndpoint(&usbintf, &endptRx, USBTRANSFERBULK, 0x02, 64, 512, 1, OPT_SHORTPKT);

status = USBD_CreateEndpoint(&usbintf, &endptTx, USBTRANSFERBULK, 0x82, 64, 512, 1, OPT_SHORTPKT);

status = MSCD_CreateInterface(&usbd, &mscd, 0x5);

Sometimes when I try to send a packet out on my TX thread, which simply just de-queues and sends out messages, I get back either a ERR_TIMEOUT error or a ERR_ACCESSDENIED error from USBD_Write. Once I have gotten the ACCESSDENIED, the only way to get out of that error state is to do a reset. Stepping through USBD_Write, on my call stack, it looks like it will often get interrupted by the USBD thread or the MSC thread and then when I have returned from that interrupt, I get the ERR_TIMEOUT and then later the ERR_ACCESSDENIED error. It almost seems like everything is trying to write to the same endpoint but I see how that could be possible.

If I comment out all the code to initialize the MSD, I still see the same issue. I have also tried making the timeout extremely large which also doesn't work.

Any ideas on what might be going wrong here? Thanks!

Lane

Posted
5 years ago

In USBD_Write, we changed the transfer pending check from 

if(endpt->signals.thread)

to 

if(endpt->signals.signals)

and this seems to have fixed the issue or at least made it better. Do you see any issues with this fix? We didn't see the thread getting cleared anywhere so we thought maybe it was meant to be for the actual signalset instead.

Thanks.

Tyler

DZX Support
Posted
5 years ago

Hi Lane,

So yes, I think you're on to something. I think it is more correct to check the 'signals.thread' than the 'signals.signals' when checking if a transaction is pending. The signals are not ever really returned to a known state. I do think that there could be an issue with the signals.thread not being cleared when there is a timeout or other failure. I see the signal thread is getting properly cleared when the signal is explicitly set, but I think it can get stuck when it times out.

I will do a quick test with signal sets timing out etc. and check if there is an issue with that. Also, I want to confirm it's properly releasing when the USB connection goes away too. I will follow up with what I find.

-Tyler

Tyler

DZX Support
Posted
5 years ago

Hi Lane,

I setup a test with a continuous writing thread and I believe I have reproduced the behavior you described. I made a change to the signal sets, see attached file, which fixed it on my end. Basically, it just forcibly clears the thread pointer upon exit of the blocking calls. I left the USBD_Write() function checking endpt->signals.thread.

Let me know how this change works for you.

-Tyler


Lane

Posted
5 years ago
This seems to be working much better. Thanks Tyler, much appreciated!
Reply