Interfacing USB mass storage devices (aka USB flash drives)

Inspired by this thread I've been working on making mbed read USB sticks. After making an initial port of NXP's USBHostLite example, I got stuck since my mbed was an older, LPC2368 model, and did not have USB host. However, kind people helped me to get a 1768 unit much faster than Mouser could get it in stock, and with the help of Ilya I I finally have a working example that plugs into the standard FATFileSystem.

Usage

You can try my code by importing this project: MSCUsbHost

To use it in your program, you will need to copy everything from the USBHostLite folder, and also MSCFileSystem.h/cpp files.

Usage is similar to LocalFileSystem or SDFileSystem classes:

#include "mbed.h"
#include "MSCFileSystem.h"

MSCFileSystem msc("msc"); // Mount flash drive under the name "msc"

int main()
{
    printf("\nTesting file write:\n");
    FILE *fp = fopen( "/msc/msctest.txt", "w");
    if ( fp == NULL )
    {
        error("Could not open file for write\n");
    }
    fprintf(fp, "Hello mass storage!");
    fclose(fp); 
    printf("\n - OK\n");
}

Connection

Flash drives, as many unpowered USB devices, require 5V on their VBUS pin to work. You can connect it to mbed's Vu output, however you should remember that Vu is powered from mbed's USB connector. If you use independent power source connected to Vin, you'll need to power the flash drive separately with regulated 5V.

D-, D+ and ground should be connected to the corresponding pins on mbed.

Here's what the sample program outputs for my memory stick:

================================
USB Mass storage demo program for mbed LPC1768
================================

In Host_Init
Initializing Host Stack
Host Initialized
Connect a Mass Storage device
Mass Storage device connected
Successfully initialized mass storage interface; 511997 blocks of size 512
Inquiry reply:
Peripheral device type: 00h
        - Direct access (floppy)
Removable Media Bit: 1
ANSI Version: 00h
ECMA Version: 00h
ISO Version: 00h
Response Data Format: 01h
Additional length: 1Fh
Vendor Information: 'WIBU -  '
Product Identification: 'CodeMeter-StickM'
Product Revision: 'v1.0'

List of files on the flash drive:
 - IO.SYS
 - MSDOS.SYS
 - COMMAND.COM
 - autoexec.bat
 - config.sys
 - himem.exe
 - ISSDFUT.EXE
 - BOOTLOG.TXT
 - more.exe
 - README.TXT
 - BOOTLOG.PRV
 - msctest.txt

Testing file write:

 - OK

Testing file read:

 - OK, read string: 'Hello mass storage!'

Notes

Insertion/removal detection is not working. The USB drive should be connected before you try to access it.

Remarks

While making this stuff work, I found some things that are not explained sufficiently (if at all) in the user manual. Maybe this will help other people working with the LPC17xx's USB host.

1) Port 1 must be configured as a host using the (underdocumented in the LPC17xx UM) PORT_FUNC field in the OTGStCtrl register. It is described in a somewhat more detail in the LPC23xx manual:

In short, you need to set bit 0 to 1 to enable host operation on port U1. Both 0b01 and 0b11 worked for me.

2) to access that register, you must set PORT_SEL_EN (aka OTG_CLK_EN) bit in the OTGClkSt register beforehand. It can be turned off afterwards.

3) in addition to the host clock (HOST_CLK_EN), you also need to enable the AHB clock (AHB_CLK_EN) in the OTGClkSt register. I guess it's kinda obvious in the hindsight (since USB needs AHB to work), but it's not mentioned explicitly anywhere.


41 comments

27 Jan 2010

Very impressive detective work! It is not a trivial manual to decipher.

I tried your program and it works pretty well. It gives me a couple of warnings in the printout, but it does not prevent from writing and reading a file.

What do you think is needed for insertion/removal detection to work? Is it something that should be handled in the ISR and given to a callback function?

27 Jan 2010

What warnings are you getting?

I haven't looked at the code closely yet, so I can't say much about detection. I only know it's not working currently :)

27 Jan 2010

I've never done a USB Host interface, but instinct tells me there ought to be a few Rs and Cs to correctly terminate the USB connection. Is there a published schematic with values?

27 Jan 2010

The schematic is here, see page 2.

