[TUT] SD card initialization and the Butterfly

Go To Last Post
27 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There's a lot of SD/MMC card info around, but most of it's not easy to wade through. This document tells specifically how to wire an SD card to a Butterfly, initialize it, and send commands.

There's no code, and you'll still have to do some research, but hopefully this will throw a little light on what's going on.

Please let me know if you have additions or corrections.

Attachment(s): 

Chuck Baird

"I wish I were dumber so I could be more certain about my opinions. It looks fun." -- Scott Adams

http://www.cbaird.org

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for writing the nice tutorial. I have a couple of questions:

1. I was wondering how do you set the clock to (SPR0, SPR1) be 400 KHz initially ?

2. The sparkfun socket has only one GND (Does this one short pins 3,6 internally) ?

3. What do we do with COM, WP and CD pins ?

thanks,
-sid

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

On the ATmega 169 the SPR0 and SPR1 (and SPI2X) bits set the SPI master clock rate at the frequency of the oscillator divided by 2, 4, 8, 16, 32, 64, or 128. To hit a specific frequency would require running your AVR at one of those multiples of the target frequency you want, then setting the bits accordingly.

I checked my Sparkfun socket and pins 3 and 6 are connected together on the breakout board and brought out to GND.

The Com pin goes to the metal housing (case), and the WP (write protect) and CD (card detect) lines go to switches located inside the socket. CD shorts to COM when a card is inserted. WP is supposed to short to COM when the card is not write protected (via its slide switch), but on my breakout board this does not work. It also doesn't work the other way, so either my board is defective (probably) or they didn't wire it up. Anyway, there's a difficult to understand schematic that shows Com, WP, and CD in the lower right hand corner.

Chuck Baird

"I wish I were dumber so I could be more certain about my opinions. It looks fun." -- Scott Adams

http://www.cbaird.org

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks. I have the IRQ, P9 connected to 10Kohm to supply voltage and the Com, WP, CD left open.

I have a question regarding setting clock to 400 KHz. The AT169 data sheet suggests using CLKPS[0-3] to divide the default clock frequency. However, I need a divider of 20 (8MHz/20 = 400 KHz), but CLKPS divides in powers of 2 (1, 2, 4, 8, ...)

I have posted this on avr-forums. Also, I am trying to get some code working on butterfly with SD card interface. If it works, I would like to attach it to the tutorial ?

-sid

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I guess I don't know why you need to have 400 KHz as the clock rate. The SPI master provides the clock, and if it needed to talk to something rated at 400 KHz, that would be the maximum speed. Anything slower (such as 8MHz/32) would work. Otherwise you can use an appropriate crystal to clock the AVR at less than 8MHz and choose it so that one of the divisors gives you the 400 KHz you want.

It's certainly fine with me for you to post code here.

Chuck Baird

"I wish I were dumber so I could be more certain about my opinions. It looks fun." -- Scott Adams

http://www.cbaird.org

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have the following code currently as per the tutorial. However, it does not work with the AVR-Butterfly:

+-----------------------------
#define SD_PORT PORTE
#define SD_DDR DDRE
#define SD_SPI_CS PE4 //Use PE4 as chip sel

#define SD_SPI_PORT PORTB
#define SD_SPI_DDR DDRB
#define SD_SPI_SS PB0
#define SD_SPI_SCK PB1
#define SD_SPI_MOSI PB2
#define SD_SPI_MISO PB3

void SPI_Init(void) {
uint8 dummy, i;

SBI(SD_SPI_DDR, SD_SPI_SS); // set PB0 as op
SBI(SD_SPI_PORT, SD_SPI_SS); // set PB0 to 1
SBI(SD_SPI_DDR, SD_SPI_SCK);
SBI(SD_SPI_DDR, SD_SPI_MOSI);
CBI(SD_SPI_DDR, SD_SPI_MISO);
SBI(SD_DDR, SD_SPI_CS);
SBI(SD_SPI_PORT, SD_SPI_CS);

SBI(SPCR, MSTR); // Master
CBI(SPCR, CPOL); // CPOL, CPHA = 0, 0 => mode0
CBI(SPCR, CPHA);
CBI(SPCR, SPR0); // Fosc/64 ~ 125 KHz
SBI(SPCR, SPR1);
CBI(SPCR, DORD);
CBI(SPCR, SPIE); // No SPI interrupt enable
SBI(SPCR, SPE); // Write to SPCR

dummy = SPSR;
dummy = SPDR;
}

