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.

TMS320C5535: SD CARD operating in anomalous ways

Part Number: TMS320C5535

Hello, on my project at work were using an sd card for storing a large amount of data over a long period, simple enough right?

problem is, our sd card seems to not abide the standard sd card specifications, for example:

were using version 3.08 of the C55X CSL, the MMC_selectCard function would always return a crc error,

to deal with that we made another nearly identical function instead:

CSL_Status MMC_selectCardALT(CSL_MmcsdHandle    hMmcsd,
                          CSL_MMCCardObj     *pMmcCardObj)
{
	Uint32             argument;
	Uint32             resp;
    volatile Uint16    delay;
    volatile Int16     status;
	Uint16             cardCheck;
	Uint16             cmdRetryCnt;
	Uint16             eventFlags;
	static int i = 0;
	cmdRetryCnt = CSL_MMSCD_ACMD41_RETRY_COUNT;

    if((hMmcsd !=  NULL) && (pMmcCardObj != NULL))
    {
 		/* Passed Parameter are correct */
    }
    else
    {
        if(NULL == hMmcsd)
        {
            return (CSL_ESYS_BADHANDLE);
        }
        else
        {
            return (CSL_ESYS_INVPARAMS);
        }
    }

    hMmcsd->cardObj            = pMmcCardObj;
	pMmcCardObj->cardType      = CSL_CARD_NONE;
	pMmcCardObj->mmcHcDetected = 0;
	pMmcCardObj->sdHcDetected  = 0;

	/* Place the MMCSD controller in RESET state */
    CSL_FINST(hMmcsd->mmcRegs->MMCCTL, MMCSD_MMCCTL_CMDRST, DISABLE);
    CSL_FINST(hMmcsd->mmcRegs->MMCCTL, MMCSD_MMCCTL_DATRST, DISABLE);

	/* Configure time-out registers */
    hMmcsd->mmcRegs->MMCTOR = CSL_MMCSD_RESPONSE_TIMEOUT;
    hMmcsd->mmcRegs->MMCTOD = CSL_MMCSD_DATA_RW_TIMEOUT;

	/* Configure the clock */
	/*
	 * Disbale the clock.
	 * MMCSD controller has auto-clocking feature which automatically
	 * enables the clock when there is a communication with the card
	 */
    CSL_FINST(hMmcsd->mmcRegs->MMCCLK, MMCSD_MMCCLK_CLKEN, DISABLE);
    CSL_FINS(hMmcsd->mmcRegs->MMCCLK, MMCSD_MMCCLK_CLKRT,
             CSL_MMCSD_CLK_DIV_INIT);

	/* Take the MMCSD controller out of RESET state */
    CSL_FINST(hMmcsd->mmcRegs->MMCCTL, MMCSD_MMCCTL_CMDRST, ENABLE);
    CSL_FINST(hMmcsd->mmcRegs->MMCCTL, MMCSD_MMCCTL_DATRST, ENABLE);



	/* Send CMD 0 */
	CSL_FINS(hMmcsd->mmcRegs->MMCCIDX, MMCSD_MMCCIDX_CIDX, 0);

	status = MMC_sendCmd(hMmcsd,
						 (Uint32)CSL_MMCSD_CARD_INIT0_CMD,
						 (Uint32)CSL_MMCSD_STUFF_BITS,
						 CSL_MMCSD_EVENT_EOFCMD);



	/*
	 * This loop runs for three times to detect the three differnt
	 * cards supported; MMC/SD/SDHC
	 */
	for(cardCheck = 0; cardCheck < 3; cardCheck++)
	{
		/*
		 * Send SEND_IF_COND command - Support for high capacity cards
		 * SEND_IF_COND (CMD8) is used to verify SD Memory Card(ver2.00)
		 * interface operating condition.
		 */
		if(0 == cardCheck)
		{
			/* CMD8 for SD HC card */
			argument = CSL_MMC_CMD8_ARG;
			hMmcsd->mmcRegs->MMCRSP7 = CSL_MMCSD_MMCRSP7_RESETVAL;
			CSL_FINS(hMmcsd->mmcRegs->MMCCIDX, MMCSD_MMCCIDX_CIDX, 0);

			eventFlags = CSL_MMCSD_EVENT_EOFCMD | CSL_MMCSD_EVENT_ERROR;
			status = MMC_sendCmd(hMmcsd,
								 (Uint32)CSL_MMCSD_SDHC_CARD_INIT_CMD,
								 (Uint32)argument,
								 eventFlags);
			if(CSL_EMMCSD_CRCERR == status)
			{
				return (status);
			}

			if((status & CSL_MMCSD_EVENT_ERROR) == 0)
			{
				if((CSL_SD_HC_ECHO_PATTERN | CSL_SD_HC_VHS_ECHO) ==
				   (hMmcsd->mmcRegs->MMCRSP6 & 0x1FF))
				{
					argument = CSL_MMC_ACMD41_ARG_HCS;
				}
				else
				{
					/* Card with incompatible voltage range */
					pMmcCardObj->cardType  = CSL_CARD_NONE;
					hMmcsd->numCardsActive = 0;
					break;
				}
			}
			else
			{
				argument = CSL_MMC_ACMD41_ARG_NOHCS;


				/*
				 * Some of the cards which does not respond for CMD 8
				 * need to be reset for proper operation.
				 * Send CMD 0
				 */
				CSL_FINS(hMmcsd->mmcRegs->MMCCIDX, MMCSD_MMCCIDX_CIDX, 0);

				eventFlags = CSL_MMCSD_EVENT_EOFCMD;
				status = MMC_sendCmd(hMmcsd,
									 (Uint32)CSL_MMCSD_CARD_INIT0_CMD,
									 (Uint32)0x0000,
									 eventFlags);
			}

		} /* End of if(cardCheck == 0) */
		else if(1 == cardCheck) /* Initialize the SD card */
		{
			/* Send command ACMD41 (CMD55 + CMD41)  */
			do
			{

				hMmcsd->mmcRegs->MMCRSP7 = CSL_MMCSD_MMCRSP7_RESETVAL;
				CSL_FINS(hMmcsd->mmcRegs->MMCCIDX, MMCSD_MMCCIDX_CIDX, 0);
				for(i = 0; i < 10000;i++)
				{
					asm("		NOP");
				}
				eventFlags = CSL_MMCSD_EVENT_EOFCMD | CSL_MMCSD_EVENT_ERROR;
				status = MMC_sendCmd(hMmcsd,
									 (Uint32)CSL_MMCSD_SD_CARD_INIT_CMD,
									 (Uint32)0x0000,
									 eventFlags);


				if (CSL_EMMCSD_CRCERR == status)
				{
						return (status);
				}

				/* Check for errors - Card can be MMC */

				if((status & CSL_MMCSD_EVENT_ERROR_CMDTIMEOUT) != 0)
				{
					resp = 0;
					break;
				}


				/* CMD 41 */
				hMmcsd->mmcRegs->MMCRSP7 = CSL_MMCSD_MMCRSP7_RESETVAL;
				CSL_FINS(hMmcsd->mmcRegs->MMCCIDX, MMCSD_MMCCIDX_CIDX, 0);

				eventFlags = CSL_MMCSD_EVENT_EOFCMD | CSL_MMCSD_EVENT_ERROR;
				status = MMC_sendCmd(hMmcsd,
									 (Uint32)CSL_MMCSD_CMD_41,
									 (Uint32)argument,
									 eventFlags);

				/* Check for errors - Card can be MMC */
				if(CSL_EMMCSD_TIMEOUT == status)
				{
					resp = 0;
					break;
				}

				resp = hMmcsd->mmcRegs->MMCRSP7;
				resp = (resp << CSL_MMCSD_SHIFT_MAX) | (hMmcsd->mmcRegs->MMCRSP6);

				/* Check if card is MMC Card */
				if(resp == 0)
				{
					break;
				}

				cmdRetryCnt--;
				if(cmdRetryCnt == 0)
				{
					return (CSL_EMMCSD_TIMEOUT);
				}

			} while((resp & CSL_MMCSD_CMD41_RESP) != CSL_MMCSD_CMD41_RESP);

			if(resp != 0)
			{
				/* Check card is high capacity or standard capacity card */
				if((resp & CSL_MMCSD_SDHC_RESP) != 0)
				{
					pMmcCardObj->sdHcDetected = TRUE;
				}
				else
				{
					pMmcCardObj->sdHcDetected = FALSE;
				}

				pMmcCardObj->cardType  = CSL_SD_CARD;
				hMmcsd->numCardsActive = 1;
				break;
			}

		} /* End of if(cardCheck == 1) */
		else /* Initialize the MMC card */
		{
			/* CMD 1 */
			cmdRetryCnt = CSL_MMSCD_CMD1_RETRY_COUNT;
			argument = CSL_MMC_CMD1_ARG;

			do
			{
				/* send command   */
				hMmcsd->mmcRegs->MMCRSP7 = CSL_MMCSD_MMCRSP7_RESETVAL;
				CSL_FINS(hMmcsd->mmcRegs->MMCCIDX, MMCSD_MMCCIDX_CIDX, 0);

				eventFlags = CSL_MMCSD_EVENT_EOFCMD;
				status = MMC_sendCmd(hMmcsd,
									 (Uint32)CSL_MMCSD_MMCS_CARD_INIT_CMD,
									 (Uint32)argument,
									 eventFlags);
				if(CSL_EMMCSD_TIMEOUT == status)
				{
					return (CSL_EMMCSD_TIMEOUT);
				}

				resp = hMmcsd->mmcRegs->MMCRSP7;
				resp = (resp << CSL_MMCSD_SHIFT_MAX) | (hMmcsd->mmcRegs->MMCRSP6);
				cmdRetryCnt--;
			} while(((resp & CSL_MMCSD_CMD1_RESP) != CSL_MMCSD_CMD1_RESP) &&
			  (cmdRetryCnt > 0));

			if(cmdRetryCnt != 0)
			{
			    pMmcCardObj->cardType  = CSL_MMC_CARD;
			    if((resp & 0x40000000) != 0)
			    {
					pMmcCardObj->mmcHcDetected = TRUE;
				}
				else
				{
					pMmcCardObj->mmcHcDetected = FALSE;
				}

			    hMmcsd->numCardsActive = 1;
			}
			else
			{
			    pMmcCardObj->cardType  = CSL_CARD_NONE;
			    hMmcsd->numCardsActive = 0;
			}
		}
	}

	return (CSL_SOK);
}

notice the 10000 nops before sending CMD55, that's what fixed it.

now as far as were aware things are not supposed to work that way, but we cant find an explanation for why that might be needed.

in addition while the function SD_getCardCSD returns CSL_OK and seems to be working fine, one look at the response that the processor actually recived from the sd card shows evidence to the opposite,

all of the response registers are 0.

meaning, even though the sd card haven't returned any error code/signal, still something must have went wrong there, which raises the question of what exacly did go wrong?

and lastly, an sd card is supposed to store data right? its memory shouldn't be completely reset every single time its power is turned off and most importantly it should be possible to write for then a single start address.

sadly, our sd cards fail at all of those things.

all 3 of our sd cards and boards (all identical, multiple units for testing) have produced the exact same results.

anyone have a guess as for why and how it could happen, and how to fix it?

our SD cards are an 8GB cards from Transcend's  microSD C10M card series

our IDE is code composer 6

and were using both DSP/BIOS version 5.42.1.09 and C55X CSL version 3.08