Monday, June 2, 2008

TT750 SD card multithread problem

/* Add the retry scheme to solve the SD card multithread problem */
// This bug looks like Freescale SD module or DMA module bug.
/*---------------------------------------------------------------------------*/
// Read multiple block from MMC card.
BOOL MMCSD_ReadMultipleBlock(TMMCSD_CardInformationStructure *pCIS, DWORD dwAddress, void *pBuffer, DWORD dwLength)
{
TMMCSD_Reg *pMMCSD;
int ii;
//hf++ 20060503
volatile int dwTimeout=0;
BYTE * pbtDataBuffer = (BYTE*)pBuffer;
int retry=0;
int blRetValue = 0;
//hf-- 20060503

RETAILMSG(MMCSD_DEBUG_MSG, (TEXT("MMCSD_ReadMultipleBlock+, Address:0x%x, Size:0x%x\r\n"), dwAddress, dwLength));
RETAILMSG(MMCSD_DEBUG_MSG, (TEXT("Size:0x%x\r\n"), dwLength));
for (retry = 0; retry<3;retry++)
{
if (retry !=0)
RETAILMSG(1, (TEXT("MMCSD_ReadMultipleBlock retry=0x%x\r\n"), retry));
if (blRetValue!=0)
{
RETAILMSG(1, (TEXT("MMCSD_ReadMultipleBlock retry reason=0x%x\r\n"), blRetValue));
}
blRetValue = 0;
pMMCSD = gpMMCSD;
pbtDataBuffer = (BYTE*)pBuffer;
#if 0
// Activate card.
if (pCIS->CardType == MMCSD_CardMMC) {
if (!MMCSD_MMC_SelectCard(pMMCSD, pCIS->dwRCA)) {
return FALSE;
}
}
else if (pCIS->CardType == MMCSD_CardSD) {
if (!MMCSD_SD_SelectCard(pMMCSD, pCIS->dwRCA)) {
return FALSE;
}
}
else {
return FALSE;
}
#endif

//hf++ 20060503 add timeout
// Make sure card is ready to transfer
dwTimeout = 0;
while ((!MMCSD_IsReady(pMMCSD, pCIS))&&(dwTimeout Sleep(0);
dwTimeout++;
}
if (dwTimeout>=MMC_SD_TIMEOUT)
{
RETAILMSG(MMCSD_ERROR_MSG, (TEXT("MMCSD_ReadMultipleBlock: IsReady Timeout1\r\n")));
blRetValue = 1;
continue;
}

//hf-- 20060503

// Set hardware transfer dwLength register.
MMCSD_SetTransferLength(pMMCSD, MMCSD_DATA_BLOCK_LENGTH);

// Set block dwLength for transaction.
if (!MMCSD_SendCMD16(pMMCSD, MMCSD_DATA_BLOCK_LENGTH)) {
RETAILMSG(MMCSD_ERROR_MSG, (TEXT("MMCSD_ReadMultipleBlock: MMCSD_SendCMD16 Failed!\r\n")));
blRetValue = 2;
continue;
}

//hf++ 20060503 add timeout
// Make sure card is ready to transfer
dwTimeout = 0;
while ((!MMCSD_IsReady(pMMCSD, pCIS))&&(dwTimeout Sleep(0);
dwTimeout++;
}
if (dwTimeout>=MMC_SD_TIMEOUT)
{
RETAILMSG(MMCSD_ERROR_MSG, (TEXT("MMCSD_ReadMultipleBlock: IsReady Timeout2\r\n")));
blRetValue = 3;
continue;
}
//hf-- 20060503

if (pCIS->CardType == MMCSD_CardSD) {
MMCSD_SD_SetBusWidth(pMMCSD, pCIS->dwRCA, MMCSD_BusWidth4Bit);
}
else {
MMCSD_MMC_SetBusWidth(pMMCSD);
}

MMCSD_SetBlockNumber(pMMCSD, dwLength/MMCSD_DATA_BLOCK_LENGTH, MMCSD_DatModeDataReceiveStart);
// Send read multiple block command.
if (!MMCSD_SendCMD18(pMMCSD, dwAddress)) {
RETAILMSG(MMCSD_ERROR_MSG, (TEXT("MMCSD_ReadMultipleBlock: MMCSD_SendCMD18 Failed!\r\n")));
blRetValue = 4;
continue;
}

//MMCSD_SetClock(pMMCSD, MMCSD_ClockStart);
//pMMCSD->STR_STP_CLK = 0x06;

// Copy data from card.
for (ii=dwLength/MMCSD_DATA_BLOCK_LENGTH; ii>0; ii--) {
if (!MMCSD_ReceiveSingleBlock(pMMCSD, (BYTE*)pbtDataBuffer, MMCSD_DATA_BLOCK_LENGTH)) {
RETAILMSG(MMCSD_ERROR_MSG, (TEXT("MMCSD_ReadMultipleBlock: MMCSD_ReceiveSingleBlock Failed!\r\n")));
blRetValue = 5;
continue;
}
pbtDataBuffer = (BYTE*)((DWORD)pbtDataBuffer + MMCSD_DATA_BLOCK_LENGTH);
}

// Send stop transmission command.
if (!MMCSD_SendCMD12(pMMCSD)) {
RETAILMSG(MMCSD_ERROR_MSG, (TEXT("MMCSD_ReadMultipleBlock: MMCSD_SendCMD12 Failed!\r\n")));
blRetValue = 6;
continue;
}

// Wait for transaction to complete.
// while (!MMCSD_IsDataTransferDone(pMMCSD)) {
// Sleep(0);
// }

// MMCSD_SetClock(pMMCSD, MMCSD_ClockStop);

#if 0
// Deactivate card.
MMCSD_DeselectCard(pMMCSD);
#endif
if (blRetValue == 0)
break;
//RETAILMSG(MMCSD_DEBUG_MSG, (TEXT("MMCSD_ReadMultipleBlock-\r\n")));
}
if ((retry!=0)&&(retry!=3))
RETAILMSG(MMCSD_ERROR_MSG, (TEXT("MMCSD_ReadMultipleBlock: recover by retry=%x\r\n"), retry));
if (retry == 3)
{
RETAILMSG(MMCSD_ERROR_MSG, (TEXT("MMCSD_ReadMultipleBlock: can't recover\r\n")));
return FALSE;
}

return TRUE;
}

No comments: