Jump to content
  • 0

PmodSD on CMOD A7


PTSmith

Question

Hello,

I'm looking into storing data from an ADC system read through an FPGA to an SD card at 3.5 Mbps.  I'd prefer not to use a processor.  It looks like I could plug the PmodSD into a CMOD A7 (for example).  I've found some discussions of directly writing to an SD card on the Digilent Forum, and some links to VHDL to do this; I especially like this code:

https://github.com/xesscorp/VHDL_Lib/blob/master/SDCard.vhd?_ga=2.101734593.1593613684.1574706372-1261715882.1574452484

In this discussion:

D@n says he has been able to write to an SD card at 8 Mbps, so that would be fast enough for me.  However, in this discussion:

BenBog says he can't write faster than 1 Mbps.  Is this because he is going through a linux driver from the MicroBlaze?

Once the write gets going, the SPI clock used by the SD card is 25 MHz, so I'm wondering what limits the achievable write speed to much less than 25 Mbps?  Is it because the write is limited to 512 byte blocks and then you have to set up a new write sequence?

If one writes to an SD card directly with vhdl through SPI you obviously don't generate a file system; I presume if you use a formatted SD card the file formatting gets overwritten.  This would be fine, but I'm wondering how/if one can then read this SD card on a computer?  Presumably when you plug in such a card the OS will see that the card isn't formatted and won't know what to do with it.  Is there some way to still get the data off the card?

thanks in advance,

Paul Smith

Indiana University Physics

 

Link to comment
Share on other sites

12 answers to this question

Recommended Posts

@PTSmith,

Can you still get the data off of an SD card that doesn't have a file system on it?  Absolutely!  On a linux system, you would open its respective /dev file, such as /dev/sdh or some such.  You can see what it is when it tries to mount and fails--it'll stuff a message in the logs telling you what device name was assigned to the SD Card.  The "dd" command can then be used directly if you want, or you can use your own program to read from the SD Card.

As for card speed, when I did my SD card work earlier this month, the speed of the SD card wasn't limited by my processor (ZipCPU--so I doubt it would be limited by a MicroBlaze), but rather by the SD card itself not being ready for subsequent writes.  In other words, it's not the protocol that limits the speed, rather it's the card itself that will be the speed limit.

Dan

Link to comment
Share on other sites

Great, thanks for the quick and very informative reply, D@n!  If I can write directly from VHDL without a microBlaze or other processor it will save me a lot of design effort.

I started reading this spec:

http://academy.cba.mit.edu/classes/networking_communications/SD/SD.pdf?_ga=2.9720497.507573557.1574713618-1111739473.1574713618

I wonder if you know of any more recent version of the SD card spec?  I suppose the SPI mode hasn't changed for quite a while.

Anyway, in 7.2.4 there is a description of writing in SPI mode.  So, after you send the block of data, you wait for the card to go NOT BUSY; this is the speed limit I think. I can just buffer my data in block RAM while the card is busy as long as I can get an overall rate of ~3.5 Mbps to the card.

I see you can buy SD cards with different speeds.

Were you using 1-bit or 4-bit communication with the SD card?  Is there any reason the PmodSD can't use a microSD card with an adapter?

One more question; do all SD cards support SPI mode?  It sort of looks like this is required.

Link to comment
Share on other sites

@PTSmith,

Let's see ... I was using this project, and only quite recently I might add.  The most recent/working version is in the dev tree.  I wrote about my recent experiences here.  Your spec is newer than the one I used.  I was using the 1-bit (SPI) mode.  You should be able to use the PmodSD with a microSD card with an adaptor--I've done that myself, although not for this most recent project.  As for whether or not all SD cards support SPI mode, I don't know, but my guess is that it's a high percentage of them.  I was successful using SPI mode with both a Lexar card as well as a SanDisk card.

Dan

Link to comment
Share on other sites

17 hours ago, D@n said:

@PTSmith,

 I wrote about my recent experiences here.  Your spec is newer than the one I used.  I was using the 1-bit (SPI) mode. 

Dan