27 Jan 2010

The warnings are probably due to some difference in the specific USB flash drive I'm using:

 

In Host_Init
Initializing Host Stack
Host Initialized
Connect a Mass Storage device
Mass Storage device connected
Successfully initialized mass storage interface; 1023999 blocks of size 512
Inquiry reply:
Peripheral device type: 00h
        - Direct access (floppy)
Removable Media Bit: 1
ANSI Version: 02h
        - warning! must be 0
ECMA Version: 00h
ISO Version: 00h
Response Data Format: 02h
        - warning! should be 1
Additional length: 1Fh
Vendor Information: 'Pretec  '
Product Identification: '512MB           '
Product Revision: '2.00'

List of files on the flash drive:
... 

 

 

27 Jan 2010

Ah, interesting. Looks like your drive supports newer spec that what's available on the USB site. I guess I should make those checks to be "equals or greater", instead of "equals".

27 Jan 2010

Hi Igor,

I did not mean the mbed schematics, but just the details of connecting the new Host USB connector to D- and D+. I would expect a resistor in between each mbed D pin and the USB connector pin, and a cap to ground from each active connector pin. But as I said I've never done a Host USB port before

27 Jan 2010

If you check the schematics, you will see the resistors and caps you're talking about. Since they're already present on the mbed board, I guess no extra ones are necessary. I connected directly to the pins.

27 Jan 2010

I did not realize that the mbed D- D+ pins are at connector end of  the series resistors.

Thanks

06 Apr 2010 . Edited: 06 Apr 2010

I've imported the code into my compiler, then compiled and stored on my mbed. When I reset my mbed, I get a short serial output followed by flashing siren lights:

================================
USB Mass storage demo program for mbed LPC1768
================================

In Host_Init
Initializing Host Stack
Host Initialized
Connect a Mass Storage device
ERROR: In Host_EnumDev at Line 385 - rc = -1
Could not enumerate device: -1
List of files on the flash drive:
Could not open d

Any idea why it cannot enumerate the device? What can I do to fix it?

 

The line in question (Line 385 in usbhost_lpc17xx.c) is this block of code:

rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 8);
if (rc != OK) {
PRINT_Err(rc);
return (rc);
}

Could it be an issue with my USB drive?

Thanks :)

04 Nov 2010 . Edited: 04 Nov 2010

FYI - I've encountered the identical issue. I tried 4 different types of USB stick drives all with the same response.

Assuming the code was correct I fiddled with the USB connections.  This seemed to do the trick.

 

17 Nov 2010

Have you tried this with a USB hard drive (not a flash stick)?

20 Dec 2010

Wanting to use this code for logging a large amount of data, but wanted to know if I'm continuously writing to the flash disk - what would be the best way to go about doing this without wearing out the flash quickly ? I guess could put in a RAM buffer and then write a large block at a time, but then obviously this may be quite time consuming so ideally would like to log as AD samples are taken...Any ideas would be appreciated. Thanks!

31 Dec 2010

hi , i tried using the code . but my mbed is just flashing led's ... can anyone help me with the connection schematics please . thanks !

18 Jan 2011

 

Pleasde help in using the schematics. I am getting some error

26 Jan 2011

I noticed that Cool components has a nice USB A breakout board, http://www.coolcomponents.co.uk/catalog/product_info.php?products_id=556

They seem to be a bit hard to find elsewhere.

31 Jan 2011 . Edited: 01 Feb 2011

 

I have pulled down D+ and D- with 15K resistors for using as usb host, Power for USB I am taking from VU, But When I conneted to PC using USB connector MBED board is not detected by PC. MBED board is getting powered up. But it is not detected as Mass Storgae device Please help me to resolve this.

Jammulak.

01 Feb 2011

HI,

 

How to load bin file into Mbed when using USB Host functionality. When D+ and D-  are pulled down with 15K resistors MBED is not detected as Storage device. Please help

01 Feb 2011

This page is about connecting USB devices to mbed. If you're having problems with programming mbed itself, please post in the forums.

01 Feb 2011

Hi Kiran,

