EmbDev.net

Forum: µC & Digital Electronics SDHC support


von Al pacino D. (bigmicro)


Rate this post
useful
not useful
uC: Atmel at91sam7A3
compiler: IAR EWARM

Hello my friends,

I got the interface working between my ARM uC and SD card using Chan's 
FatFs. It works well for SD cards to 1 GB, but 2GB and SDHC type cards 
doesn't work. I would like to know how to get 2 GB cards work. The SD 
document of SanDisk is not really clear about it. I understand 2 GB uses 
1024 bytes instead of 512, I think. But I couldn't find a lot of 
information about it on how to interface it with a uC.

Also I would like to know if there is some kind of an open source code 
for working with SDHC. The fat filesystem is not important, cause that's 
quite standard, what more important is how to talk with SD card.

I hope somebody can give me some useful links, advise, tips, example 
codes are welcome.

Thank you.

von holger (Guest)


Rate this post
useful
not useful
Hello Al,
latest code of Chan seems to have SDHC support !?
May be you should download a newer version.

Here is some code working with an ATMega32

Beitrag "MP3 von 4GB SDHC mit ATMega32"

It does not support 2GB and 4GB SD cards (1024 byte sectors),
but it does work with a Toshiba 4GB SDHC card (512 byte sectors).
Reading and writing.

Download FatSingleOpt.zip file from bottom of the page !
Take a look into mmc_spi.c.

greetings
 holger

von Obelix (Guest)


Rate this post
useful
not useful

von Al pacino D. (bigmicro)


Rate this post
useful
not useful
Thank you for your replies my friends,

I'll read the other links later, but first I have a question. Isn't the 
problem for reading the SDHC in the hardware layer? I mean Chan's FatFs 
is ok, it does what it must do, you just need to give the data in the 
right way to FatFs. So, the problem is not how to handle fat filesystem 
in a different way, but how the SPI module interact with the SDHC.

If SDHC works with 1024 or more bytes datablock, than you could cut the 
first 512 bytes out of 1024 and pass it to Chan's FatFs and vice versa. 
The drawback is, it needs more processing and thus a slower data 
transfer.

Ofcourse, Chan's FatFs could be optimized by working with datablocks of 
1024 at once instead of 512 bytes. I think I have the latest version of 
Chan's FatFs and I've read that he didn't have tested datablock of more 
than 512 bytes (e.g. 1024) yet.

von Al pacino D. (bigmicro)


Rate this post
useful
not useful
Hello again my friends,

