cancel
Showing results for 
Search instead for 
Did you mean: 

SD Card example on MCB-STR9

gkruger
Associate II
Posted on July 05, 2007 at 16:56

SD Card example on MCB-STR9

8 REPLIES 8
gkruger
Associate II
Posted on May 17, 2011 at 09:44

Hello,

Has anyone got a SD Card working on the MCB-STR9 (Keil evaluation board) or on the str912fw44 for that matter?

The problem I have is that I can see on the scope that the Chip Select(nss)goes high after every byte sent, and then the SD Card does not respond correctly if that happens.

I started with just a basic program, trying to send the IDLE command and waiting for the 0x01 response.

So I decided to use another GPIO pin and do the chip select manually( I tried to set the nss pin as a gpio and control it manually but couldn't get it to switch).

Now I can see that the Card responds correctly on the scope. But when I start sending the IDLE command, the MISO is low, and only goes high after the first clock. This gives me 0x7f (0b011111111) and when I receive the data, instead of the 0x01 (which I can see on the scope, and is only sent much later). This did not happen when I used the correct NSS pin, has anyone else had a similar problem?

Code:

GPIO_WriteBit(GPIO7, GPIO_Pin_7, Bit_RESET);

sd_Command(0, 0, 0); //Sends the IDLE command

while( SSP_GetFlagStatus(SSP0, SSP_FLAG_TxFifoEmpty) != SET );

resp=sd_Resp8b(); //Sends 0xff until response has been received

while( SSP_GetFlagStatus(SSP0, SSP_FLAG_TxFifoEmpty) != SET );

GPIO_WriteBit(GPIO7, GPIO_Pin_7, Bit_SET);

I have to check the status to see whether the data has been sent before continuing, unfortunately the flag is set before the last byte is transmitted, so I set the CS high one byte to early. Any simple way of doing this without using a timer?

Any comment suggestions? I hope I did something wrong and there is a way of keeping the nss pin low for the whole transaction (surely if the sd connector is on the board you should be able to).

Regards,

Gert

ben2
Associate II
Posted on May 17, 2011 at 09:44

If this is the first idle command to get the card into SPI mode I had some similar problems on 1 board, when switching from SanDisk to Kingston SD cards.

Basically you can always ignore the first byte back from the SD card, as all commands needs at least one byte, and you will probably find the second byte is 0x01.

I think the problem is, that for the first few clocks after the initial IDLE command the SD card is still in the process of switching from SD card mode to SPI mode. I think in SD card mode the data pin is tri-stated and will sometime float low and sometimes high. After a couple of clock pulses the interface switches to SPI mode and drives the data out line high, hence the data you are seeing. If you clock in a second byte it will probably be 0x01.

Ben

roger_lynx
Associate II
Posted on May 17, 2011 at 09:44

The problem I have is that I can see on the scope that the Chip Select(nss)goes high after every byte sent, and then the SD Card does not respond correctly if that happens.

It is easier to de-couple the CS from the rest of the SPI signals, in the light of the following sentence from the MMC ver. 3.3 specs (same for SD in SPI mode):

 

The CS signal must be continuously active for the duration of the SPI transaction (command, response and data). The only exception is card-programming time. At this time the host can de-assert the CS signal without affecting the programming process.

Hope this helps?

roger_lynx
Associate II
Posted on May 17, 2011 at 09:44

Basically you can always ignore the first byte back from the SD card, as all commands needs at least one byte, and you will probably find the second byte is 0x01.

I am not sure what you mean by ''ignore the first byte'', since it is required to provide the card with NCR/NRC clocking, as stated in specs:

After the last SPI bus transaction, the host is required to provide eight clock cycles for the card to complete the operation before shutting down the clock. The state of the CS signal is irrelevant throughout this eight-clock period.

gkruger
Associate II
Posted on May 17, 2011 at 09:44

Hi guys,

Thanks for the answers!

Quote:

It is easier to de-couple the CS from the rest of the SPI signals, in the light of the following sentence from the MMC ver. 3.3 specs (same for SD in SPI mode):

I tried to de-couple the CS pin by setting it up as a GPIO, but when I do a GPIO_WriteBit the pin doesn't respond.

With GPIO setup:

Code:

GPIO_InitTypeDef GPIO_Struct;

GPIO_StructInit( &GPIO_Struct );

GPIO_Struct.GPIO_Direction = GPIO_PinOutput;

GPIO_Struct.GPIO_Pin = GPIO_Pin_7;

GPIO_Struct.GPIO_Type = GPIO_Type_PushPull ;

GPIO_Struct.GPIO_IPConnected = GPIO_IPConnected_Disable;

GPIO_Struct.GPIO_Alternate = GPIO_OutputAlt1; //Instead of OuputAlt2, thus decoupling?

GPIO_Init (GPIO5, &GPIO_Struct);

So that is why I have changed to another pin (Which works). But because the Keil Eval board already has a sd card holder, and they connected pin5.7 to the CS I figured there has to be a way to get it working?

Regards,

Gert

ben2
Associate II
Posted on May 17, 2011 at 09:44

Perhaps I was not very clear, when I say ignore the first byte back. Obviously you need to transmit 0xff after the command, until you have clocked in the required amount of bytes. In all instances I have seen the first byte back after the command is 0xff. However as I said, I have seen 1 instance where the first byte back after the command was 0x7f after the initial IDLE command to put the SD card into SPI mode.

In case of seeing a different byte on a scope as to what is being received I would check to make sure the receive FIFO is completely empty before sending the IDLE command. If it is not emptied first what you see on a scope will not match what you get out of the FIFO.

gkruger
Associate II
Posted on May 17, 2011 at 09:44

Hi Ben,

Thanks, I understood what you meant. I can actually see on the scope that the card takes 8 clocks before responding(I see 0xff) and then I get the 0x01. And you are correct that I did not empty the fifo, when I sent the IDLE command (0x40,0x00,0x00,0x00,0x00,0x95) the incoming fifo was filling up with data (the MISO is high) so end up with a fifo buffer full of 0xff (the first byte was 0x7f), after enough reads from the Data Register I get the right data.

I now clear the fifo as follows after I have sent the cmd, but before I send out 0xff and check for response.

Code:

while( (SSP_GetFlagStatus(SSP0, SSP_FLAG_RxFifoNotEmpty) == SET)&&(i<8)) //wait till Rx FIFO is not empty

{

Fifo[i++] = SSP_ReceiveData(SSP0);

}

Kind Regards,

Gert

roger_lynx
Associate II
Posted on May 17, 2011 at 09:44

Perhaps I was not very clear, when I say ignore the first byte back

:-[

Obviously you need to transmit 0xff after the command, until you have clocked in the required amount of bytes.

 

In all instances I have seen the first byte back after the command is 0xff.

Obviously... :o ... since you are sending out 0xFF, the MCU's shift register is receiving 0xFF.....ne pas?

In SPI's master mode, receiving cannot happen without transmitting - there is no smoke without fire, hm?

Unless...you mean to say that the first MM/SDC response is 0xFF,

which I doubt it could happen since R1 response with ALL errors = ON can be 0x7F (most significant bit is always zero)...and R1b response is R1 followed by either 0xFF (or non-zero) = READY or 0x00 = BUSY.

So...the first byte back is your own transmitted byte, and the card's response is the following byte in case of R1.

But you can get this info from the SPI/MMC specs, not only from my crude explanation:

See this:

http://elm-chan.org/docs/spi_e.html

and

that:

http://elm-chan.org/docs/mmc/mmc_e.html

This horse is beaten to death, figuratively speaking, of course.

:-[

[ This message was edited by: hARMless on 10-07-2007 02:58 ]