Fun and interesting read; I especially liked your term "jenga design". ?

Here is an even newer version of the spec:  https://www.sdcard.org/downloads/pls/

Neither include the SPI timing diagram; have you seen it anywhere?  Probably not necessary...

I presume your 8 Mbits/sec write to SD is averaged over some long time...

Link to comment
Share on other sites

@PTSmith,

The "Jenga design" was torn up and rewritten--that's why I was pointing you to the dev branch earliier.

If you'd like to see a timing diagram, feel free to install SymbiYosys together with the boolector engine, and run "make" in the bench/formal directory.  This will generate a series of VCD files under bench/formal/*_cvr/engine_0/trace*.vcd (IIRC) which should illustrate most of what you need to know.  There will be a directory for sending data to the card (bench/formal/spitxdata_cvr/engine*/trace*vcd), another one for receiving data (spirxdata_cvr/...) etc.  It should help you out.

Dan

Link to comment
Share on other sites

@PTSmith,

Almost forgot, a "make" in the main directory (assuming you also have Verilator installed, in addition to symbiyosys and boolector) will generate a file in bench/cpp/trace.vcd showing a trace of 1) how to bring the card up from scratch, 2) read the card specific registers, and then 3) read data from the card, 4) write data to the card, 5) verify the data written to the card, 6) rewrite the original data, 7) verify that the data was rewritten properly.

Dan

Link to comment
Share on other sites

So, I had to work on other stuff for the last few months, but have gotten back to this.

Found a controller I liked even better at:

https://github.com/ibm2030/SimpleSDHC

Was able to write a single block of 512 bytes to an SD card and view it on a Mac with:

dd if=/dev/disk3 | hexdump | more

It took 184 uS to transfer the data, or 2.8 Mbytes/sec.  The card stayed busy for 5.3 mS, so write speed is 96.6 kbytes/sec.  Seems plausible.

However, not fast enough for my application; I'd like to get 1Mbyte/sec write speed if possible which would give me a comfortable margin.

I want to try a multiple block write next which hopefully will be faster.  I suppose the more blocks the faster.

But, it's not at all clear to me what is the maximum number of blocks the card will accept.

Also, it's not obvious what the erase_count input does or whether I need to use it.  I guess I can figure it out, but wouldn't mind a hint.

Link to comment
Share on other sites

If I write 16 blocks it takes 6.44 ms, or 1.27 Mbytes/sec.

If I write 32 blocks it takes 9.24 ms, or 1.77 Mbytes/sec.

If I write 256 blocks, it takes ~50 ms, or 2.6 Mbytes/sec.

One surprising thing is the value of erase_count doesn't seem to make any difference; for example changing from 1 to 32 when writing 32 blocks it still takes 9.24 ms; at least thats how long the sd_busy signal stays on.

I haven't been able to write some number of blocks, terminate the write, wait for sd_busy to drop, then initiate another write of the same number of blocks; SimpleSDHC just stays always busy and stops acknowledging write data after the first block in the second group of blocks; sometimes with error 3, but usually no error.

I guess what I have is good enough for what I want to do; I can just start a multi-block write and stream data to the SD card a block at a time.  But I worry that I don't really understand why erase_count doesn't matter, nor why I can't stop and then start up writing again.

Link to comment
Share on other sites

I modified my VHDL so that I can initiate a write of 256 blocks by pushing a button on the CMOD A7; it works as fast as I can push the button, so I guess my loop just tries again too soon; evidently the sd_busy being low doesn't really mean the card is ready for a new multi-block write.  One new discovery; on maybe one out of 50 tries the write of 256 blocks takes longer than 50 ms; I've seen 63 and 76 ms.  Still fast enough, but yet another thing I don't understand about SD cards.

Link to comment
Share on other sites

Modified test vhdl so I can start and stop writing with the two buttons on the CMOD A7.  Wrote over 1 Gbyte with no problems.  Wrote continuously for 100 sec and counted 554,508 blocks or almost 2.84 Mbytes/sec.

So, almost 3X faster than what I need.? Time to move on to design of the PCB.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...