I've read the other post from other links and downloaded 
FatSingleOpt.zip. Are the FAT.c and DOS.c good sources? At the moment I 
work with Chan's FatFs and it works very well. The only problem is 
reading 2 GB SD cards (I don't know where to modify this problem) and I 
haven't even tried yet the SDHC cards.

I've read from wiki that Toshiba SD cards of 4 GB or more are not not 
standards of SD association and won't be compatible with the real 
original SDHC standard so using them on your pc will require some 
additional special card-reader or something . So I'm a bit confused and 
don't know what to do.
Anyway, I need to read/write with my Atmel's ARM to SD card up to 8 GB 
and also be possible to read/write on the pc (with a cardreader).

Any suggestion?

Thanks in advance.

von Obelix (Guest)


Rate this post
useful
not useful
Toshibas SDHC-Karten haben 512Byte pro Sector.

von Daniel S. (dschwab)


Rate this post
useful
not useful
Al pacino Deniro wrote:
> Thank you for your replies my friends,
>
> I'll read the other links later, but first I have a question. Isn't the
> problem for reading the SDHC in the hardware layer? I mean Chan's FatFs
> is ok, it does what it must do, you just need to give the data in the
> right way to FatFs. So, the problem is not how to handle fat filesystem
> in a different way, but how the SPI module interact with the SDHC.

The SPI module interact is the same how for the SD Cards. The different 
is in the command instruction to communicate with the SD card.

> If SDHC works with 1024 or more bytes datablock, than you could cut the
> first 512 bytes out of 1024 and pass it to Chan's FatFs and vice versa.
> The drawback is, it needs more processing and thus a slower data
> transfer.

The Read Command from a SD Card work with byte adressing. So if you want 
read the second sektor from a SD Card you must multiplicate it with 
512byte. For example:

First Sektor 0 x 512 = byte adress for the SD card
Second Sektor 1 x 512 = byte adress for the SD card
Third Sektor 2 x 512 = byte adress for the SD card

This ist important, because the FAT calculate in Sektors (512bytes) and 
the SD Card in bytes.

> Ofcourse, Chan's FatFs could be optimized by working with datablocks of
> 1024 at once instead of 512 bytes. I think I have the latest version of
> Chan's FatFs and I've read that he didn't have tested datablock of more
> than 512 bytes (e.g. 1024) yet.

If you want now Read SDHC so you need to change the byte adress 
calculating to sektor calculating. For Example:

First Sektor 0 = Sektor adress for the SDHC card
Second Sektor 1 = byte adress for the SDHC card
Third Sektor 2 = byte adress for the SDHC card

The Instrucion to read the data is the same for the Software, only the 
adressing is different. If you want read data from a SDHC with a SD 
driver you receive allways the false sektor.

Don't forget, in the initializing you need now CMD8.

http://www.mikrocontroller.net/attachment/22931/FATSingleOpt.zip

But this driver it see well. In the Read function he suport the SDHC, 
but it can be that there are some mistakes (he has not tested yet) in 
the initialisation. If it don't work, so you must search there.

I hope I could help you.
bye

von Al pacino D. (bigmicro)


Rate this post
useful
not useful
Thanks for your reply my friends,

Daniel Schwab wrote:
> The Read Command from a SD Card work with byte adressing. So if you want
> read the second sektor from a SD Card you must multiplicate it with
> 512byte. For example:
>
> First Sektor 0 x 512 = byte adress for the SD card
> Second Sektor 1 x 512 = byte adress for the SD card
> Third Sektor 2 x 512 = byte adress for the SD card
>
> This ist important, because the FAT calculate in Sektors (512bytes) and
> the SD Card in bytes.

Yes I understand, that's how I got Chan's FatFs hooked up on my uC.

> If you want now Read SDHC so you need to change the byte adress
> calculating to sektor calculating. For Example:
>
> First Sektor 0 = Sektor adress for the SDHC card
> Second Sektor 1 = byte adress for the SDHC card
> Third Sektor 2 = byte adress for the SDHC card
>
> The Instrucion to read the data is the same for the Software, only the
> adressing is different. If you want read data from a SDHC with a SD
> driver you receive allways the false sektor.

So somebody managed read/write to an SDHC in opensource world?

> But this driver it see well. In the Read function he suport the SDHC,
> but it can be that there are some mistakes (he has not tested yet) in
> the initialisation. If it don't work, so you must search there.

I hope somebody has enough time to test it :)
I'm now trying to get reading/writing 2 GB SD card and than I'll look if 
I'm able to read/write for SDHC cards.

If somebody wants to help, you're welcome.

> I hope I could help you.
> bye

It's always helpful if you post an idea or a solution my friend.

Thank you very much for your attention.

von holger (Guest)


Rate this post
useful
not useful
>> But this driver it see well. In the Read function he suport the SDHC,
>> but it can be that there are some mistakes (he has not tested yet) in
>> the initialisation. If it don't work, so you must search there.

>I hope somebody has enough time to test it :)

I tested SDHC. Reading and writing works perfectly.
The only thing that is not supported are 2GB and 4GB
SD cards with 1024 byte per sector.

May be you can change this by making BYTE_PER_SEC
a global variable (S_SIZ for Chan), and set it right
in MMC initialisation procedure. But don't forget
to enlarge sectorcache and fatcache buffers to 1024 byte.

von Al pacino D. (bigmicro)


Rate this post
useful
not useful
Thank you for your reply Holger,

I don't know if I understand you well, but SDHC cards are from 2 GB and 
higher, so do you mean it works as long as it's 1 GB or lower?

Anyway, I'll give a try to get 1024 bytes sector work. If I manage to 
get it work with 2 GB SD card, I promise I'll post the code here.

Thank you.

von Daniel S. (dschwab)


Rate this post
useful
not useful
Hello Holger

It's posible for you to post your newest code from the SDHC and SD card 
access software here to download? Because 2 years ago I wrote any 
drivers for SD access and they have any features which I miss in your 
driver and you have any features wich I miss in my driver. So I would 
like try to merge it.

for example:
I need lesser than 100byte to access files include FAT (you need 1.2kb).

bye Daniel

von holger (Guest)


Rate this post
useful
not useful
>I don't know if I understand you well, but SDHC cards are from 2 GB and
>higher, so do you mean it works as long as it's 1 GB or lower?