char SPI_byte(char c) {
char rcv = 0, i;
SPDR = c;
//while (!(inb(SPSR) & (1<<SPIF)));
loop_until_bit_is_set(SPSR, SPIF);
rcv = SPDR;
i = SPSR;
return rcv;
}

char SD_Init(void) {
unsigned int i;
char rcv;

SBI(SD_PORT, SD_SPI_CS); //Deselect SD
for (i = 0; i < 10; i++)
rcv = SPI_byte(0xff);
Delay(1);
CBI(SD_PORT, SD_SPI_CS); //Select SD

SPI_byte(0x40);
SPI_byte(0x00);
SPI_byte(0x00);
SPI_byte(0x00);
SPI_byte(0x00);
SPI_byte(0x95);

for (i = 0; i < 10; i++)
if((rcv = SPI_byte(0xff)) != 0xff)
break;
SBI(SD_PORT, SD_SPI_CS);

return rcv;
}

main() {
char buf[32], c;

CLKPR = (1<<CLKPCE);
CLKPR = (0<<CLKPS1)|(0<<CLKPS0); //clk = 8MHz
UART_Init();
LCD_Init();
SPI_Init();

c = SD_Init();
if (c == 0x01) {
} else {
sprintf(buf, "%d\n", c);
UART_Puts("fail\n");
UART_Puts(buf);
}
while(1);
}
+----------------------------------------------

When I run the code above, SD_init returns -1 (255). Not sure if there is something wrong with the code. I have the SD card connected to sparkfun.

-sid

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
However, it does not work with the AVR-Butterfly:

Actually, I meant working code. This forum isn't really the place to be debugging something. You might want to post this over on the AVR forum to have someone have a look at it.

Chuck Baird

"I wish I were dumber so I could be more certain about my opinions. It looks fun." -- Scott Adams

http://www.cbaird.org

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi..could you please tell me if the same procedure applies to interfacing an sd card to atmega32??? I am finding it really difficult to interface the sd card alone..leave the other peripherals.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@pvvikas

If you use 5v you have to use some sort of voltage adaption , as a SD/MMC uses 3.3v.

Maybe have a look here
http://www.ulrichradig.de/home/i...

Minimal schematic
http://www.ulrichradig.de/site/a...

The full "Bells & Whistles"
http://www.ulrichradig.de/site/a...

But if you use an ATmega32L @ 3.3v then i'd guess the same principle applies.

Btw: This site contains a lot of usefull info for SD/MMC , and a working FAT implementation at the bottom.
http://elm-chan.org/docs/mmc/mmc...

/Bingo

/Bingo

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i am working on interfacing an SD card to an ATMEGA32 . This setup needs to be used in a data acquisition system such that a certain parameter needs to be polled and logged every minute, the log being stored onto the SD card. something like one text file for each day containing that day's log for every minute. As i understand it, I have broken this up into 2 steps:

1)the task of acquiring data and storing it as a text file(using an ASCII header to indicate it to be a text file)

2)sending this data into the SD card and storing it in such a way that when used with a PC, the SD card folder contains text files containing a particular days readings for each minute.

please let me know if this can be implemented? if so, what is the easiest method to acheive it??

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not sure how that's immediately relevant to this thread but you might want to say what development language you are using. If it happens to be avr-gcc then a Google for "fatfs" (and a search for that here on Freaks) will be useful.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have interfaced an atmega32 to a 1GB SD card(Transcend). I can write and read a single block of data(=512 bytes) successfully. The problem comes when I try to read multiple blocks. No matter what I do, I am getting "CMD18 error". Could you please suggest a feasible solution?
Here's that chunk of code which is causing troubles..

CMD18();
for(i=0;i<50;i++)
{
if(SPI(0x0FF)==(char)0x00)
{
usart_puts("CMD18 success!");
goto read_data1;
}
}

usart_puts("CMD18 error"); return 0;

read_data1:

and the function CMD18() goes like..
void CMD18(void)
{
SPI(0x52);
SPI(0x00);
SPI(0x00);
SPI(0x05);
SPI(0x12);
SPI(0x0FF);
}
--
Regards

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is off the top of my head, and may be completely wrong, but try it with a smaller (~256K) card and see if it works. I have some vague memory of problems (i.e., other requirements) for big cards.

