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.
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.
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
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.
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).
Thanks in advance.
Toshibas SDHC-Karten haben 512Byte pro Sector.
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
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.
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.
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.
It's always helpful if you post an idea or a solution my friend.
Thank you very much for your attention.
>> 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.
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.
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.
I need lesser than 100byte to access files include FAT (you need 1.2kb).
>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 !
> 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.
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..
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.
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.
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
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.
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:
00000000 5241 494E 4152 4149 2020 2008 0000 0000 RAINARAI .....
00000016 0000 0000 0000 7A53 E936 0000 0000 0000 ......zS.6......
00000032 E542 0065 0073 0074 0061 000F 00FF 6E00 .B.e.s.t.a....n.
00000048 6400 2E00 7400 7800 7400 0000 0000 FFFF d...t.x.t.......
00000064 E545 5354 414E 4420 5458 5420 0060 3557 .ESTAND TXT .`5W
00000080 E936 E936 0000 3657 E936 0000 0000 0000 .6.6..6W.6......
00000096 4142 0065 0073 0074 0061 000F 00FF 6E00 AB.e.s.t.a....n.
00000112 6400 2E00 7400 7800 7400 0000 0000 FFFF d...t.x.t.......
00000128 4245 5354 414E 4420 5458 5420 0060 3557 BESTAND TXT .`5W
00000144 E936 E936 0000 3657 E936 0300 1E00 0000 .6.6..6W.6......
00000160 E546 0069 006C 0065 002E 000F 0019 7400 .F.i.l.e......t.
00000176 7800 7400 0000 FFFF FFFF 0000 FFFF FFFF x.t.............
00000192 E549 4C45 2020 2020 5458 5420 0012 1D5B .ILE TXT ...[
00000208 E936 E936 0000 205B E936 0000 0000 0000 .6.6.. [.6......
00000224 4146 0069 006C 0065 002E 000F 0019 7400 AF.i.l.e......t.
00000240 7800 7400 0000 FFFF FFFF 0000 FFFF FFFF x.t.............
00000256 4649 4C45 2020 2020 5458 5420 0012 1D5B FILE TXT ...[
00000272 E936 E936 0000 205B E936 0400 6100 0000 .6.6.. [.6..a...
00000288 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000304 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000320 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000336 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000352 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000368 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000384 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000400 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000416 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000432 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000448 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000464 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000480 0000 0000 0000 0000 0000 0000 0000 0000 ................
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.
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.
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
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.
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
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
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
I'll soon share the source with everybody on my website: www.ingeniuz.nl
( I'm working on it, so please be patient )
>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 !
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