No, it works with a 4GB Toshiba SDHC card. Your 2GB card
is not a SDHC card ! Look into SD spec Version 2.

You can find it here (thanks to Obelix)
Beitrag "SD-Karte - SDHC Karte"

There are 2GB and 4GB cards that are NOT SDHC
cards. They only have larger sectors.
2GB -> 1024 bytes, 4GB -> 2048 bytes (I think).
This is because CSD structure can not describe
cards above 1GB with 512 byte per sector.

SDHC cards start at 4GB. They have 512 byte per sector
and a modified CSD structure. And there has to be a
SDHC logo on the card !

So today we have two different types of 4GB cards !

von Al pacino D. (bigmicro)


Rate this post
useful
not useful
holger wrote:
> No, it works with a 4GB Toshiba SDHC card. Your 2GB card
> is not a SDHC card ! Look into SD spec Version 2.

I know my 2 GB SD card is not an SDHC type card, I just want to say that 
there are other companies selling SDHC cards, which are not compatible 
to the original standard:

Before SDHC was standardized, various manufacturers "extended" the SD 
control block fields for their 2GB and 4GB cards in different ways. 
Those cards are incompatible with many SD and some SDHC devices, as they 
conform to neither standard. (source from wikipedia)

> This is because CSD structure can not describe
> cards above 1GB with 512 byte per sector.

Well, I've checked the CSD structure for the 2 GB SD card and the CSD 
describes the specification well. The only difference between the 1GB 
and 2 GB is Max_Read_DataBlock_Length is set to 1024 bytes for 2 GB 
while 1 GB is set to 512 bytes and that is also for the Write.
While I formatted the 2GB card in 512 bytes sectorblock.
It's a bit confusing for me. Because SD Association sais as follows:

To make 2GByte card, the Maximum Block Length (READ_BL_LEN=WRITE_BL_LEN) 
shall be set to 1024 bytes. However, the Block Length, set by CMD16, 
shall be up to 512 bytes to keep consistency with 512 bytes Maximum 
Block Length cards (Less than and equal 2GByte cards)

I don't really get it what they want to say, I guess they just want to 
make it difficult for us, because they want us to pay absurd licenses

Thank you in advance.

von Al pacino D. (bigmicro)


Rate this post
useful
not useful
Hi guys,

I've tried to modify Chan's FatFs's code such a way that I can write to 
an 2 GB SD card (not a SDHC), but it doesn't work. I changed SIZE buffer 
from 512 to 1024, and it looks like everything ok if singlestep debug. 
But if I want to see the content of the 2 GB SD card on the laptop (I 
use my laptop's card reader, is the only one that can read/write to 2 GB 
SD card) than the card is EMPTY!

So somewhere in my code it writes data to the wrong address place in the 
SD card. Is there some description about using FAT32? Something like a 
functional diagram, like where to read, where to jump for writing a file 
etc.. There is nothing to find about working with SD card in 1024 
blocksize, so I'm like walking to a dead end.

I don't know what to change more, or what other things are important to 
read 2 GB cards in 1024 blocksize..

Any suggestions??

von Daniel S. (dschwab)


Rate this post
useful
not useful
Hello

I could start to merge my code with chan's and holgers code. So we have 
after a realy good driver to access files.

Wait any month until I have finished my work, try again to use your SD 
Card with 2Gb and I am sure, it works.

bye.

von holger (Guest)


Attached files:

Rate this post
useful
not useful
Hello Al,Daniel,

yesterday somebody told me, that in a previous
version of my code 2GB cards were working.
But i think only to half size of the card.

It seems not to be necessary to change sectorsize to 1024 !
Sector size of 1024 in CSD is only used to
calculate the correct drive size.
Sectoradressing is the same as for smaller
cards i think. I changed mmc_spi.c for this.
If read_bl_len is bigger 512, CMD SET_BLOCK_LEN
to 512 is executed now. Couldn't test it :(
because i have no 2GB card.

Try it ! And please tell me if it works.

von Al pacino D. (bigmicro)


Rate this post
useful
not useful
Hello my friends,

I try to write SDHC support based on Chan's FatFs this weekend, but I 
need some help of you guys. Can somebody give me a good pdf which 
describes how to communicate with SDHC cards and what should be done to 
communicate with 2 GB or more using different blocksize other than 512 
bytes?