Chuck Baird

"I wish I were dumber so I could be more certain about my opinions. It looks fun." -- Scott Adams

http://www.cbaird.org

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chuck, you are the man :)

I very much recommend your tutorial on using SD card. Real time-saver. Thumbs up!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi All ,

Can any one please post or send me the link where in I can find the basic structure code for Interfacing SD Card with AVR Microcontroller.

Hello Chuck,
Can you please send the code related to the your Tutorial so that I can start testing the SetUp, where I have interfaced 1 GB SanDisk SD Card with ATmega32L.

Thanks a Lot !!

Mandar Bagul.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello Chuck Baird,

Thanks a LOT !! for the posting the tutorial - SD and Butterfly.doc

Its a very handy - easy to implement Document.

after refering your documnet I was able to sucessfully Initilze the 256 MB SD Card.

But, I had issues in initilizing the 1 GB SD card
Is there any timing Issue ?

Thanks once again.

-Mandar Bagul
India

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
But, I had issues in initilizing the 1 GB SD card
Is there any timing Issue ?

I think the answer is yes, but I don't know what they are. See the post about 3 or 4 prior to this one.

Please do some searching and looking around, and when you find out the answer to this, post it here. I've kind of moved on to other things myself, but I would also like to know what the issues are.

Thanks. Sorry I don't have the information myself.

Chuck Baird

"I wish I were dumber so I could be more certain about my opinions. It looks fun." -- Scott Adams

http://www.cbaird.org

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello Chuck Baird,

Today, I have tried out interfacing the 1 GB SD Card from Transcend & it work fine !!

Conclusion : The tutorial - SD and Butterfly.doc is valid for 1 GB SD Card from Transcend.

Thanks a Lot once again !!

-Mandar Bagul.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe I am blind but I cant see any doc file nor link to any tutorial. Can anyone give a link to that tutorial ?

Regards.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

update: double post

Last Edited: Fri. Jun 13, 2008 - 11:16 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

See that little grid with the word "download" over towards the right in the first post? Do you not get a .doc file delivered when you use that then?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hah, i need to be logged to see that little grid ;)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

qhash wrote:
Maybe I am blind but I cant see any doc file nor link to any tutorial. Can anyone give a link to that tutorial ?

Regards.

Maybe not blind, but not very goot at looking either :wink:

https://www.avrfreaks.net/index.php?name=PNphpBB2&file=download&id=6468 is the link, its Chucks credit tho, you can find it in the post at the top of this page (page 2).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

pvvikas wrote:
i am working on interfacing an SD card to an ATMEGA32 . This setup needs to be used in a data acquisition system such that a certain parameter needs to be polled and logged every minute, the log being stored onto the SD card. something like one text file for each day containing that day's log for every minute. As i understand it, I have broken this up into 2 steps:

1)the task of acquiring data and storing it as a text file(using an ASCII header to indicate it to be a text file)

2)sending this data into the SD card and storing it in such a way that when used with a PC, the SD card folder contains text files containing a particular days readings for each minute.

please let me know if this can be implemented? if so, what is the easiest method to acheive it??

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hai

My project is almost similar to your project.
In my project I am using SD Card interface to AT89c5131. So plz can you give some idea on how to initialize the SD card and access the data.

Thanks & Regards ,
Umadevi.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Umadevi,

What has your post got to do with SD on a Butterfly (the subject of this thread)? Or AVR8 for that matter?

Anyway, look at http://elm-chan.org/fsw/ff/00ind... - there's code there for AVR, H8/300H, TLCS-870/C, PIC and V850ES so it shouldn't be too difficult to follow the same pattern and also port it to AT89.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is one thing I miss in the tutorial, how the SPI should be defined. (At least I can't find the information). The SPI bus on the AVR can be defined with for example CLK high when idle and sample on rising edge. For the tutorial to be complete I think this information should be added.

Also we have the 400 kHz issue. Is this needed or not on a SD card? At what point can you switch to faster speed? (Must be after the initialization).

My favorites:
1. My oscilloscope, Yokogawa DLM2024.
2. My soldering iron, Weller WD2M, WMRP+WMRT.
3. JTAGICE3 debugger.