0
\$\begingroup\$

I am interfacing a microSD card with a microcontroller. The following code snippet is taken from Application note 189 (AN189), MMC DATA LOGGER EXAMPLE on page no. 30. The MMC_Command_Exec() basically implements the details to send the appropriate commands to the microSD card.

// Send the SEND_OP_COND command until
// the MMC indicates that it is no
// longer busy (ready for commands).
do
{
    SPI0DAT = 0xFF;
    while (!SPIF) {
    }
    SPIF = 0;
    card_status.i = MMC_Command_Exec(SEND_OP_COND,EMPTY,EMPTY);
}
while ((card_status.b[0] & 0x01))
    ;

I am not able to understand what is the need of sending FF (instruction SPI0DAT = 0xFF;) prior to sending the command using MMC_Commd_Exec?

I have checked that if I remove SPI0DAT = 0xFF;, and put a delay of 200 ms and even more then I never get a correct result.

Also, I can see at other places that this type of dummy data was not sent, for example:

// Read the Operating Conditions Register (OCR).
do
{
    card_status.i = MMC_Command_Exec(READ_OCR,EMPTY,pchar);
}
while (!(*pchar&0x80))
    ; // Check the card busy bit of the OCR

So the simple question is when to send and when not to send.

\$\endgroup\$
3
\$\begingroup\$

The SPI bidirectional protocol requires that any time the master might try to exchange a byte of data, the slave always be ready to take in a byte of data and spit one out. The master will feed the slave a byte on MOSI without regard for whether or not the slave is ready to do anything useful with it, and whatever the slave does on the MISO pin will be interpreted as a byte of data by the master whether or not the slave had anything useful it wanted to say.

To deal with this, many SPI chips define their behavior such that the first byte following a chip select will indicate whether the device is ready to do anything with a command request other than drop it on the floor. Effectively, the first thing the master does is ask "are you ready?" If the slave answers "no", the master may ask repeatedly as often as it wants until the slave says "yes". Such a design is fairly simple to implement on the slave side, and is fairly easy to use from the master side. Further, it's generally not to hard to subdivide the different kinds of operations a device can perform into steps which are small enough that once the slave is ready to begin performing a step, it will be able to exchange all the data with that step as fast as the master cares to clock it, without further delay.

One slight wrinkle in all of this is that some slaves may need pulses on the clock wire in order to perform certain operations. As a common example, many designs expect to latch all 8 bits of the next byte they're going to send before they receive the first clock pulse. If a device which is primed to send a byte that says "not ready" becomes ready, it would have no way of knowing whether a clock pulse might arrive just as it was getting ready to change the next byte it transmitted, causing that byte to contain a mix of old and new data. One way of avoiding such a danger is to have a device decide on the sixth clock cycle of each byte whether it's going to report itself as ready on the following byte. Even if the device becomes ready just as it receives the sixth cycle of a byte, by the time the eight cycle was received the device would have had a chance to make up its mind as to whether it thought it became ready before the sixth cycle (in which case the next byte should report "ready") or failed to do so (in which case it should report another "not ready" byte).

\$\endgroup\$
1
\$\begingroup\$

I would guess it's a placeholder to allow the processor on the card to do some local data processing.

It's also possible that the logic on the card is using the SPI clock to clock some internal registers. In that case, it may need the 8 clock cycles produced by writing SPI0DAT to prepare it's response.

From page 5 of the document you link:

Before the MMC can be used, it must be properly 
powered on and initialized. It must also be configured to 
SPI mode. Figure 5and the following steps show the 
initialization sequence:
1. After receiving power, transmitat least 74 SPI clock cycles 
so that all internal start up operations can complete.
2. Drive the CS pin low.
3. Transmit a CMD0 to switch the card into SPI mode.
4. Transmit 8 SPI clock cycles.
5. Transmit a CMD1.
6. If the response to CMD1 indicates that the card is busy, go 
back to step 4. Otherwise, the card initialization is 
successful and the card can now receive and respond to 
commands.
7. Once the card is initialized, the size must be determined. 
This is done by retrieving the card specific data register 
(CSD) using CMD9 (SEND_CSD). The card size fields are 
located within this register. See the comments of the Flash 
initialization function on MMC_FLASH_Init()for specific 
implementation details.

And page 6:
enter image description here

I think, for the moment, you should simply assume it's a vagary of the SD card design. Unless you can get the low-level documentation of the SD/MMC interface protocol, that's about all you can really determine.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ A simplified version of the spec can be downloaded from sdcard.org. Compare Part1 Figure 7-2 - sdcard uses ACMD41 as SEND_OP_COND alternative. \$\endgroup\$ – Turbo J Jul 30 '13 at 11:17
1
\$\begingroup\$

Some SD cards require extra clock cycles to prepare for the next command. Sending one-byte dummy data is effectively giving the card eight cycles.

But it's more common to wait for a not-busy response from the SD card (repeatedly sending 0xFF). While the SD card is busy, some hold its "output pin" high, thus the data clocked out of it is always 0xFF.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.