If you are having problems with the mbed interface/mbed disk appearing whilst trying to use the LPC1768 USB interface on the D+ D- pins, make sure you really are connecting to those pins and not IF+/IF-. The behaviour you describe could be explained if you were connecting something to one or both of the IF+ and IF- pins; these are reserved and should not be connected, else the mbed interface may not function correctly.

Simon

04 Feb 2011 . Edited: 07 Feb 2011

Thanks Simon, it helped me to resolve the issuse.

When I am testing MSCUSBhost project I am getting up to Host initialization.

 ================================
USB Mass storage demo program for mbed LPC1768
================================

In Host_Init
Initializing Host Stack
Host Initialized
Connect a Mass Storage device

 

I am getting serial messages upto above. I am testing with mobile selected in Mass storgae mode. What could  be the problem

My USB device detection is very inconsistent. I have used some debug messages in USB isr but, those debug messgaes are not printed . Device is deteced once in 10 times.  Please help me.

 

 

 

26 May 2011

Hello everyone,

I am using Igor's libraries and can write to different kind of USB flash drives.

The only problem I'm having is when I'm trying to write accelerometer data (800Hz) from 3-axis the file writing line is holding my code resulting in some data loss. I tried to store data in FIFO of accelerometer and then write them in a for loop so the USBfd have some time to process the data. Dropping the sample rate to lower value also didn't help. Tried different FIFO sizes but checking the interrupt pin it seems whatever I'm doing the file writing holds the code for around 240ms time to time. (repeating every 3s if FIFO size is 25, each axis value stored in 4byte float separated by tab)

I'am guessing it has to do something with the block size reaching a certain value and the USBfd needs that time to process the data.

The flash drive has been checked and should be able to reach around 9Mb/s writing speed.

 

Any suggestion how to overcome my problem?  Thanks in advance!

26 May 2011 . Edited: 26 May 2011

Don't write in small chunks, write into a buffer then write that to the flash drive. USB can have pretty good throughput but the latency is usually quite bad.

Note that Stéphane Bausseron found some bugs in the FATFilesystem that I use when writing more than 512 bytes: http://mbed.org/forum/mbed/topic/2273/

26 May 2011

Thanks for the quick reply I will look into this!

26 May 2011

I'm using the latest FATFileSystem where i have no access to the diskio.c file but since it's a later version I'am hoping that has been modified by now.

 

Your other suggestion about the larger chunks has some problems for me to. I have to collect data for a longer period of time so I would need two buffers one to fill until the other one can be written to the USBfd. The problem is (if I am wright) I can't do these functions in parallel.

26 May 2011

Try this: use a Ticker to run a periodic task which would check how much data is in the buffer and flush when you have enough or when some time passed since the last flush. You might have to take some care to protect the buffer object from being modified simultaneously in the main program and the Ticker callback.

26 May 2011

It is actually a good idea but I am having to short time to try this. Thinking of trying to recover the signal using the Real-Time Clock. Thanks for your advice anyway might be a good solution for a later project.

03 Jun 2011 . Edited: 03 Jun 2011

Hello,

Let me just ask something to ensure I understand it right. So whenever I write anything to the USB flash drive (or even SD-card), using command like fprintf() the mbed first just collects 512byte big data in its memory then when the block is ready then it sends it to the USB flash drive (or even SD-card)? Unless the data never gets that big and that case the mbed fills the rest with some dummy variable?

28 Jul 2011 . Edited: 28 Jul 2011

I am hoping to use this program to allow my mbed to store the data of my DUT into a USB stick. My mbed would not be connected to any computer during the experimentation. Would this program still work?

The mbed would be recording voltage and current reading within the range allowed by the mbed.

After the experimentation, I would not be connecting my mbed to the pc to transfer data but instead use the USB stick. The reason why I cannot connect my mbed directly to a computer is due to safety reason as the DUT cannot leave the lab and since the mbed is connected to it, it could not be removed.

11 Aug 2011

hello,I am using this demo program. I added every .cpp\.h file in "USBHostLite" and "MSCFileSystem.h\.cpp". The compiler I am using is keil, during building the target, there always exist many errors, listed below: .\mbed\FileHandle.h(19): error:  #20: identifier "namespace" is undefined. I can't fix this bug, pls help.Thanks for your help.

 

30 Nov 2012
user jim hamblen wrote:

