SD cards - differences?

I'm working on a project that uses an SD card in SPI mode, and I have encountered some oddities. Most strikingly, I have code that works perfectly on a bunch of 32Mb Toshiba cards but refuses to work at all on 64Mb cards (also Toshiba, but overbranded PNY). This is not a filesystem layer error - it is a problem at the physical level. If I try to read-modify-write sector 0 (for example), it works on the 32Mb card but the readback is a sector-o-zeroes on the 64Mb card.

Are there some known differences between various types of card, that I should be taking into consideration? I've pored over a bunch of hobbyist implementations in C and a variety of assembly languages, but they all seem to be doing the same steps my code does, in the same order.

I realize this is a vague question, but I can't find any war stories in google, I'm wondering if they exist at all...

Reply to
larwe
Loading thread data ...

Are you allowing 64 clocks (the Ncr timing parameter) for the R1 response? That was a mistake I made that had my code working on some cards and not others; some responded immediately to commands and others didn't.

The other thing that I've never actually seen documented anywhere is the need to send 80 clocks with CS high before sending CMD0.

--
John W. Temples, III
Remove -spam to reply.
Reply to
John Temples

larwe schrieb:

I didn't have any problems with SD cards yet, but I have a MMC where the SPI implementation is totally messed up: the data is sampled *and* changed on the rising clock edge, which is clearly against the specification and compatible with no SPI standard in the world. It works fine if the clock frequency is above 20 MHz, though...

Screenshot of clock and data out:

formatting link

Which SPI mode are you using? The (free) protocol description is very vague about the SPI physical layer, and I found several contradictory opinions on which SPI mode to choose. My Sandisk SD card works only in mode 3, but according to

formatting link
mode 0 should be the correct setting.

--
http://www.mikrocontroller.net
Reply to
Andreas Schwarz

Hi,

Well, the odd thing is that if I put in 64 clocks' delay, my code no longer works with the 32Mb card.

I'll try this, thanks - I never heard this one either.

Reply to
larwe

You don't want to delay 64 clocks unconditionally, you want to allow

*up to* 64 clocks for the response.
--
John W. Temples, III
Reply to
John Temples

So they are being lazy and using gate propagation as a delay? Does mmc spec have a lower limit on the frequency?

Reply to
DAC

I'm sure this was not intended.

There is no lower limit.

Reply to
Andreas Schwarz

Lewin, is this data sector 0, and if so are you using the file system to deduce the sector number?

I did some experiments with SD cards about six months ago to the point where I could read and write to them from an FPGA, directly accessing the physical sectors so I didn't have to worry about the file system. What I found was that even when formatted the same the first data sector on the larger cards was at a higher physical address then on the smaller cards.

I didn't look into this enough to deduce why, I ended up starting all my data at address XXXX, which was high enough to be valid in all cards.

You might be accessing an area below 'real' sector0 in the 64MB card?

Nial.

Reply to
Nial Stewart

Hi Nial,

No, and no. I am having trouble reading at the physical layer, not the logical layer. But my problem appears to be solved, see the post I'm about to make.

The reason for this is that the card is partitioned. SOP for a partition table generated by FDISK (and built into the spec for some flash media types, e.g. SSFDC) is to reserve the first _track_ and start the first partition at cyl 0, head 1, sector 1. So the location of the first data sector depends on the geometry reported by the card, and the intellect of the computer or system that formatted the card.

I'm told (check c.a.e archives) that Windows XP has introduced some new, different, odd and incompatible behavior with respect to removable disks, which should surprise nobody. But I have not observed the specific behavior described by the poster who told me this.

Reply to
larwe

I've found the answer to my problem, and yes there is some difference between different models or perhaps sizes of card.

I was previously deasserting _CS after every sector read or write operation. It appears that some cards (not all) don't like this. You can _READ_ without problems, but you cannot _WRITE_ on such cards.

Most of the code floating around the net deasserts CS after each sector is read or written. That's why I added the feature to my own implementation, in fact - I assumed this was required behavior.

Now I simply keep CS low permanently after issuing the CMD0, until I detect card eject. This has solved my problems.

Reply to
larwe

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.