Alessandro Audero

MC9S12XEP100 in EVB9S12XEP100: SD card issues

Discussion created by Alessandro Audero on May 21, 2009
Latest reply on Jun 15, 2009 by Alessandro Audero

Dear all,

 

I really hope finding someone can help me with solution of these issues.

 

I'm using the evaluation board and the processor described by the subject and trying to communicate with several SD cards.

 

I'm using the SPI0 module on board and the SPI protocol of the SD card.

The processor is powered at 3.3V, so the SD card, then no level shifting is required. The power supplies share the same 0V. Data line are pull up'd with 47k, the power of the SD seems to be clean enough, so the data and clock signals.

 

I've initialized the SPI module without autmatic use of SS, which I act by myself, as suggested all around.

 

I'm able to init the card, the card becomes read.

 

But when I try to read, for example, the CID register, or the CSD register, I receive data that I'm not expecting and that doesn't fit the specs of the SD card.

For example, after a SEND_CID command, I should receive an R1 answer then the start data block, 0xFE and then the data. Instead, I receive something like 0x00 0xFC and then data that is not correct, since it has no mean.

 

here are my SPI routines:


void SPI0_assertSS(void) { PTS_PTS7 = 0; }void SPI0_deassertSS(void) { PTS_PTS7 = 1; }byte SPI0_XferByte(byte b) {  while(SPI0SR_SPTEF == 0) {}; SPI0DR = b; while((SPI0SR & 128) == 0) {}; return SPI0DR;}void SPI_Init(void) {  /* SPI0CR1: SPIE=0,SPE=0,SPTIE=0,MSTR=0,CPOL=0,CPHA=1,SSOE=0,LSBFE=0 */  SPI0CR1 = 4;                         /* Reset the device register */  #pragma MESSAGE DISABLE C4002        /* Disable warning C4002 "Result not used" */  SPI0SR;                              /* Read the status register */  SPI0DR;                    /* Read the device register */  /* SPI0BR: ??=0,SPPR2=0,SPPR1=1,SPPR0=0,??=0,SPR2=0,SPR1=1,SPR0=0 */  SPI0BR = 0x77;                         /* Set the baud rate register */  /* SPI0CR2: ??=0,??=0,??=0,MODFEN=0,BIDIROE=0,??=0,SPISWAI=0,SPC0=0 */  SPI0CR2 = 0;                         /* Set control register 2 */  /* SPI0CR1: SPIE=0,SPE=0,SPTIE=0,MSTR=1,CPOL=1,CPHA=1,SSOE=0,LSBFE=0 */  SPI0CR1 = 0x1c;                        /* Set control register 1 */  SPI0CR1_SPE = 1;                     /* Enable device */    }

 

 

and here my SD card routines:

 

 


byte CMD0[6]   = { 0,    0x00, 0x00, 0x00, 0x00, 0x95 };byte CMD1[6]   = { 1,    0x00, 0x00, 0x00, 0x00, 0x95 };byte CMD55[6]  = { 55,   0x00, 0x00, 0x00, 0x00, 0x95 };byte ACMD41[6] = { 41,   0x00, 0x00, 0x00, 0x00, 0x95 };byte CMD17[6]  = { 17,   0x00, 0x00, 0x00, 0x00, 0x95 };byte CMD58[6]  = { 58,   0x00, 0x00, 0x00, 0x00, 0x95 };byte CMD16[6]  = { 16,  0x00, 0x00, 0x02, 0x00, 0x95 };byte CMD10[6]  = { 10,  0x00, 0x00, 0x00, 0x00, 0x95 };byte CMD9[6]  = { 9,   0x00, 0x00, 0x00, 0x00, 0x95 };void SD_Init(void) {  byte a = 0; unsigned int i = 0;  SCISendString(0, "S0\r\n", 4);   SPI0_deassertSS();   for (i = 0; i < 40; i++) SPI0_XferByte(0xff);     Sleep_us(500000);  SCISendString(0, "S1\r\n", 4);  SPI0_assertSS();  i = 0;   do {  a = SD_Cmd(CMD0);   if (i++ > 3000) {   SCISendString(0,"E0\r\n",4);   return;  }   } while(a != 0x01);  SCISendString(0, "S2\r\n", 4); i = 0; do {  a = SD_Cmd(CMD1);    Sleep_us(5000);  if (i++ > 65534) {   SCISendString(0,"E1\r\n",4);   return;  }        } while (a & 0x01); SPI0_deassertSS();  SCISendString(0, "\r\nS3\r\n", 6);  SD_SetBlockLenTo512();  SCISendString(0, "\r\nS4\r\n", 6);  SD_ReadCID();  SCISendString(0, "\r\nS5\r\n", 6); }void SD_ReadCID(void) { SPI0_assertSS(); SD_Cmd(CMD10);  SD_WaitReply(0xfe, 50);  SPI0_deassertSS();  }unsigned char SD_SetBlockLenTo512(void) { byte ret; SPI0_assertSS(); ret = SD_Cmd(CMD16); SPI0_deassertSS(); SCISendString(0,"L0\r\n",4); SCISendUChar(0, ret); SCISendString(0, "\r\n", 2); SCISendString(0,"L1\r\n",4); SPI0_deassertSS(); return 0; }

byte SD_Cmd(byte *cmd) {
int i = 0;
byte ret;

cmd[0] = (cmd[0] & 0x3f) | 0x40;

SPI0_XferByte(0xff);    
for (i = 0; i < 6; i++) ret = SPI0_XferByte(cmd[i]);
do {
  if (!(ret & 0x80)) break;
  if (i++ > 256) break;
  ret = SPI0_XferByte(0xff);
} while(1);

return ret;
}

As you probably have noticed, there is some debug printed out to the terminal via RS232.

 

I've followed the references that are on internet about SD card protocol, and I cannot find a way to correctly read the SD card registers, or even memory, and so on.

 

I've printed all bytes passed under the SPI module, but no ones in no occasion, had fit the specs of the SD SPI protocol.

 

If someone of you can help me, it will be very appreciated, since are two days of working in it..

 

Thanks in advance,

 

Regards,

 

Ale

Outcomes