ASF4 HSMCI SD card initialization example?

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Anybody have an example of using the mci_sync_* methods to initialize an SD card? I've got an Atmel Start project going. I've done SD card in SPI mode before, but part of the whole purpose of this chip is the ability to use 4 bit mode. Every command I send gives back a 0 from mci_sync_get_response(), so I have little confidence that it's actually talking to the card properly.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The magic appears to be ORing in some constants to the command value. For example

    if (!mci_sync_send_cmd(&MCI_0, 8 | MCI_RESP_PRESENT | MCI_RESP_BUSY, 0x1aaUL))

        goto error;

    resp = mci_sync_get_response(&MCI_0);

    if ((resp & 0xff) != 0xaa)

        goto error;

That works. Alas, ACMD41 is not presently working. Still trying to figure that one out.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, I'm stuck.

    delay_ms(10);

    mci_sync_send_clock(&MCI_0); // send the initialization clock cycles

    delay_ms(10);

 

    if (!mci_sync_send_cmd(&MCI_0, 0, 0)) // GO_IDLE - reset

        goto error;

 

    if (!mci_sync_send_cmd(&MCI_0, 8 | MCI_RESP_PRESENT | MCI_RESP_CRC, 0x1aaUL))

        goto error;

    resp = mci_sync_get_response(&MCI_0);

    if ((resp & 0xfff) != 0x1aa)

        goto error;

 

    uint32_t timeout_start = millis;

    volatile bool ready = false;

    do {

        delay_ms(1);

        ready = mci_sync_send_cmd(&MCI_0, 55 | MCI_RESP_PRESENT | MCI_RESP_CRC, 0);

        resp2 = mci_sync_get_response(&MCI_0);

        ready = mci_sync_send_cmd(&MCI_0, 41 | MCI_RESP_PRESENT, 0x40000000UL);

        resp = mci_sync_get_response(&MCI_0);

        if (millis - timeout_start > INIT_TIMEOUT) goto error;

    } while(!ready || !(resp & 0x80000000UL));

 

What's happening is that the rest value from the response to the ACMD41 never has the !busy bit (bit 31) set. According to the spec, I'm supposed to use CMD0, then CMD8 to validate the basic voltage constraints, then loop on ACMD41 for up to a second until the busy bit is 1. That never happens.

HELP!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I got past that. It turns out that the argument to ACMD41 must have at least one of the power bits set or the card won't see it as a request to initialize. The sequence is CMD0, ACMD41, CMD2, CMD3, CMD9 (to get block count), CMD7, ACMD42, ACMD6 (entering 4 bit mode) and CMD7 with a zero RCA to deselect.

I've gotten the card to initialize fully and have successfully read a block using CMD7, CMD17 followed by CMD7 with a zero RCA.