MC9S12XEP100 in EVB9S12XEP100: SD card issues

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MC9S12XEP100 in EVB9S12XEP100: SD card issues

2,646 Views
Rhapsody
Contributor III

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

Labels (1)
0 Kudos
7 Replies

480 Views
kef
Specialist I

Are you sure about CPOL and CPHA setting? Googling quicky revealed this

http://www.navyelectronic.com/images/Communication%20with%20MMCSD%20card%20via%20SPI%20protocol.pdf

 

and they state that SD/MMC requires CPOL=CPHA=0

0 Kudos

480 Views
EricChen
NXP Employee
NXP Employee

  /* SPI0CR1: SPIE=0,SPE=0,SPTIE=0,MSTR=0,CPOL=0,CPHA=1,SSOE=0,LSBFE=0 */
  SPI0CR1 = 4;                         /* Reset the device register */

Why the MSTR bit is not set?  And the CPOL/CPHA should be 0 for the MMC/SD .

0 Kudos

480 Views
Rhapsody
Contributor III

Actually, what you pointed out, is only the first write to that register within the init procedure, just to reset the SPI module, as stated by the examples and by the reference guide I have. The second write instead, set the MSTR to 1. Regarding the CPOL/CPHA, I've tried both configuration, either to 0 or to 1, nothing changed.

 

Thanks anyway,

ale 

0 Kudos

480 Views
Rhapsody
Contributor III

First of all, thanks for your time.

Actually, I've already double, and even more times, checked about CPOL and CPHA. From specs and app notes I've found out there, the clock should idle high and the samples are taken on the rising edge, so the configuration should be CPOL = CPHA = 1.

 

Anyway, I've tried also to use the configuration you suggested, with no valuable results. The card is not able even to initialize itself..

 

Thanks again,

 

Ale

Message Edited by Rhapsody on 2009-05-22 07:22 AM
0 Kudos

480 Views
Rhapsody
Contributor III

Addendum:

I've noticed that every command that has a standard R1 or R2 reply is correctly executed, and the answer correctly sent by the SD, even the GET_STATUS tells me that everything is fine (0x00 0x00).

But when I send the GET_CID or GET_CSD (getting erroneus answers) and then the GET_STATUS again, I get a weird reply, 0xc0 0x00, that doen's make sense, since each answer has to start with the MSB cleared..

 

This is driving me crazy, I really don't know how and where to act.. It has to work, but it doesn't..

 

Thanks again for any of you that can help me.

 

Ale 

0 Kudos

480 Views
Pedro_
Contributor III

Can you scope the SS line and check for noise?

0 Kudos

480 Views
Rhapsody
Contributor III

Yes, I've already checked the signals' noise, and the SPI module seems to read correctly what is on the cable.. Even the clock and SS are ok, even the timing seems to be ok, I'm using a very low clock, about 300 kHz, and I've tried also with lower values, as 12kHz, no changes.. So, I don't guess there is a problem with the hardware.. Even the power lines are clean enough..

And both the SD card I've tested are fully working with the PC SD card reader I have, under windows.. 

 

Thanks anyway for you help.

 

Ale 

0 Kudos