I noticed that Cool components has a nice USB A breakout board, http://www.coolcomponents.co.uk/catalog/product_info.php?products_id=556

They seem to be a bit hard to find elsewhere.

Thanks for the picture. I'm using a PCB-mount connector and it was handy to have something to confirm the pinout against. It was that or wikipedia and on there they don't make it clear which way they are "looking".

15 Dec 2012

where i have to connect the D+ and D- pins of usb to mbed in this programme?

31 Dec 2012

I've got this going fine with one USB memory stick (thanks). Now I want to do it with two devices. Two questions arise:

1) On the face of it, the code is all written on the assumption that there will only ever be one device attached. Is there a good reason for this? It should be possible to enumerate through all the attached devices, but it looks like quite a rewrite, and much of the code is only lightly commented.

2) I can't find any definitive statement about whether one can connect two USB devices in parallel. As it's a master-slave device, I'd have thought it should work. Or do I need to use a hub? And what goes in a hub?

The two devices will initially both be mass storage, though one might be something else eventually.

14 Feb 2013

Hello Sir, Please help me out in reading USB Mass storage device using mbed LPC1768. I have been using Igor skochinsky's code to read USB Mass storage Device using mbed LPC 1768 and it was working fine earlier(a month before). The code was able to display the USB enumeration data, list of files in USB mass storage device,read and write acknowledgement data. But now I am using the same code to read the USB,but I am unable to get the list of files in USB. I am just getting the following output in hyperterminal

 

 

=================================

USB Mass Storage Demo Program for mbed LPC1768

=================================

 

Reading USB memory

 

In Host_Init

Initialising Host Stack

Host Initialised

 

Connect a Mass Storage Device

 

I tried with the couple of other mass storage devices too,.its not working,.

Please help me out

 

Prashanth Shetty

prashanthshetty149@yahoo.com

16 Feb 2013 . Edited: 16 Feb 2013

I would be obliged if someone could look into this, too.  I don't think Prashanth has a hardware problem because my code started behaving the exact same way recently (both this and another USB application I've been using leveraging this library).  Oddly the code stops at the "Connect a Mass Storage Device" same as Prashant when the thumb drive is inserted but if the drive is removed (or wasn't there to begin with) the program continues and fails enumeration (see below).  This used to work.  I didn't update the library but I did recompile.  When I load an old bin file I compiled weeks ago, that works.

 

================================

USB Mass storage demo program for mbed LPC1768

================================

 

In Host_Init

Initializing Host Stack

Host Initialized

Connect a Mass Storage device  [Note(*) program freezes here until the thumbdrive is removed]

ERROR: In Host_EnumDev at Line 386 - rc = -1

ERROR: In Host_EnumDev at Line 387 - rc = 15856

Could not enumerate device: -1

 

List of files on the flash drive:

Could not open d

16 Feb 2013 . Edited: 16 Feb 2013

Nevermind.  Now it's working again for me.  Not sure what changed.  Probably flakey wiring and bad luck when it working briefly when I tried the old version coupled with similar sightings from others.

10 Mar 2013

user Tick Tock wrote:

Nevermind.  Now it's working again for me.  Not sure what changed.  Probably flakey wiring and bad luck when it working briefly when I tried the old version coupled with similar sightings from others.

hello Tick Tock,i tried with the old version too.its not working,.

08 Jan 2014

Grey  wrote:

I've imported the code into my compiler, then compiled and stored on my mbed. When I reset my mbed, I get a short serial output followed by flashing siren lights:

================================
USB Mass storage demo program for mbed LPC1768
================================

In Host_Init
Initializing Host Stack
Host Initialized
Connect a Mass Storage device
ERROR: In Host_EnumDev at Line 385 - rc = -1
Could not enumerate device: -1
List of files on the flash drive:
Could not open d

Any idea why it cannot enumerate the device? What can I do to fix it?

 

The line in question (Line 385 in usbhost_lpc17xx.c) is this block of code:

rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 8);
if (rc != OK) {
PRINT_Err(rc);
return (rc);
}

Could it be an issue with my USB drive?

Thanks :)

I have this same problem, I tried several different drives but the all come up with the same error.

 

did anybody figure it out?

08 Jan 2014

