Sign In | Register |
0

USBD Connection Notifications

Technical Question - Created by Spencer on 3/9/2016 11:17:06 AM
Actions
Implemented in
v16.1.7

Spencer

Posted
8 years ago

Good Morning,


I'm using the Mass Storage Controller USB Device and am tyring to find the most elegant way to detect a USB connection. The embedded application uses a file on the storage disk for diagnostic information. Right now, I'm manually disabling diagnostic logging using a button on the device before connecting usb to avoid a corrupt mass storage device.

I would like to try and detect a connection from a host, disable my diagnostic logging, unmount the file system, and then allow the connection to proceed.

My first attempt was at calling the "USBD_IsConnected(&usbd)" function from a thread to detect the connection. I've found that by the time I can call this and check the result, the USB interrupt has already responded to several commands and it's too late. I've also found that this call will return true forever, after a connection has been initialized even after the USB cable is unplugged. 

I'm hoping you can point me towards a hook or callback that I've overlooked in the USB Stack to help, or guide me in the right direction to implement this feature that plays the nicest with the USB Stack and the rest of the SDK.


Thanks so much,

-Spencer

Tyler

DZX Support
Posted
8 years ago

Hello Spencer,


In order to keep the USB responsive to host requests, it may be best to try and detect the connected host via the VBUS signal. You could setup the USB stack as usual, but not make a call to USB_Open(). Upon detecting VBUS (on an MCU pin), perform the shut down of the local file system, then call USB_Open() which will then indicate to the host to begin enumeration. What's nice is that it wouldn't matter how much time goes by between VBUS appearing and calling USBD_Open().


For the reverse, USBD_Close() can be used to disconnect from the host, but the stack structure (interfaces, endpoints etc) will remain unchanged. Then the local file system can mount again.


Using VBUS does require the appropriate hardware to be implemented, so if that isn't psossible, I can provide some more information if a callback etc is required.


Tyler

DZX Support
Posted
8 years ago

Spencer,


Thinking some more on this. Another option is to have the USB connect with a host as normal, but have the mass storage interface respond with information indicating the media is not ready (for example an SD card not inserted). Then you could just use the USBD_IsConnected() to detect when a host is present and not worry about it being too late.


This path would require some changes in the mass storage interface and the underlying disk drivers, but it will be needed for us in the future for SD card support.


-Tyler


Spencer

Posted
8 years ago

Tyler,

Thank you for the response. I don't have the VBUS piped into the processor. I will attempt to implement the "not ready" approach in your post and report back. Sounds like a wonderful solution.


Thanks,

-Spencer

Tyler

DZX Support
Posted
8 years ago

Spencer,


I am looking into adding this capability as well on our end. I am currently working with an SD card and working through the proper responses for when the card is not present. The biggest behavior change is within the mass storage interface for the SCSI_TESTUNITREADY command. It's working as expected when the card is removed, but still working on the recovery for when the card is reinserted.


The issue for your scenario is that the "disk" will be ready and mounted even while the on-board file system is accessing it. I am considering having a lock-out mechanism that can be manually set/cleared for a MSCDLUN. This provides the owner of the lun the ability to simulate the underlying disk being unaccessible to the mass storage interface.


-Tyler

Spencer

Posted
8 years ago

Tyler,

The update sounds good. As an aside, I was noticing that an un-supported command would induce an endpoint stall. I noticed that I was getting a PREVENT ALLOW MEDIUM REMOVAL command and responding with an unsupported response and then a stall.

I've added a hack to not stall on PREVENT ALLOW MEDIUM REMOVAL and it drastically sped up the time it took for windows to recognize the mass storage device.

I'll mock up some test code for the "NOT READY" and see how it responds. Looking forward to the update on your end.


Thanks so much,

-Spencer

Spencer

Posted
8 years ago

Adding the MEDIUM_NOT_PRESENT response with the FS mounted by firmware does the trick. I'm still fighting windows with the recovery time when it finally becomes present but my issue is definitely solved at the moment.


Thanks,

-Spencer

Tyler

DZX Support
Posted
8 years ago

The latest release, version 16.1.7, is now available and contains the ability to enable/disable a logical unit with a mass storage interface. See function MSCD_SetEnabled(). When the unit is disabled, it will be presented to the host as if the media is not present. It also includes  a fix so that USBD_IsConnected() does not stay TRUE after being configured by a host.


The disk media drivers now allow for a custom handler function to be provided for the checking of media present using DISK_SetMediaPresentHandler(). This is another way to control whether the host can access the disk media.


There are quite a few other changes to the mass storage class in this release to get better adherence to the mass storage specification. Mostly more error checking and proper handling of stalling/unstalling of endpoints when needing to terminate data transfers.


-Tyler

 

Spencer

Posted
8 years ago

Thanks Tyler,


Will download the latest and get it swapped in.

Spencer

Posted
8 years ago

I was able to swap in the 16.1.7 Kernel. This medium present doesn't work in my case because the same medium present call is made in diskio whether my firmware is accessing the disk or windows. I don't get to differentiate if it's present for me to use or for windows to use (which makes perfect sense). Had to switch thinking to imagine an SD card use. You'd want this exact behavior.


The MSCD_Enable() call works perfect for my application. Thanks! Case closed for this one!


Reply