I want to focus on this part and hopefully can come with a nice source 
everybody can use it on his/her project or product.

Thank you.

von Al pacino D. (bigmicro)


Rate this post
useful
not useful
Hello my friends,

I've tried something with 2 GB SD card, and I managed to write in the 
Root Table Directory, but it went wrong writing the content of it. So 
the filename seems to be written good in Root Table Directory, but only 
the content is missing. I've the hex data here:
1
00000000 5241 494E 4152 4149 2020 2008 0000 0000 RAINARAI   .....
2
00000016 0000 0000 0000 7A53 E936 0000 0000 0000 ......zS.6......
3
00000032 E542 0065 0073 0074 0061 000F 00FF 6E00 .B.e.s.t.a....n.
4
00000048 6400 2E00 7400 7800 7400 0000 0000 FFFF d...t.x.t.......
5
00000064 E545 5354 414E 4420 5458 5420 0060 3557 .ESTAND TXT .`5W
6
00000080 E936 E936 0000 3657 E936 0000 0000 0000 .6.6..6W.6......
7
00000096 4142 0065 0073 0074 0061 000F 00FF 6E00 AB.e.s.t.a....n.
8
00000112 6400 2E00 7400 7800 7400 0000 0000 FFFF d...t.x.t.......
9
00000128 4245 5354 414E 4420 5458 5420 0060 3557 BESTAND TXT .`5W
10
00000144 E936 E936 0000 3657 E936 0300 1E00 0000 .6.6..6W.6......
11
00000160 E546 0069 006C 0065 002E 000F 0019 7400 .F.i.l.e......t.
12
00000176 7800 7400 0000 FFFF FFFF 0000 FFFF FFFF x.t.............
13
00000192 E549 4C45 2020 2020 5458 5420 0012 1D5B .ILE    TXT ...[
14
00000208 E936 E936 0000 205B E936 0000 0000 0000 .6.6.. [.6......
15
00000224 4146 0069 006C 0065 002E 000F 0019 7400 AF.i.l.e......t.
16
00000240 7800 7400 0000 FFFF FFFF 0000 FFFF FFFF x.t.............
17
00000256 4649 4C45 2020 2020 5458 5420 0012 1D5B FILE    TXT ...[
18
00000272 E936 E936 0000 205B E936 0400 6100 0000 .6.6.. [.6..a...
19
00000288 0000 0000 0000 0000 0000 0000 0000 0000 ................
20
00000304 0000 0000 0000 0000 0000 0000 0000 0000 ................
21
00000320 0000 0000 0000 0000 0000 0000 0000 0000 ................
22
00000336 0000 0000 0000 0000 0000 0000 0000 0000 ................
23
00000352 0000 0000 0000 0000 0000 0000 0000 0000 ................
24
00000368 0000 0000 0000 0000 0000 0000 0000 0000 ................
25
00000384 0000 0000 0000 0000 0000 0000 0000 0000 ................
26
00000400 0000 0000 0000 0000 0000 0000 0000 0000 ................
27
00000416 0000 0000 0000 0000 0000 0000 0000 0000 ................
28
00000432 0000 0000 0000 0000 0000 0000 0000 0000 ................
29
00000448 0000 0000 0000 0000 0000 0000 0000 0000 ................
30
00000464 0000 0000 0000 0000 0000 0000 0000 0000 ................
31
00000480 0000 0000 0000 0000 0000 0000 0000 0000 ................
32
00000496 0000 0000 0000 0000 0000 0000 0000 0000 ................

The one I added with my microcontroller is File.txt, but as I said, I 
couldn't find the content . Can somebody tell me which bytes tell me 
which sector to look for the content?

Thnx in advance.

von Al pacino D. (bigmicro)


Rate this post
useful
not useful
I'm sorry, I've made a mistake.
I haven't written the last file File.txt with the microcontroller. 
That's also done via windows.

But during singlestep debugging, the write-operation was succesful. I 
send data in 512 bytes block. I guess it doesn't work with 512 bytes 
data block. Maybe I've to make 1024 bytesblock to send. But it's strange 
why I don't receive send errors.

von Al pacino D. (bigmicro)


Rate this post
useful
not useful
Hello everybody,

I can read from 2 GB sd card, but I can't write to it.
I tried to make the sd card corrupt, by filling 0xFF to the first 
physical sector 0. If I open the sd card in the pc, the same sector 
seemed to be not overwritten.

I've done exactly the same thing for 1 GB sd card, and than I've put it 
in the pc to read it. Well guess what, windows says the SD card needs to 
FORMAT before I can use it. So there is really something about the 2 GB 
sd card why it can't be written.

With 2 GB sd card I've tried 512 bytes datablock as well as 1024 bytes 
datablock

If writing to 2 GB card is not possible, than that should be the 
problem. I think the problem is not the filesystem (maybe a little bit), 
but the ability to write to the SD card of 2 GB types. So is there some 
kind of write protection we need to disable....? I guess something in 
the initialization of the SD card must be modified for 2 GB cards.

I haven't tried yet for SDHC cards, because I don't have them.

von Al pacino D. (bigmicro)


Rate this post
useful
not useful
Hello my friends,

I got the SDHC card working, I've tried it with 4 GB and 8 GB SDHC cards 
with AT91SAM7A3! It works great, except a tiny problem! The problem is 
how to determine the size of the SDHC type cards.

There are two differences in SD cards, old SD cards of Version 1.xx and 
new SD cards (including SDHC) of Version 2.00. Old SD cards up to and 
including 1 GB are mostly of version 1.xx, but microSD and SDHC cards 
are of Version 2.00 and thus have a modified CSD register. One of the 
differences is how to determine the card's size.

The size of Version 1.xx type cards (old SD's) is determined by the 
following formula:
memory capacity = BLOCKNR * BLOCK_LEN
BLOCKNR = (C_SIZE+1) * MULT
MULT = 2^C_SIZE_MULT+2, (whereby C_SIZE_MULT < 8)
BLOCK_LEN = 2^READ_BL_LEN,  (whereby READ_BL_LEN < 12)

The size of Version 2.00 type cards (microSD's and SDHC's) is determined 
by the following formula:
memory capacity = (C_SIZE+1) * 512K byte
That's it!

Accoording to my code I get for both SDHC cards 4 GB and 8 GB the same 
memorysize: 3.67 GB.

Accoording to Windows XP the 4 GB SDHC card's memory capacity is:
3.78 GB, and for 8 GB SDHC is: 7.59 GB

So is there anyone who can help me to calculate the memory size on the 
right way? If somebody likes to share the secret I can complete the SDHC 
library.

I'll soon share the source with everybody on my website: www.ingeniuz.nl 
( I'm working on it, so please be patient )

von holger (Guest)


Rate this post
useful
not useful
>memory capacity = (C_SIZE+1) * 512K byte
>Accoording to my code I get for both SDHC cards 4 GB and 8 GB the same
>memorysize: 3.67 GB.

If you calculate the disc size in bytes, you have to
use a variable with more than 32 Bit for 8 GB !

von Al pacino D. (bigmicro)


Rate this post
useful
not useful
Hell0 Holger,

Thnx for your reply, yes I found out that it has to do with 32 bits 
limit. So I've used double to solve this problem.

This means that the whole thing is working ok now.

I would like to show the code how to make your reader sdhc compatible, 
but it takes some time to show it and because I'm at work now, I can't 
waist my boss's time. So as soon as I have some time free in my own 
time, than I'll drop it on my website (I'm also working on my website :( 
).

Anyway I can give you some tips where to look to get it work. The 
changes you need with the standard SD library provided by a lot of 
goodwilling guys who share their sources (Like the writer of Chan's 
FatFS, or holger ;-)) is in the initial part. To know if you have to 
deal with version 1.xx or version 2.00, you need to send CMD8 ( see the 
flowdiagram of SD specs. ). If the card responses than you need to set 
HCS bit with ACMD41, when you than send CMD58 you need to check CSS is 
set. If this is the situation, than the card is SDHC otherwise the card 
is SD of version 2.00 (like microSD).

If CMD8 doesn't respond than the card is a standard SD of version 1.xx.
If it's a version 2.00 SD card, you can calculate the memory size 
accoording to the following formula: (C_SIZE+1) * 2^19  Watchout that 
this can be bigger than a 32 bits value, so you need a variable type of 
64 bits (like double).
And than the latest important point, in case of SDHC, you need to send 
sectornumbers and NOT byteaddresses. Normally you multiply sectornumbers 
with 512, but with SDHC cards you don't.

If you have any questions trying to get SDHC cards working, just post a 
message or send me an eM@il: xtelligence (at) gm@il (dot) com

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.