I would start by having a look at: http://mbed.org/handbook/USBHostMSD, that is way more recent.

14 Jul 2014

Good morning, I have a crazy situation,

 

My MBED, in a coolcomponents dev board, AND my own PCB,

can read.write to the USB Memory stick,  **AFTER PROGRAMMING**

but when I power cycle MY PCB, (two of them) USB read.write stopps working !!

wheras, the 'real MBED' will work ??

 

The only thing I can think of is:

 

something happening in the MAGIC cchp?

 

Can anyone help, Realy need to get this going..

 

 

Cheers

 

**Ceri

 

 

 

printout from working boot & faild boot ...

//working

USB Mass storage demo program for mbed LPC1768

From: http://mbed.org/users/igorsk/code/MSCUsbHost/file/95e55809ecdb/main.cpp

================================

In Host_InitInitializing Host StackHost InitializedConnect a Mass Storage deviceMass Storage device connectedSuccessfully initialized mass storage interface; 30261247 blocks of size 512

Inquiry reply:nPeripheral device type: 00hn - Direct access (floppy)nRemovable Media Bit: 1nANSI Version: 02hn - warning! must be 0nECMA Version: 00hnISO Version: 00hnResponse Data Format: 02hn - warning! should be 1nAdditional length: 1FhnVendor Information: 'Imation 'nProduct Identification: 'Nano Pro        'nProduct Revision: 'PMAP'nIn Host_InitInitializing Host StackSpurious status change (connected)?Host InitializedConnect a Mass Storage deviceMass Storage device connectedSuccessfully initialized mass storage interface; 30261247 blocks of size 512

Inquiry reply:nPeripheral device type: 00hn - Direct access (floppy)nRemovable Media Bit: 1nANSI Version: 02hn - warning! must be 0nECMA Version: 00hnISO Version: 00hnResponse Data Format: 02hn - warning! should be 1nAdditional length: 1FhnVendor Information: 'Imation 'nProduct Identification: 'Nano Pro        'nProduc

List of files on the flash drive:

 

//broken

USB Mass storage demo program for mbed LPC1768

From: http://mbed.org/users/igorsk/code/MSCUsbHost/file/95e55809ecdb/main.cpp

================================

In Host_InitInitializing Host StackHost InitializedConnect a Mass Storage deviceMass Storage device connectedSuccessfully initialized mass storage interface; 30261247 blocks of size 512

Inquiry reply:nPeripheral device type: 00hn - Direct access (floppy)nRemovable Media Bit: 1nANSI Version: 02hn - warning! must be 0nECMA Version: 00hnISO Version: 00hnResponse Data Format: 02hn - warning! should be 1nAdditional length: 1FhnVendor Information: 'Imation 'nProduct Identification: 'Nano Pro        'nProduct Revision: 'PMAP'nIn Host_InitInitializing Host StackSpurious status change (connected)?Host InitializedConnect a Mass Storage deviceMass Storage device connectedSuccessfully initialized mass storage interface; 30261247 blocks of size 512

Inquiry reply:nPeripheral device type: 00hn - Direct access (floppy)nRemovable Media Bit: 1nANSI Version: 02hn - warning! must be 0nECMA Version: 00hnISO Version: 00hnResponse Data Format: 02hn - warning! should be 1nAdditional length: 1FhnVendor Information: 'Imation 'nProduct Identification: 'Nano Pro        'nProduc

List of files on the flash drive:

 

Error !! Could not open directory!  [E1]

 

Testing file write:

05 Apr 2016 . Edited: 05 Apr 2016
Hi, I'm trying to use this library to log data on an usb stick. Until I declare file descriptor local to the function it works correctly, when I declare the file descriptor global or static (I open the file at the beginning of program, then call the function to write data in other part of program), i get an error. //Works void LogData() { FILE *FileLog2; FileLog2 = fopen("/msc/FileLog.txt", "a+"); } //Not works FILE *FileLog2; void LogData() { FileLog2 = fopen("/msc/FileLog.txt", "a+"); } Errors: In Host_Init Initializing Host Stack Host Initialized Connect a Mass Storage device ERROR: In Host_EnumDev at Line 386 - rc = -1 Could not enumerate device: -1

You need to log in to post a comment