lpcware

SD/MMC problem on Embedded Artists baseboard with LPC1343

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by maticomp on Tue Oct 26 17:12:09 MST 2010
Hello!

I'm a newcomer to LPC Xpresso world and I've been trying to implement some test software using SD/MMC cards with LPC1343 seated on Embedded Artists LPCXpresso base-board.

I've downloaded examples from EA showcasing the features, but whereas all other examples work fine, the SD/MMC is giving me a headache.

Lib_MCU, Lib_FatFs_SD and Lib_EaBaseboard are provided in the examples.

The code is pretty much straightforward:


    GPIOInit();
    init_timer32(0, 10);

    SSPInit();

    SysTick_Config(SystemCoreClock / 100);

    if ( !(SysTick->CTRL & (1<<SysTick_CTRL_CLKSOURCE_Msk)) )
    {
      LPC_SYSCON->SYSTICKCLKDIV = 0x08;
    }

    delay32Ms(0, 500);

    stat = disk_initialize(0);

    if (stat & STA_NOINIT) {
        UARTSendString((uint8_t*)"MMC: not initialized\r\n");
    }

    if (stat & STA_NODISK) {
        UARTSendString((uint8_t*)"MMC: No Disk\r\n");
    }

    if (stat != 0) {
        return 1;
    }
The problem is, that  disk_initialize(0) always returns 1, meaning "NOT INITIALIZED". I tried to analyze this particular function looking for trouble.


DSTATUS disk_initialize (
    BYTE drv        /* Physical drive nmuber (0) */
)
{
    BYTE n, cmd, ty, ocr[4];

    GPIOSetDir( PORT1, 11, 1 ); /* CS */
    GPIOSetDir( PORT2, 10, 0 ); /* Card Detect */

    if (drv) return STA_NOINIT;            /* Supports only single drive */
    if (Stat & STA_NODISK) return Stat;    /* No card in the socket */

    power_on();                            /* Force socket power on */
    FCLK_SLOW();
    for (n = 10; n; n--) rcvr_spi();    /* 80 dummy clocks */

    ty = 0;
    if (send_cmd(CMD0, 0) == 1) {            /* Enter Idle state */
        Timer1 = 100;                        /* Initialization timeout of 1000 msec */
        if (send_cmd(CMD8, 0x1AA) == 1) {    /* SDHC */
            for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();        /* Get trailing return value of R7 resp */
            if (ocr[2] == 0x01 && ocr[3] == 0xAA) {                /* The card can work at vdd range of 2.7-3.6V */
                while (Timer1 && send_cmd(ACMD41, 1UL << 30));    /* Wait for leaving idle state (ACMD41 with HCS bit) */
                if (Timer1 && send_cmd(CMD58, 0) == 0) {        /* Check CCS bit in the OCR */
                    for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();
                    ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;    /* SDv2 */
                }
            }
        } else {                            /* SDSC or MMC */
            if (send_cmd(ACMD41, 0) <= 1)     {
                ty = CT_SD1; cmd = ACMD41;    /* SDv1 */
            } else {
                ty = CT_MMC; cmd = CMD1;    /* MMCv3 */
            }
            while (Timer1 && send_cmd(cmd, 0));            /* Wait for leaving idle state */
            if (!Timer1 || send_cmd(CMD16, 512) != 0)    /* Set R/W block length to 512 */
                ty = 0;
        }
    }
    CardType = ty;
    deselect();

    if (ty) {            /* Initialization succeded */
        Stat &= ~STA_NOINIT;        /* Clear STA_NOINIT */
        FCLK_FAST();
    } else {            /* Initialization failed */
        power_off();
    }

    return Stat;
}
What I found is that line:


if (send_cmd(CMD0, 0) == 1) {            /* Enter Idle state */
fails, because send_cmd() here returns 255, and not 1. I have the feeling that this implementation of SD/MMC initialization does not follow the SD specification closely. What bugs me the most is the fact, that:


#define    FCLK_SLOW()                    /* Set slow clock (100k-400k) */
#define    FCLK_FAST()                    /* Set fast clock (depends on the CSD) */
These definitions are left blank, and SD specification clearly states that SPI clock must be set to approximately 400KHz for the initialization to work.

Have any of you encountered SD/MMC implementation problems using LPC1343 and EA XPresso base-board and could provide any clue how to approach this problem?

Every place I look at it is said that card should go into idle mode after issuing CMD0, but there is no evidence of 0xFF reply possible.

I'd appreciate any kind of help!


Best regards,
Mateusz

Outcomes