This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

microSD for MSP430F5438A

Other Parts Discussed in Thread: MSP430F5438A

I am having trouble initializing a SanDisk 4G MicroSD HC card. I am using the MSP430F5438A processor. Funny thing is, even though the software slaa281b and sdcard_appnote_foust.pdf examples state that the card is not found (not initialized) I can read and write sectors. I have been reading the forums and tried a lot of good pointers but I still do not seem to initialize the card properly, I cannot seem to get card size (always returns zero) and I am getting garbage data as if the data is off by one byte...

The engineers have a 500873-0806 MMC socket on our device. P3.1 is attached to pin3 (CMD/DI) of the socket P3.2 is attached to pin 7 (DAT0/DO) of the socket P3.3 is attached to pin5 (CLK/SCK) of the socket and P3.4 is attached to pin2 (DAT3/nCS) of the socket.

This means I have to use UCB0. Is that a problem? I would hope not since both USCI modules support SPI Mode.

// P3.4 defaults as MMC nCS GPIO

P3OUT |= BIT4;  // set MMC CS high, CS is active low

P3DIR |= BIT4;   // enable P3.4 as output

 

// P3.2 defaults as MMC MISO input

P3SEL |= BIT2; // enable USCI_B0 option select

// MMC MOSI

P3OUT |= BIT1; // set MMC SIMO high

P3DIR |= BIT1; // enable P3.1 as MMC MOSI output

P3SEL |= BIT1; // enable USCI_B0 option select

// MMC SCLK

P3OUT |= BIT3; // set MMC CLK high

P3DIR |= BIT3; // enable P3.3 as MMC SCLK output

P3SEL |= BIT3; // enable USCI_B0 option select

I read that Mode 0 is defined for SDC. Thus the Mode 0(CPHA=0, CPOL=0) is the proper setting to control MMC/SDC. I've read that the TI chip uses the opposite definition of "phase" from standard so I set the control bits to be: UCCKPH=1 and UCCKPL=0.

switch(mode)

{

case SPI_MODE_ZERO:   // CPOL=0;CPHA=0;UCCKPL=0;UCCKPH=1;

UCB3CTL0 &= ~UCCKPL; // Clock polarity low

UCB3CTL0 |= UCCKPH;    // Clock phase high

break;

.

.

.

}

I also set the speed below 400Hz...

UCB0CTL1 |= UCSSEL_2; // SMCLK (1MHZ)

UCB0BR0 = 3; // divide clock by 3 (1.04 / 3 = @350Hz

UCB0BR1 = 0;

The rest of the code is in slaa281b with a little input from foust...

What should I do next?

  • The different card types (SD, HD, XD) are using different versions of the card information, where the different fields have slightly different meanings (othe factors due to the larger capacity, etc.)

    Also, for HD and XD cards, address values for read and write are sectors while on SD cards, address was in bytes. So you are most likely misinterpreting the information about card size (because using the wrong format) while your read and write go to a totally different location on the card (but read back from the the same wrong location properly).

    However, in your code, you enable a lot of interrupts but you don't have any ISR to handle them.

    Also, you don't synchronize your code with the transmission progress. You just fire your data into TXBUF as fast as you can, overwriting the unsent data in the buffer.

    Please check the diagrams in the users guide. They tell you the proper order of events and software action for a transfer.

    I suggest raading a few of the many other threads about I2C and SD cards in this forum.

  • Jens-Michael Gross:

    Thanks for the reply. The information about many different types of cards (i.e. SDSC, SDHC, etc) was interesting and I ended up learning a great deal from foust and elm-chan. The TI code example was basically for SDSC cards only. There is another more involved sequence of initializing SDHC cards which I am sure you are aware of.

    Actually, the real basic issue was right in front of my eyes:

    case SPI_MODE_ZERO: // CPOL=0;CPHA=0;UCCKPL=0;UCCKPH=1;

    UCB3CTL0 &= ~UCCKPL; // Clock polarity low

    UCB3CTL0 |= UCCKPH; // Clock phase high

    should be:

    case SPI_MODE_ZERO: // CPOL=0;CPHA=0;UCCKPL=0;UCCKPH=1;

    UCB0CTL0 &= ~UCCKPL; // Clock polarity low

    UCB0CTL0 |= UCCKPH; // Clock phase high

    That was special... cut and paste issues... :-/   I hate that when I do that... its the little things that get you.

    And then like I said issuing the right cmds and using the right protocol for the SDHC cards...

    Thanks

     

  • Now that you mention it... IIRC you need to read the register for supported operating voltages before proceeding. Which does not exist on SDSC or MMC cards.

    And I totally missed the UCB3/UCB0 typo.

    I too used the Ti code example only as a starting point on MMC and SDSC cards. Then I extended it for background hot-swapping, added error checking (to prevent lock-ups) and, and, and. Support of micro-SD cards was added (while standard/mini SDSC cards are backwards compatible with MMC, microSDSC are not).

    And then came SDHC. :(
    Well, 1GB cards are large enough for our applications, but these are hard to find now.

**Attention** This is a public forum