PDA

View Full Version : SD Cards; Can I use one like an eeprom?



parsko
01-26-2007, 06:34 AM
There have been a number of posts regarding this subject, SD cards. I recall reading (recently), but could not find after plenty of searching, that one could simply treat a SD card like eeprom. More specifically; that one could simply write to specific bytes of memory.

So, please clarify, that I could simply write a byte to a random address? I gather that SD cards may require a protocol to start up, or could one simply hook up the wires, and blast bytes at addresses until the thing is full?

I understand that this sacrifices one potentially HUGE advantage of the SD card, FAT16 compatibility. I'm willing to sacrifice that if I can get rid of this board with 8 eeproms sittin next to me...

Thanks,

-Parsko

asterick
01-26-2007, 06:47 AM
It depends on the SD card. Some allow for random read/write to unaligned LBAs... Some only allow you to write 512 byte chunks on 512 byte boundaries.

rokicki
01-26-2007, 06:51 AM
You do need a bit of protocol to start up, and the cards work in 512-byte blocks, not bytes (in general)
but otherwise you can use it as you describe.

If you truly need random byte writes you will need to do that by reading a block, modifying the
appropriate byte or bytes, and writing that whole block back.

Other than that, yeah, just treating them as one big huge block device is fine. And very little code is
needed to do this. Download http://tomas.rokicki.com/fat16work/ and use any of the block-level
routines there (essentially they include mount a card, read a block, write a block). One is super
simple, in Spin, and somewhat slow. The others use assembly and give you varying degrees of
speed.

Note that while most writes will complete quickly, sometimes a write may take up to a fifth of a
second to finish. This is due to the nature of the cards.

A particularly simple way to use a card is just as a linear file, treating a block of zeros as empty.
To "append" to this file, at startup you can do a quick binary search to find the first block with
any zeros in it, and then just continue from that point. Of course you need to start by clearing the
full card.

A block read will take on the order of a millisecond. A block write will take on average about
twice that long, but most block writes will take about a millisecond.

parsko
01-26-2007, 03:46 PM
Hmm, this sounds like a more usable idea. I keep pushing myself to get this 1Mhz I2C protocol written, but I can't get my mind wrapped around it right now. Plus, I was projecting only being able to write roughly 12kBps to a board of 8 (512k) eeproms on four (two I2C banks) pins. If I can get the same results, but use a more robust (read: newer) technology, that would be better.

My scheme was to use the block write on the eeproms anyway. I have no issues expanding this block to 512 bytes, from 64. That's 8 times more at a similar write speed. I'm a bit worried about your "sometimes a write may take up to a fifth of a second to finish". Would you care to expand on that? Is that statement brand specific?

My ultimate project works completely out of PASM, with only human interface items (buttons/LCD) being done in SPIN, since the human eye is wicked slow. So, I would be calling the writeBlock code exclusively from (expletive)y. Without dissecting your code, would you expect that to be relatively easy to setup?

I would still probably use two SD cards, so I can log seemlessly. With only ~1MB/2 pins for Eeproms, I wouldn't be utilizing my Prop efficiently. Upwards of 2 GB/5 pins is more along the lines of what I'd like.

I like SPI better than I2C, also.

Time to do some reading. Thanks, I'll likely have a few more questions to clear the fog later...

-Parsko

rokicki
01-26-2007, 05:19 PM
Yeah, you can easily rework the routines to call them only from (expletive)embly, no problem.

The reason (I think) sometimes writes are slow is because sometimes the device needs to erase a new chunk of the chip, and
erasing is slow. So you'll get a lot of fast writes (that write to a block already erased) and then one will be slow.

If you want to experiment, there are preerase commands and the like that may possibly help this, but I'm not entirely
sure if they will always work or how they will always work, and they will definitely complicate the code. And different
cards may have different internal architectures so I really can't guarantee anything.

The slow writes happen (on the cards I've tested) about once every 512 writes (pretty repeatably). That's a very low
percentage of the writes.

I am not sure what you are building, but I would probably start with using a single card. It's really quite fast.

Of course my recommendation is to mock virtually everything up in Spin first, and then downcode to (expletive)embly as needed.

The only code you need to look at to start is sdspi.spin; that's everything you need to read and write blocks, and it is
very simple. The (expletive)embly is just various versions of that code.