Go Down

Topic: sd card (Read 5 times) previous topic - next topic

carl47

#5
Jun 22, 2010, 08:40 am Last Edit: Jun 22, 2010, 08:56 am by carl47 Reason: 1
Sorry for the delay.  I usually check my mail every day.

The pins are defined in the .h file.

In that file change:
#define setupDDRB DDRB |= 0x2c;  //set SS as output for cs
#define selectSDCARD PORTB &= ~0x04;  //set the SS to 0 to select the sd card
#define deselectSDCARD PORTB |= 0x04;  //set the SS to 1 to deselect the sd card

To:

#define setupDDRB DDRB |= 0x28;  //set SS as output for cs
#define setupDDRD DDRD |= 0x20;  //set SS as output for cs
#define selectSDCARD PORTD &= ~0x20;  //set the SS to 0 to select the sd card
#define deselectSDCARD PORTD |= 0x20;  //set the SS to 1 to deselect the sd card

In the .ccp file add:

setupDDRD;

after setupDDRB; in the function
unsigned char SDCARDclass::SD_reset(void)

While you are in the .h file delete all the ; at the end of the define macro statements. Its not correct to have them see:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1268083394

Let me know if this works for you.

stolken

I'll try it asap and tell you if it works, thanks a lot for your help  ;)

stolken

So :
I edit it tonight and it doesn't work  :(

I understand I should remove all the ; in the define statement so I write this :

Code: [Select]

#define setupSPI SPCR = 0x53 //Master mode, MSB first, SCK phase low, SCK idle low, clock/64
#define deselectSPI SPCR = 0x00  //deselect SPI after read write block
#define clearSPI  SPSR = 0x00 // clear SPI interupt bit
#define setupDDRB DDRB |= 0x28  //set SS as output for cs
#define setupDDRD DDRD |= 0x20  //set SS as output for cs
#define selectSDCARD PORTD &= ~0x20  //set the SS to 0 to select the sd card
#define deselectSDCARD PORTD |= 0x20  //set the SS to 1 to deselect the sd card


I'm right ?
If I do this, I get some serious errors while compiling with arduino.




Another issue is you tell me to add in the .cpp :

Code: [Select]
setupDDRD;

before

Code: [Select]
setupDDRB;


but in the  unsigned char SDCARDclass::SD_reset(void)
I only have
Code: [Select]
setupDDRB  without ;

Can you explain me what I need to do ?

Thanks again.  ;)




CowJam

I'd like to give your code a try - how do I wire an SD card to the arduino?
Do you have a schematic for it?

carl47

I'm sorry I should not have mentioned the ;
It has confused the issue And I will be more careful
in future. I will also check that the code I give does compile.

#define setupDDRB DDRB |= 0x2c;

The define is just a compiler directive to repace any occurance
of:

setupDDRB

With:

DDRB |= 0x2c;

As I have left off the ; throughout the .cpp file you do need
the ; in the define in the .h file.

0x2c in binary = 0010 1100
The data direction register B is being set.

The chip select pin is bit 2 ie PB2.
We dont need it any more so use:

DDRB |= 0x28;

Your circuit uses PD5 so we need to set the data direction register D:

DDRD |= 0x20;

Then use PD5 as the select anfd deselect pin.

So here is the .h file which does compile:


Code: [Select]
#ifndef SDCARD_h
#define SDCARD_h

#define setupSPI SPCR = 0x53; //Master mode, MSB first, SCK phase low, SCK idle low, clock/64
#define deselectSPI SPCR = 0x00;  //deselect SPI after read write block
#define clearSPI  SPSR = 0x00; // clear SPI interupt bit

#define setupDDRB DDRB |= 0x28;  //set SS as output for cs
#define setupDDRD DDRD |= 0x20;  //set SS as output for cs
#define selectSDCARD PORTD &= ~0x20;  //set the SS to 0 to select the sd card
#define deselectSDCARD PORTD |= 0x20;  //set the SS to 1 to deselect the sd card

#include "WProgram.h"

class SDCARDclass
{
public:
unsigned char readblock(unsigned long Rstartblock);
unsigned char writeblock(unsigned long Wstartblock);

private:
unsigned char SD_reset(void);
unsigned char SD_sendCommand(unsigned char cmd, unsigned long arg);
unsigned char SPI_transmit(unsigned char data);

};//end of class SDCARDclass

extern SDCARDclass SDCARD;


Here is the new unsigned char SDCARDclass::SD_reset(void) which does compile:

Code: [Select]
unsigned char SDCARDclass::SD_reset(void)
{
unsigned char response;
unsigned int retry = 0;
setupDDRB
setupDDRD
setupSPI
clearSPI
/* After power up (including hot insertion, i.e. inserting a card when the bus is operating) the SD Card
enters the idle state. In case of SD host, CMD0 is not necessary. In case of SPI host, CMD0 shall be
the first command to send the card to SPI mode.*/
do
{
  response = SD_sendCommand(0, 0); //send 'reset & go idle' command
  if(++retry>254){
  return 1;}  
} while(response != 0x01);
/*CMD1 is not recommended because it may be difficult for the host
to distinguish between MultiMediaCard and SD Memory Card.
but we will never use a MMC card so take easy route.
For the Thick (2.1 mm) SD Memory Card - CMD1 (SEND_OP_COND) is valid*/
retry=0;
do
{
   response = SD_sendCommand(1, 0); //activate card's initialization process
   if(++retry>254){
   return 2;}  
}while(response);
//CRC disabled in SPI mode so we will keep it that way.
retry = 0;
do
{  
 response = SD_sendCommand(16, 512); //set block size to 512
 if(++retry>10)
 return 8;            //time out  
}while (response);
return 0;
}//end of SD_reset function


Let hope that It will run your sd card!

Go Up