The USBMSD interface is used to emulate a mass storage device over USB. You can use this class to store or load data to and from a storage chip (SDcard, flash,...). This class implements the MSD protocol and calls pure virtual functions such as disk_initialize, disk_write or disk_read to interact with a storage chip. More information on how to use this class with your own chip can be found at the end of this document.
The USBMSD class implements the MSD protocol. It permits to access a memory chip (flash, sdcard,...)
from a computer over USB. But this class doesn't work standalone, you need to subclass this class
and define pure virtual functions which are called in USBMSD.
You have to inherit from USBMSD and define ALL the following pure virtual functions:
virtual int disk_read(uint8_t * data, uint64_t block): function to read a block
virtual int disk_write(const uint8_t * data, uint64_t block): function to write a block
virtual int disk_initialize(): function to initialize the memory
virtual uint64_t disk_sectors(): return the number of blocks
virtual uint64_t disk_size(): return the memory size
virtual int disk_status(): return the status of the storage chip (0: OK, 1: not initialized, 2: no medium in the drive, 4: write protection)
All functions names are compatible with the fat filesystem library. So you can imagine using your own class with USBMSD and the fat filesystem library in the same program. Just be careful because there are two different parts which will access the sd card. You can do a master/slave system using disk_status().
Once these functions defined, you can call connect() (at the end of the constructor of your class for instance) of USBMSD to connect your mass storage device. connect() will first call disk_status() to test the status of the disk. If disk_status() returns 1 (disk not initialized), then disk_initialize() is called. After this step, connect() will collect information such as the number of blocks and the memory size.
A class example which inherits from USBMSD has been developed in order to access an SD card. You can follow this example and write your own class to access your storage chip.
Thanks for making this code available! I just tried it out and it worked but was EXTREMELY slow.
A 2Meg file took over 5 min to write and about 40 sec to read. Do you know why it is so slow.
I don't believe the SPI bus should be that slow unless you are using a very slow clock.
Hi Samuel,
Thanks for making this code available! I just tried it out and it worked but was EXTREMELY slow.
A 2Meg file took over 5 min to write and about 40 sec to read. Do you know why it is so slow.
I don't believe the SPI bus should be that slow unless you are using a very slow clock.
I tried this morning with a 4.6 Mb file and a SPI clock at 5MHz (same spi clock as in the example). It took me 55s to write it and 20s to read it. The time to write one block (512B) on my SD card is approximately 5ms . After I lose some time to buffer one block because I am receiving a block packets by packets. This operation takes me 0.5ms.
So for a 4.6Mb file, the theoretical time to write it with these previous values is: 4600000/512(size of 1 block)*5.5ms = 50s. We are not far away from 55s.
So it's quite slow but most of the time is lost in the disk_write method. More specifically, most of the time is lost because the program is waiting the end of the writing (while(_spi.write(0xFF) == 0);).
Sam
Hi David,
I tried this morning with a 4.6 Mb file and a SPI clock at 5MHz (same spi clock as in the example). It took me ~55s to write it and ~20s to read it. The time to write one block (512B) on my SD card is approximately 5ms . After I lose some time to buffer one block because I am receiving a block packets by packets. This operation takes me ~0.5ms.
So for a 4.6Mb file, the theoretical time to write it with these previous values is: 4600000/512(size of 1 block)*5.5ms = ~50s. We are not far away from 55s.
So it's quite slow but most of the time is lost in the disk_write method. More specifically, most of the time is lost because the program is waiting the end of the writing (while(_spi.write(0xFF) == 0);).
Sam
I just ran some more tests. Tests were done under windows7 and windows XP with same results for a 2GB memory card.
Tests were also done with FAT16 and FAT32 format with same results.
4.2MB file write: 2 min 24 s (144s)
4.2MB file read: 35s
I am not sure why I am getting different results from yours. What size card are you using, what file format and which operating system?
By the way, are you making use of the on-board mass storage class in ROM on the device? When I look at your code, it looks like the mass storage class is written in software but the specs on the LPC11U24 say that MSC is in ROM.
Hi Samuel,
I just ran some more tests. Tests were done under windows7 and windows XP with same results for a 2GB memory card.
Tests were also done with FAT16 and FAT32 format with same results.
4.2MB file write: 2 min 24 s (144s)
4.2MB file read: 35s
I am not sure why I am getting different results from yours. What size card are you using, what file format and which operating system?
By the way, are you making use of the on-board mass storage class in ROM on the device? When I look at your code, it looks like the mass storage class is written in software but the specs on the LPC11U24 say that MSC is in ROM.
I am using a micro SD (Transcend 1Gb) card. The format is FAT16 on windows 7 32bits. Do you have something to measure the time spent in disk_write() ? Like a logic analyzer.
No USBMSD does not use the code in ROM.
Hi David,
I am using a micro SD (Transcend 1Gb) card. The format is FAT16 on windows 7 32bits. Do you have something to measure the time spent in disk_write() ? Like a logic analyzer.
No USBMSD does not use the code in ROM.
Thanks for your efforts with this. I'm trying to use this from a Mac, although I've also tried a PC, and there's a problem during initialisation. If I add some debug in USBMSD::CBWDecode() I find that it is called repeatedly with the following SCSI commands:
03 REQUEST_SENSE
00 TEST_UNIT_READY
1e MEDIA_REMOVAL
03 REQUEST_SENSE
25 READ_CAPACITY
the 03-25 sequence is repeated 7 times, and the whole lot starts over.
I first saw this trying to access an SD card, so I've created a very simple subclass of USBMSD which creates a RAM disk of 32 512 byte buffers and this shows the same problem.
I should add that the above sequence is preceded by:
00 TEST_UNIT_READY
12 INQUIRY
00 TEST_UNIT_READY
12 INQUIRY
Any thoughts?
Steve
Hi Samuel,
Thanks for your efforts with this. I'm trying to use this from a Mac, although I've also tried a PC, and there's a problem during initialisation. If I add some debug in USBMSD::CBWDecode() I find that it is called repeatedly with the following SCSI commands:
03 REQUEST_SENSE
00 TEST_UNIT_READY
1e MEDIA_REMOVAL
03 REQUEST_SENSE
25 READ_CAPACITY
the 03-25 sequence is repeated 7 times, and the whole lot starts over.
I first saw this trying to access an SD card, so I've created a very simple subclass of USBMSD which creates a RAM disk of 32 512 byte buffers and this shows the same problem.
I should add that the above sequence is preceded by:
00 TEST_UNIT_READY
12 INQUIRY
00 TEST_UNIT_READY
12 INQUIRY
Any thoughts?
Steve
Looks like the MEDIA_REMOVAL returning an error was the problem. My 16K RAM disk now works, although only as a raw device because it's too small to be partitioned!
Now to get the SD card working, which is awkward as it's HC.
Steve
Looks like the MEDIA_REMOVAL returning an error was the problem. My 16K RAM disk now works, although only as a raw device because it's too small to be partitioned!
Now to get the SD card working, which is awkward as it's HC.
Steve
It's weird that it didn't work on Mac OS because I remember having tested it.
Otherwise, nice job! You can either publish your code (right click on your program and publish program) on the mbed website and send me the link to access the code or you can send me your program.
Sam
Hi Steve,
It's weird that it didn't work on Mac OS because I remember having tested it.
Otherwise, nice job! You can either publish your code (right click on your program and publish program) on the mbed website and send me the link to access the code or you can send me your program.
Sam
This is OS X Lion, so that may have made a difference.
Are you also responsible for the USBMSD_SD class? I've modified that so that disk_size is no longer used. Only dealing in block sizes and counts means that handling >4G cards simply requires changing the USBMSD members of addr and MemorySize to uint64_t.
Steve
Hi Sam,
This is OS X Lion, so that may have made a difference.
Are you also responsible for the USBMSD_SD class? I've modified that so that disk_size is no longer used. Only dealing in block sizes and counts means that handling >4G cards simply requires changing the USBMSD members of addr and MemorySize to uint64_t.
Steve
I notched that only a limited number of endpoints were supported with a TODO comment to add support for the others. I've switched the USBMSD over to use EP5, which works, so as not to clash with the serial driver, so I can use both at once, but alas this fails, I suspect because whilst there may be many instances of USBDevice, there should only be implementation of the USBBusInterface, and I believe we're getting one of those per device. Is this something that you're working on?
The other problem I'm having is switching between the USB access to my SD card and a local filesystem. Both work in separate builds, but the USBMSD_SD support is only working if a global instance is declared. I was intending instantiating the device only when needed, and then instantiating the local FAT filesystem at other times; I'd not expect then to co-exist.
Steve
I notched that only a limited number of endpoints were supported with a TODO comment to add support for the others. I've switched the USBMSD over to use EP5, which works, so as not to clash with the serial driver, so I can use both at once, but alas this fails, I suspect because whilst there may be many instances of USBDevice, there should only be implementation of the USBBusInterface, and I believe we're getting one of those per device. Is this something that you're working on?
The other problem I'm having is switching between the USB access to my SD card and a local filesystem. Both work in separate builds, but the USBMSD_SD support is only working if a global instance is declared. I was intending instantiating the device only when needed, and then instantiating the local FAT filesystem at other times; I'd not expect then to co-exist.
Steve
You cannot instantiate two USB devices. But you can have a USB device with several interfaces (Serial and MSD for instance). For that you have to modify the configuration descriptor to have several interfaces on it.
What is your code for the USB and the filesystem? Do you have USBMSD_SD which inherits from FATFileSystem and USBDevice ?
Sam
Hi Steve,
You cannot instantiate two USB devices. But you can have a USB device with several interfaces (Serial and MSD for instance). For that you have to modify the configuration descriptor to have several interfaces on it.
What is your code for the USB and the filesystem? Do you have USBMSD_SD which inherits from FATFileSystem and USBDevice ?
Sam
Has anyone managed to get a FLASH Memory chip to work?
I realy need to get my own 'filesystem' working.
With the same features as the 'majic' chip.
Idealy for both LPC1768 & LPC11U24
Cheers
Ceri
Has anyone managed to get a FLASH Memory chip to work?
I realy need to get my own 'filesystem' working.
With the same features as the 'majic' chip.
Idealy for **both **LPC1768 & LPC11U24
Cheers
**Ceri
Your comment about having a single config descriptor makes a lot of sense! If I were to create a class which inherited from both USBSerial and USBMSD I'd end up with two USBDevices though right? Do you have a pattern for combining several functions into a single device?
I'd like to send you my code changes to get >4G working under OS X Lion. Under a dozen lines of changed code. I'm new to this site... it is possible to PM you?
Steve
Hi Sam,
Thanks for your feedback.
Your comment about having a single config descriptor makes a lot of sense! If I were to create a class which inherited from both USBSerial and USBMSD I'd end up with two USBDevices though right? Do you have a pattern for combining several functions into a single device?
I'd like to send you my code changes to get >4G working under OS X Lion. Under a dozen lines of changed code. I'm new to this site... it is possible to PM you?
Steve
OK, found the PM button... should have looked harder!
In summary then, what I want to be able to do, effectively what the mbed's normal USB interface does, is to have a USB serial connection that's up all the time for use as a console, and then to have a USB MSD device to transfer data to/from the device, but I also want to be able to access that filesystem locally. Given that both the MSD and FAT filesystems access the storage (SD) device at the block level, the two can't be running at the same time, so as with the LocalFileSystem class which uses the 2Mbytes of onboard FLASH storage, I fully expect the MSD device to be unmounted when I access the SD locally.
Any pointers as to how to have both serial and MSD USB endpoints co-exist on the same device, and how to take the MSD device on/offline (connect()/disconnect()?) without upsetting the USBSerial device, would be most helpful.
Steve
OK, found the PM button... should have looked harder!
In summary then, what I want to be able to do, effectively what the mbed's normal USB interface does, is to have a USB serial connection that's up all the time for use as a console, and then to have a USB MSD device to transfer data to/from the device, but I also want to be able to access that filesystem locally. Given that both the MSD and FAT filesystems access the storage (SD) device at the block level, the two can't be running at the same time, so as with the LocalFileSystem class which uses the 2Mbytes of onboard FLASH storage, I fully expect the MSD device to be unmounted when I access the SD locally.
Any pointers as to how to have both serial and MSD USB endpoints co-exist on the same device, and how to take the MSD device on/offline (connect()/disconnect()?) without upsetting the USBSerial device, would be most helpful.
Steve
I am currently designing a small system, of my own, with bair parts (LPC1768 & LPC11U24)
and I want All of the above, but an optional BASIC HID (as well)
is my end target.
Keyboard & mouse would be amasing as well :)
Cheers
Ceri
Me too **Please .. **
I am currently designing a small system, of my own, with bair parts (LPC1768 & LPC11U24)
and I want All of the above, but an optional BASIC HID (as well)
is my end target.
Keyboard & mouse would be amasing as well :)
Cheers
**Ceri
I started making all the changes I recognised needed doing, such as adding EP5 usage, and merging the USBMSD, USBCDC and USBSerial classes into one and then discovered http://mbed.org/users/okini3939/programs/USB_CDC_MSD_Hello/m2ogop which is where somebody has done just that! This still needs the fix in USBMSD to handle MEDIA_REMOVAL to work on OS X Lion, but it seems just the ticket. It also doesn't handle 64 bit addressing of large memory devices but that was also easily fixed.
That it was necessary to merge these classes is a sad reflection on C++ (Java would have made this much easier!), and shows that a USBDevice class is needed to which USBEndpoint objects can be attached before connecting, rather than subclassing the USBDevice.
Steve
I started making all the changes I recognised needed doing, such as adding EP5 usage, and merging the USBMSD, USBCDC and USBSerial classes into one and then discovered http://mbed.org/users/okini3939/programs/USB_CDC_MSD_Hello/m2ogop which is where somebody has done just that! This still needs the fix in USBMSD to handle MEDIA_REMOVAL to work on OS X Lion, but it seems just the ticket. It also doesn't handle 64 bit addressing of large memory devices but that was also easily fixed.
That it was necessary to merge these classes is a sad reflection on C++ (Java would have made this much easier!), and shows that a USBDevice class is needed to which USBEndpoint objects can be attached before connecting, rather than subclassing the USBDevice.
Steve
First of all, I wish to thank you for writing this awesome library ! This is a great starting point for my project which involves using your implementation of the USBMSD class.
I now have a question regarding your USBMSD class, which might be very stupid (please bear with me, since I am very new to MBED).
I imported your 'USBMSD_SD_HelloWorld' program into the IDE and it compiles fine.
However, I can't see the header file ("USBMSD_SD.h") that your code uses. Am I correct to assume that I can't view any of the header files within the IDE? Do I always have to view the header file by pointing the browser to the SVN trunk ?
Thanks in advance for your time!
regards,
Seemanta
First of all, I wish to thank you for writing this awesome library ! This is a great starting point for my project which involves using your implementation of the USBMSD class.
I now have a question regarding your USBMSD class, which might be very stupid (please bear with me, since I am very new to MBED).
I imported your 'USBMSD_SD_HelloWorld' program into the IDE and it compiles fine.
However, I can't see the header file ("USBMSD_SD.h") that your code uses. Am I correct to assume that I can't view any of the header files within the IDE? Do I always have to view the header file by pointing the browser to the SVN trunk ?
Thanks in advance for your time!
regards,
Seemanta
You can see all the source code by right clicking on USBMSD_SD for instance and then on Edit library. You should then be able to see the source code.
Sam
Hi Seemanta,
Nice to see that USBMSD is used :)
You can see all the source code by right clicking on USBMSD_SD for instance and then on Edit library. You should then be able to see the source code.
Sam
Hi Sam,
I made all the connections as shown in the image above, but my code is not working. When I connect my USB cable to the mini-USB connector, I get a pop up at the lower right hand corner of my screen saying, "Windows does not recognize this USB device".
I am using Windows 7. And the connections are proper to the best of my knowledge. I also checked the integrity of my SD card and the breakout boards; they are all fine.
What could you think the problem be ? Is there some idiosyncrasy of the USBMSD library that I don't know of ?
I would really appreciate your help in this regard.
Seemanta
Hi Sam,
I made all the connections as shown in the image above, but my code is not working. When I connect my USB cable to the mini-USB connector, I get a pop up at the lower right hand corner of my screen saying, "Windows does not recognize this USB device".
I am using Windows 7. And the connections are proper to the best of my knowledge. I also checked the integrity of my SD card and the breakout boards; they are all fine.
What could you think the problem be ? Is there some idiosyncrasy of the USBMSD library that I don't know of ?
I would really appreciate your help in this regard.
//Seemanta
if You load example USBMSD_SD_HelloWorld, compile and copy to mbed. Device should be recognised and driver for device is being installed.
If this does not happen, check if D+ and D- for USB connector aren't swapped. Sometimes it hapenned to me if I swapped those wires, device wasn't recognized.
Check If You didn't edited VID and PID in constructor of USBMSD?
I figured out that windows "associates" driver for each VID & PID so once I made USB mouse example and tested in windows and then built usb keyborad with same VID & PID, windows did not recognized as driver for USB mouse was associated with that VID and PID.
BTW are You using WIN7 32bit or 64bit?
Is mbed powered via its mini B USB connector or via USB device connector on breakout board?
Hello Seemanta,
if You load example USBMSD_SD_HelloWorld, compile and copy to mbed. Device should be recognised and driver for device is being installed.
If this does not happen, check if D+ and D- for USB connector aren't swapped. Sometimes it hapenned to me if I swapped those wires, device wasn't recognized.
Check If You didn't edited VID and PID in constructor of USBMSD?
I figured out that windows "associates" driver for each VID & PID so once I made USB mouse example and tested in windows and then built usb keyborad with same VID & PID, windows did not recognized as driver for USB mouse was associated with that VID and PID.
BTW are You using WIN7 32bit or 64bit?
Is mbed powered via its mini B USB connector or via USB device connector on breakout board?
I compiled USBMSD_SD_HelloWorld and copied it to mbed. My OS did not recognize the SD card.
D+ and D- are correct.
I am using VID and PID without changing the values in the USBMSD library - VID=0x0703 and PID=0x0104
I am using Win7 64 bit.
Mbed is powered via the USB device connector on the breakout board (just like in the picture above).
I hope the above information helps.
Seemanta
Hi llumpu,
* I compiled USBMSD_SD_HelloWorld and copied it to mbed. My OS did not recognize the SD card.
* D+ and D- are correct.
* I am using VID and PID without changing the values in the USBMSD library - VID=0x0703 and PID=0x0104
* I am using Win7 64 bit.
* Mbed is powered via the USB device connector on the breakout board (just like in the picture above).
I hope the above information helps.
//Seemanta
I am also using Windows 7 64 bits, so it is not the problem.
Several advice:
Try the USBMouse example to check that your hardware is correct
Try this program which uses USBMSD with a file system located in RAM
Sam
Hi Seemantha,
I am also using Windows 7 64 bits, so it is not the problem.
Several advice:
* Try the [[USBMouse| USBMouse]] example to check that your hardware is correct
* Try this [[http://mbed.org/users/samux/programs/USBMSD_RAM/m69mnd| program]] which uses USBMSD with a file system located in RAM
Sam
I am using a standard SD card with 1 GB capacity. And I shall try the USBMouse and the other program and let you guys know my finding.
I am grateful for the time you guys are taking to answer my queries.
I am using a standard SD card with 1 GB capacity. And I shall try the USBMouse and the other program and let you guys know my finding.
I am grateful for the time you guys are taking to answer my queries.
Yayy! It works. I just disconnected everything and re-wired the circuit. So it might have been a problem with some connection.
Thanks for your support, all of you!
Seemanta
Yayy! It works. I just disconnected everything and re-wired the circuit. So it might have been a problem with some connection.
Thanks for your support, all of you!
//Seemanta
Thanks llumpu, for your support and help. Sharing information and helping others is what makes such places so great!
Now that that problem is solved, there is something else that I am trying to do. I have made a post in the forum regarding this: http://mbed.org/forum/mbed/topic/3302/
I would be grateful if you or anyone took a look at it and commented. In short, I am trying to communicate custom data packets with the USB host side from my MBED at the USB device level. Not sure how to go about doing that.
Seemanta
Thanks llumpu, for your support and help. Sharing information and helping others is what makes such places so great!
Now that that problem is solved, there is something else that I am trying to do. I have made a post in the forum regarding this: [[http://mbed.org/forum/mbed/topic/3302/]]
I would be grateful if you or anyone took a look at it and commented. In short, I am trying to communicate custom data packets with the USB host side from my MBED at the USB device level. Not sure how to go about doing that.
//Seemanta
Hi Sam,
Thanks for your work, which unveils many clues in my application.
In my application, raw data acquiring from DAQ system (24 bits * 64 channels each block with 2k sample rate) is going to transmit into mbed through SPI interface and pass through USB interface to an Android-powered device.
Although I find mbed LPC 1768 is the most powerful ADK (Android Development Kit) available in market, but I am still searching the possibility to implement high speed rate link based on mbed. First step of this investigation is testing some example then find out the bottleneck. Low speed data link test was already done by me with success recently, but high speed data link test is also needed to be implemented.
Your codes give me some information but I still have some problem, and I hope some support from you kindly.
1. P5P8 in mbed are connected to P7679 in LPC 1768, and worked in Function 3 (or Mode 3). This interface is a SSP interface (SSP1), not only SPI interface.
Available in weblink: http://mbed.org/users/Lerche/notebook/lpc1768-pin-functions/
SSP interface compatible with Motorola SPI, 4-wire TI SSI, and National Semiconductor Microwire buses, 8 frame FIFOs for both transmit and receive, 4 to 16 bit data frame and DMA transfers supported by GPDMA. In a word, it has the capability for high speed link theoretically.
My question for this point is how fast I could set the SPI clock?
In your example, the default set is 5MHz. Could I set it as high as possible like CPU clock 100MHz? If there is some real test data, please kindly let me know.
_spi.frequency(5000000); Set to 5MHz for data transfer
OK
_status = 0x00;
return 0;
}
2. Mbed LPC 1768 only support full-speed USB, it could transmit data in 12 Mbps theoretically, but how about its real performance? I suppose that you have the possibility to implement some test to unveil it?
Please kindly give me some suggestion about those 2 problems.
Have a nice day!
Hi Sam,
Thanks for your work, which unveils many clues in my application.
In my application, raw data acquiring from DAQ system (24 bits * 64 channels each block with 2k sample rate) is going to transmit into mbed through SPI interface and pass through USB interface to an Android-powered device.
Although I find mbed LPC 1768 is the most powerful ADK (Android Development Kit) available in market, but I am still searching the possibility to implement high speed rate link based on mbed. First step of this investigation is testing some example then find out the bottleneck. Low speed data link test was already done by me with success recently, but high speed data link test is also needed to be implemented.
Your codes give me some information but I still have some problem, and I hope some support from you kindly.
1. P5~P8 in mbed are connected to P76~79 in LPC 1768, and worked in Function 3 (or Mode 3). This interface is a SSP interface (SSP1), not only SPI interface.
Available in weblink: http://mbed.org/users/Lerche/notebook/lpc1768-pin-functions/
SSP interface compatible with Motorola SPI, 4-wire TI SSI, and National Semiconductor Microwire buses, 8 frame FIFOs for both transmit and receive, 4 to 16 bit data frame and DMA transfers supported by GPDMA. In a word, it has the capability for high speed link theoretically.
My question for this point is how fast I could set the SPI clock?
In your example, the default set is 5MHz. Could I set it as high as possible like CPU clock 100MHz? If there is some real test data, please kindly let me know.
_spi.frequency(5000000); // Set to 5MHz for data transfer
// OK
_status = 0x00;
return 0;
}
2. Mbed LPC 1768 only support full-speed USB, it could transmit data in 12 Mbps theoretically, but how about its real performance? I suppose that you have the possibility to implement some test to unveil it?
Please kindly give me some suggestion about those 2 problems.
Have a nice day!
1. I think that the maximum frequency on the SPI bus is 48 MHz. So you can try to increase the default 5MHz. But I remember when I was testing with my SD card, the time to write one block (512B) was approximately 5ms and there was not a big difference between 1MHz and 5MHz.
2. So I did some tests concerning the speed:
with interrupt endpoints (used in USBHID for instance), the mbed reaches the maximum speed (for this kind of endpoints): 64kBytes/s
with bulk endpoints, the mbed can send up to 1000 packets of 64bytes each second (so a speed of 576kBytes/s). This has been tested with USBSerial
Hope that helps,
Sam
Hi Quan,
1. I think that the maximum frequency on the SPI bus is 48 MHz. So you can try to increase the default 5MHz. But I remember when I was testing with my SD card, the time to write one block (512B) was approximately 5ms and there was not a big difference between 1MHz and 5MHz.
2. So I did some tests concerning the speed:
* with interrupt endpoints (used in USBHID for instance), the mbed reaches the maximum speed (for this kind of endpoints): 64kBytes/s
* with bulk endpoints, the mbed can send up to 1000 packets of 64bytes each second (so a speed of 576kBytes/s). This has been tested with USBSerial
Hope that helps,
Sam
Hi Sam,
Thanks a lot for your quick reply.
1. My purpose is not only increasing the SPI clock, but also increasing the data rate per second on SPI bus. In my application, data is not in a SD card but from a FPGA. Mbed is going to act as a master and DAQ system end with FPGA is going to be a slave.
I am a new beginner of SPI bus, and please kindly give me some information of how to implement a high speed SPI data link.
2. Also with bulk endpoints, I suppose that there is a bottleneck in USB serial. If a USBhost library is well implemented like the example of “USBHostLite_LPC17xx.001” from ‘OnChip Technologies LLC’ and NXP, instead of make a trick with USB serial for simplicity.
When I tested the AndordAccessory example from cookbook, I found that this program does not implement real USB host but make a trick with a method that using serial-USB port and all data transceiver under serial protocol instead of USB protocol for simplicity.
I suppose that USB host protocol is still under developing in mbed, and no reliable and stable library is available for directly using by now. Furthermore, UART3, one of the LPC1768 UARTS, is connected to USB port in mbed board and a library for mapping serial data between USB data is available in mbed library. Then a trick is made for simplicity.
In this way, if building a stable library in mbed part, there is the possibility that reach a higher speed rate like 777.216 Kbytes per second (24 bits * 128 channels * 2024 sample rate) or just a few modification in USBSerial also could achieve this goal.
What about your opinion?
In a word, if I want to implement a data link from SPI bus to USB with at lease 777.216 Kbytes per second, what should I do in your opinion?
Hi Sam,
Thanks a lot for your quick reply.
1. My purpose is not only increasing the SPI clock, but also increasing the data rate per second on SPI bus. In my application, data is not in a SD card but from a FPGA. Mbed is going to act as a master and DAQ system end with FPGA is going to be a slave.
I am a new beginner of SPI bus, and please kindly give me some information of how to implement a high speed SPI data link.
2. Also with bulk endpoints, I suppose that there is a bottleneck in USB serial. If a USBhost library is well implemented like the example of “USBHostLite_LPC17xx.001” from ‘OnChip Technologies LLC’ and NXP, instead of make a trick with USB serial for simplicity.
When I tested the AndordAccessory example from cookbook, I found that this program does not implement real USB host but make a trick with a method that using serial-USB port and all data transceiver under serial protocol instead of USB protocol for simplicity.
I suppose that USB host protocol is still under developing in mbed, and no reliable and stable library is available for directly using by now. Furthermore, UART3, one of the LPC1768 UARTS, is connected to USB port in mbed board and a library for mapping serial data between USB data is available in mbed library. Then a trick is made for simplicity.
In this way, if building a stable library in mbed part, there is the possibility that reach a higher speed rate like 777.216 Kbytes per second (24 bits * 128 channels * 2024 sample rate) or just a few modification in USBSerial also could achieve this goal.
What about your opinion?
In a word, if I want to implement a data link from SPI bus to USB with at lease 777.216 Kbytes per second, what should I do in your opinion?
For the moment I have never reached more than 580 kBytes/s on the USB bus (this max speed has been reached with USBSerial). A first improvement in the USB stack should be using DMA. Also, the speed on the bus depends a lot of other devices connected on the bus. For instance bulk endpoints (used in USBSerial), have not the priority on the bus. So if there are devices with interrupt or isochronous endpoints which are using the bus, bulk transfers will be slow.
Sam
Hi Quan,
For the moment I have never reached more than 580 kBytes/s on the USB bus (this max speed has been reached with USBSerial). A first improvement in the USB stack should be using DMA. Also, the speed on the bus depends a lot of other devices connected on the bus. For instance bulk endpoints (used in USBSerial), have not the priority on the bus. So if there are devices with interrupt or isochronous endpoints which are using the bus, bulk transfers will be slow.
Sam
Hi Sam,
Thanks a lot for help. Please kindly give me some detail information about how you reach the max 580 kBytes/s on the USB bus. Specifically, I want to the following information in your test, if possible.
1. the pin connect of mbed as well as its peripherals;
2. The data is from REAL SPI interface or from a programmed ram pre-written in mbed?
3. Is there some C++ code under this test to share with us ?
4. Any information about how to implement DMA in USB stack.
Have a nice day!
As shown in the following figure (page 5 of 82 pages in datasheet of Product data sheet of LPC1769/68/67/66/65/64/63 - rev. 8 — 14 November 2011 ), the MCU of mbed LPC1768 is LPC1768FBD, means USB CONTROLLER WITH DMA.
SSP0 and SSP1(PIN76 to 79 <SSP1 interface> in MCU LPC168 are connected to Pin5 to 8 in mbed)are also connected to DMA. Theoretically, if implement SSP as well as USB host properly, we could reach a high speed rate. What is your opinion? Any suggestion ?
For the moment I have never reached more than 580 kBytes/s on the USB bus (this max speed has been reached with USBSerial). A first improvement in the USB stack should be using DMA. Also, the speed on the bus depends a lot of other devices connected on the bus. For instance bulk endpoints (used in USBSerial), have not the priority on the bus. So if there are devices with interrupt or isochronous endpoints which are using the bus, bulk transfers will be slow.
Sam
Hi Sam,
Thanks a lot for help. Please kindly give me some detail information about how you reach the max 580 kBytes/s on the USB bus. Specifically, I want to the following information in your test, if possible.
1. the pin connect of mbed as well as its peripherals;
2. The data is from REAL SPI interface or from a programmed ram pre-written in mbed?
3. Is there some C++ code under this test to share with us ?
4. Any information about how to implement DMA in USB stack.
Have a nice day!
As shown in the following figure (page 5 of 82 pages in datasheet of Product data sheet of LPC1769/68/67/66/65/64/63 - rev. 8 — 14 November 2011 ), the MCU of mbed LPC1768 is LPC1768FBD, means USB CONTROLLER WITH DMA.
SSP0 and SSP1(PIN76 to 79 <SSP1 interface> in MCU LPC168 are connected to Pin5 to 8 in mbed)are also connected to DMA. Theoretically, if implement SSP as well as USB host properly, we could reach a high speed rate. What is your opinion? Any suggestion ?
{{/media/uploads/xiong_quan/3-14-2012_12-36-21_pm.png}}
<<quote samux>>
Hi Quan,
For the moment I have never reached more than 580 kBytes/s on the USB bus (this max speed has been reached with USBSerial). A first improvement in the USB stack should be using DMA. Also, the speed on the bus depends a lot of other devices connected on the bus. For instance bulk endpoints (used in USBSerial), have not the priority on the bus. So if there are devices with interrupt or isochronous endpoints which are using the bus, bulk transfers will be slow.
Sam
<</quote>>
When checked the document of "UM10360: LPC17xx User manual" , I found the SSP1 could connect to GPDMA (General Purpose DMA). In LPC1768, there are eight GPDMA channels, and it's possible to configure one channel worked in peripheral to memory mode. More detail information about that is available in Table 564 (Page 605 of 840).
Then another configuration is set another channel worked in memory to memory mode, or point to Independent DMA in USB CONTROLLER (THIS approach is still under investigation).
This two step may implement a high speed link from SPI interface to USB interface. What is about your opinion? Please feel free to give any suggestion.
Warmly regards
Quan
Hi Sam,
When checked the document of "UM10360: LPC17xx User manual" , I found the SSP1 could connect to GPDMA (General Purpose DMA). In LPC1768, there are eight GPDMA channels, and it's possible to configure one channel worked in peripheral to memory mode. More detail information about that is available in Table 564 (Page 605 of 840).
Then another configuration is set another channel worked in memory to memory mode, or point to Independent DMA in USB CONTROLLER (THIS approach is still under investigation).
This two step may implement a high speed link from SPI interface to USB interface. What is about your opinion? Please feel free to give any suggestion.
Warmly regards
Quan
The test I did to reach the maximum speed was not between SPI and USB. It was just a program sending 64 bytes packets over USBSerial. The 64 bytes length (size of the endpoint) is important otherwise the host does not request several packets per frame.
I never played with DMA but I think that to implement a high speed SPI to USB interface, a solution can be as you said:
GPDMA to transfer data from SPI to memory
USB controller in DMA mode to transfer data from memory to endpoints
Hope that helps
Sam
Hi Quan,
The test I did to reach the maximum speed was not between SPI and USB. It was just a program sending 64 bytes packets over USBSerial. The 64 bytes length (size of the endpoint) is important otherwise the host does not request several packets per frame.
I never played with DMA but I think that to implement a high speed SPI to USB interface, a solution can be as you said:
* GPDMA to transfer data from SPI to memory
* USB controller in DMA mode to transfer data from memory to endpoints
Hope that helps
Sam
Hello all,
Is it possible to see the files that we uploaded from the programming USB, also using the second USB port?
I need a USB key with two device USB ports...
Thanks in advance
Pedro
Hello all,
Is it possible to see the files that we uploaded from the programming USB, also using the second USB port?
I need a USB key with two device USB ports...
Thanks in advance
Pedro
That it was necessary to merge these classes is a sad reflection on C++ (Java would have made this much easier!), and shows that a USBDevice class is needed to which USBEndpoint objects can be attached before connecting, rather than subclassing the USBDevice.
Steve
Well, it is not a C++ issue, it is more like a design issue... a USBEndpoint class is not a USBDevice, it is just using it... so each USBEndpoint should have a reference to a USBDevice (the same object)...no inheritance... reusable code is not all about inheritance...! the USBDevice must be prepared to be used by multiple clients... my intention is not to criticize the current code ;-) better something working then just some nice drawings on paper...!
<<quote SteveEvans>>
That it was necessary to merge these classes is a sad reflection on C++ (Java would have made this much easier!), and shows that a USBDevice class is needed to which USBEndpoint objects can be attached before connecting, rather than subclassing the USBDevice.
Steve
<</quote>>
Well, it is not a C++ issue, it is more like a design issue... a USBEndpoint class is not a USBDevice, it is just using it... so each USBEndpoint should have a reference to a USBDevice (the same object)...no inheritance... reusable code is not all about inheritance...! the USBDevice must be prepared to be used by multiple clients... my intention is not to criticize the current code ;-) better something working then just some nice drawings on paper...!
Hello Pedro, I think it is possible. You can access files on local filesystem from code. So it seems that using D+ & D- pins to connect to host PC and mbed acting as device (MSC,CDC) is possible. At the same time can be mbed connected to host via itself's USB mini B connector with access to files and serial port.
Maybe there will be need to controll access to same resource files on local filesystem from two "threads".
Hello Pedro, I think it is possible. You can access files on local filesystem from code. So it seems that using D+ & D- pins to connect to host PC and mbed acting as device (MSC,CDC) is possible. At the same time can be mbed connected to host via itself's USB mini B connector with access to files and serial port.
Maybe there will be need to controll access to same resource files on local filesystem from two "threads".
how difficult would it be to allow accses to an AT45DBxxx Flash chip, on my dev board.
using the code in [[http://mbed.org/users/samux/programs/USBMSD_RAM/m69mnd|USBMSD-RAM]]
Cheers
**Ceri
That it was necessary to merge these classes is a sad reflection on C++ (Java would have made this much easier!), and shows that a USBDevice class is needed to which USBEndpoint objects can be attached before connecting, rather than subclassing the USBDevice.
Steve
Well, it is not a C++ issue, it is more like a design issue... a USBEndpoint class is not a USBDevice, it is just using it... so each USBEndpoint should have a reference to a USBDevice (the same object)...no inheritance... reusable code is not all about inheritance...! the USBDevice must be prepared to be used by multiple clients... my intention is not to criticize the current code ;-) better something working then just some nice drawings on paper...!
Hi Pedro,
Indeed. What's needed is to be able to attach USB device drivers to specific endpoints on a USB device. There will generally only be one such USB device although that's a limitation of the hardware and so shouldn't be reflected in the design. It would then be possible to add a number of serial ports along with MSD, for example, on the same device. Each registration would contribute to the config descriptor passed to the host upon connection.
That said, it's quite possible, if not so elegant to simply merge together functions into a single class. This is what I ended up doing to support serial and/or MSD, the configuration declaring either serial or serial and MSD depending on if I needed to mount my filesystem locally or remotely.
And, like you say, whatever design limitations there may be, this code is a very useful starting point. Now that I have my application fully functional I shall at some point revisit and refactor the USB to include DMA support etc.
Steve
<<quote pedro_nf>>
<<quote SteveEvans>>
That it was necessary to merge these classes is a sad reflection on C++ (Java would have made this much easier!), and shows that a USBDevice class is needed to which USBEndpoint objects can be attached before connecting, rather than subclassing the USBDevice.
Steve
<</quote>>
Well, it is not a C++ issue, it is more like a design issue... a USBEndpoint class is not a USBDevice, it is just using it... so each USBEndpoint should have a reference to a USBDevice (the same object)...no inheritance... reusable code is not all about inheritance...! the USBDevice must be prepared to be used by multiple clients... my intention is not to criticize the current code ;-) better something working then just some nice drawings on paper...!
<</quote>>
Hi Pedro,
Indeed. What's needed is to be able to attach USB device drivers to specific endpoints on a USB device. There will generally only be one such USB device although that's a limitation of the hardware and so shouldn't be reflected in the design. It would then be possible to add a number of serial ports along with MSD, for example, on the same device. Each registration would contribute to the config descriptor passed to the host upon connection.
That said, it's quite possible, if not so elegant to simply merge together functions into a single class. This is what I ended up doing to support serial and/or MSD, the configuration declaring either serial or serial and MSD depending on if I needed to mount my filesystem locally or remotely.
And, like you say, whatever design limitations there may be, this code is a very useful starting point. Now that I have my application fully functional I shall at some point revisit and refactor the USB to include DMA support etc.
Steve
What is wrong with MSD_SD as main wouldn't work if started when USB isn't connected?
If started with connected USB, and then disconnected, it works?
#include "mbed.h"
#include "USBMSD_SD.h"
Serial pc(USBTX, USBRX);
USBMSD_SD sd(p5, p6, p7, p8);
int main() {
pc.baud(115200);
pc.printf("SD_Hello\r\n");
while(1) {
pc.printf("Still here on mbed\r\n");
wait(1);
}
}
I suppose that USBMSD_SD sd(p5, p6, p7, p8); line is waiting for USB to connects. How to ignore this and skip the line if USB isn't connected?
What is wrong with MSD_SD as main wouldn't work if started when USB isn't connected?
If started with connected USB, and then disconnected, it works?
<<code>>
#include "mbed.h"
#include "USBMSD_SD.h"
Serial pc(USBTX, USBRX);
USBMSD_SD sd(p5, p6, p7, p8);
int main() {
pc.baud(115200);
pc.printf("SD_Hello\r\n");
while(1) {
pc.printf("Still here on mbed\r\n");
wait(1);
}
}
<</code>>
I suppose that USBMSD_SD sd(p5, p6, p7, p8); line is waiting for USB to connects. How to ignore this and skip the line if USB isn't connected?
as mentioned by others thank you for taking the time to make this library.
I was wondering if you could point me in the right direction..
I want to use the LPC11u24 as a USBMSD to access an sd via pc, and also use it to write to the sd using the fat file system when not connected to a pc, my crude attempts have not managed to fit the code onto this device, I was wondering if you had tried this?
Hi Sam,
as mentioned by others thank you for taking the time to make this library.
I was wondering if you could point me in the right direction..
I want to use the LPC11u24 as a USBMSD to access an sd via pc, and also use it to write to the sd using the fat file system when not connected to a pc, my crude attempts have not managed to fit the code onto this device, I was wondering if you had tried this?
I've used Sam's code on the LPC11u24 and found that it fit's fine; I've also been making some modifications to the code to allow the card to be removed and swapped with another card; also, I am trying to incorporate SDHC compatibility; albeit with limited success.
Thanks
Jon
Hi Joe,
I've used Sam's code on the LPC11u24 and found that it fit's fine; I've also been making some modifications to the code to allow the card to be removed and swapped with another card; also, I am trying to incorporate SDHC compatibility; albeit with limited success.
Thanks
Jon
Part of this is pretending to be a Mass Storage Device via USB to the PC, right?
The other half is reading and writing an SD card which is attached to the Mbed via a "fast" SPI connection, as the source and destination of the data, right?
I am trying to use MSCFileSystem to read/write a USB flash drive, but the there are some "long" (700 ms) delays occasionally that make the recording of a high speed data stream very difficult. I do not know if this delay is due to the library or a property of the flash drive.
For high speed, should I be trying to write to an SD card instead?
Part of this is pretending to be a Mass Storage Device via USB to the PC, right?
The other half is reading and writing an SD card which is attached to the Mbed via a "fast" SPI connection, as the source and destination of the data, right?
I am trying to use MSCFileSystem to read/write a USB flash drive, but the there are some "long" (700 ms) delays occasionally that make the recording of a high speed data stream very difficult. I do not know if this delay is due to the library or a property of the flash drive.
For high speed, should I be trying to write to an SD card instead?
I am making notebook page about LPC11u24 as USB MSD with AT45xx serial memory to store configurations for program runing on LPC itself and easily access loged data. When I will finish it, I will post link here.
Hello Tom,
I am making notebook page about LPC11u24 as USB MSD with AT45xx serial memory to store configurations for program runing on LPC itself and easily access loged data. When I will finish it, I will post link here.
Example program for USBMSD device (USB Flashdisk) library using AT45DBxx serial flash storage chip. Works with 2, 4, 8, 16, 32 and 64 Mbit chips within AT45DBxx
Hello Tom,
I just published example USBMSD_AT45_HelloWorld program and library using AT45xx memory .
<<program /users/llumpu/code/USBMSD_AT45_HelloWorld/>>
Thank you for publishing your code. I see how it has been modified to work with the Atmel flash but I am still a little lost how to use it. Does the provided code just all the SD card to be accessed via USB? If I want to read/write to it from inside the program, whilst retaining the filesystem, do I use the same commands or would I have to bring in the filesystem libraries and use those?
Thank you for publishing your code. I see how it has been modified to work with the Atmel flash but I am still a little lost how to use it. Does the provided code just all the SD card to be accessed via USB? If I want to read/write to it from inside the program, whilst retaining the filesystem, do I use the same commands or would I have to bring in the filesystem libraries and use those?
No the existing USB port cannot be used with this library. In fact, the usual USB port is not even connected to the nxp lpc1768 microcontroller where is running this library. The USB port is connected to the mbed interface.
You can only use the p31 (D+), p32 (D-) pins with this library.
Cheers,
Sam
Hi Luke,
No the existing USB port cannot be used with this library. In fact, the usual USB port is not even connected to the nxp lpc1768 microcontroller where is running this library. The USB port is connected to the [[http://mbed.org/handbook/mbed-interface| mbed interface]].
You can only use the p31 (D+), p32 (D-) pins with this library.
Cheers,
Sam
Thanks for the reply. I suppose I can't use p31/p32 for software updates either so I am stuck with exposing two separate USB ports - one for programming and the other for SD access?
Thanks for the reply. I suppose I can't use p31/p32 for software updates either so I am stuck with exposing two separate USB ports - one for programming and the other for SD access?
I have got the SD card example to work OK but am having trouble with the AT45 version. I have the IC connected like this...
Signal
AT45 pin
mbed Pin
MOSI
1
p5
SCK
2
p7
nRST
3
-
nCS
4
p8
nWP
5
-
Vcc
6
Vo
Gnd
7
Gnd
MISO
8
p6
And the USB lead connected to p31 & p32, but the program seems to hang when it creats the AT45 object. Any ideas anyone?
EDIT: Got it working - I think I had a problem with the USB connector. Great library, thanks
I have got the SD card example to work OK but am having trouble with the AT45 version. I have the IC connected like this...
|Signal | AT45 pin |mbed Pin
|MOSI | 1 | p5
|SCK | 2 | p7
|nRST | 3 | -
|nCS | 4 | p8
|nWP | 5 | -
|Vcc | 6 | Vo
|Gnd | 7 | Gnd
|MISO | 8 | p6
And the USB lead connected to p31 & p32, but the program seems to hang when it creats the AT45 object. Any ideas anyone?
EDIT: Got it working - I think I had a problem with the USB connector. Great library, thanks
Please login to post comments.