Hi experts,
My customer is using "TMS320VC55XCSL-LOWPWR03_08_ 1_00" and has a problem with being stuck in a loop when using "csl_mmcsd.c"'s MMC_read() function.
C:\ti\c55_lp\c55_csl_3.08.01\src
Q1: They can't get out of the 3820~3829 line loop, is there a possible cause?
After sending a read command to the SD, it should break because MMCST0's DRRDY is normally set. However, there are cases where the loop continues.
Monitors MMCST1 and checks for FIFO empty before throwing a read command. Verify that MMCST1 is FIFO full and DRFUL when waiting for DRRDY without exiting the while loop.
Here is an excerpt from the MMC_read() function and a comment:.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CSL_Status MMC_read(CSL_MmcsdHandle hMmcsd, Uint32 cardAddr, Uint16 noOfBytes, Uint16 *pReadBuffer) { volatile Uint32 response; volatile Int16 status; volatile Uint16 mmcStatus; volatile Uint16 count; Uint16 stopCmdRetryCnt; CSL_Status result; Uint16 *pReadBuff; Uint16 rdCntMmc; Uint16 readRetryCount; Uint16 blkCnt; Uint16 reIssueReadFlag; Uint16 readCmd; Bool reStartDma; Uint16 saved; reStartDma = 0; readRetryCount = CSL_MMSCD_READ_WRITE_RETRY_COUNT; if((hMmcsd != NULL) && (pReadBuffer != NULL)) { /* Set block length */ if(noOfBytes != 0) { /* * For standard capacity memory cards, it is possible to set * the block length other than 512. Block length configured * using MMC_setBlockLength() API will be stored in MMCSD * handle. */ if((hMmcsd->blockLen != 0) && (hMmcsd->cardObj->sdHcDetected != TRUE)) { blkCnt = (noOfBytes)/(hMmcsd->blockLen); CSL_FINS(hMmcsd->mmcRegs->MMCBLEN, MMCSD_MMCBLEN_BLEN, hMmcsd->blockLen); } else { blkCnt = (noOfBytes)/(CSL_MMCSD_BLOCK_LENGTH); CSL_FINS(hMmcsd->mmcRegs->MMCBLEN, MMCSD_MMCBLEN_BLEN, CSL_MMCSD_BLOCK_LENGTH); } CSL_FINS(hMmcsd->mmcRegs->MMCNBLK, MMCSD_MMCNBLK_NBLK, blkCnt); mmcStatus = CSL_MMCSD_BUSY_STATE; do { status = hMmcsd->mmcRegs->MMCST1; mmcStatus |= status & CSL_MMCSD_FIFO_EMPTY; if((status & CSL_MMCSD_BUSY_STATE) == 0) { mmcStatus &= ~CSL_MMCSD_BUSY_STATE; } } while(((mmcStatus & CSL_MMCSD_FIFO_EMPTY) != CSL_MMCSD_FIFO_EMPTY) || ((mmcStatus & CSL_MMCSD_BUSY_STATE) == CSL_MMCSD_BUSY_STATE)); } else { return (CSL_ESYS_INVPARAMS); } /* Set Endian mode */ CSL_FINS (hMmcsd->mmcRegs->MMCCTL, MMCSD_MMCCTL_PERMDR, hMmcsd->readEndianMode); /* Reset FIFO */ CSL_FINST(hMmcsd->mmcRegs->MMCFIFOCTL, MMCSD_MMCFIFOCTL_FIFORST, RESET); //Verify that the FIFO has been reset to empty at this point /* Configure FIFO for read */ CSL_FINST(hMmcsd->mmcRegs->MMCFIFOCTL, MMCSD_MMCFIFOCTL_FIFODIR, READ); /* Set FIFO access width */ if(CSL_MMCSD_OPMODE_POLLED == hMmcsd->opMode) { CSL_FINST(hMmcsd->mmcRegs->MMCFIFOCTL, MMCSD_MMCFIFOCTL_ACCWD, 2BYTES); } else { CSL_FINST(hMmcsd->mmcRegs->MMCFIFOCTL, MMCSD_MMCFIFOCTL_ACCWD, 4BYTES); } /* Set FIFO threshold */ CSL_FINST(hMmcsd->mmcRegs->MMCFIFOCTL,MMCSD_MMCFIFOCTL_FIFOLEV, 256BIT); if(blkCnt > 1) { readCmd = CSL_MMCSD_READ_MULTIPLE_BLOCK_CMD; } else { readCmd = CSL_MMCSD_READ_BLOCK_CMD; //blkCnt is 1, single block read } if(CSL_MMCSD_OPMODE_POLLED == hMmcsd->opMode) { do { readRetryCount--; //Verify there are no retries if(readRetryCount == 0) { return (CSL_EMMCSD_TIMEOUT); } /* * This flag enables the reading process to re-start * right from sending the command incase of errors * during the read operation */ reIssueReadFlag = 0; /* KR032010 */ pReadBuff = pReadBuffer; rdCntMmc = 0; status = MMC_sendCmd(hMmcsd, //DRRDY does not stand before read command, FIFO checks empty (Uint32)readCmd, (Uint32)cardAddr, CSL_MMCSD_EVENT_EOFCMD); if(reIssueReadFlag == 1) { continue; } do //Occurs immediately after a read command, not in the middle of reading a block { do { status = hMmcsd->mmcRegs->MMCST0; if((status & CSL_MMCSD_DATA_TOUT_CRC_ERROR) != 0) { reIssueReadFlag = 1; break; } } while((status & CSL_MMCSD_READ_READY) != CSL_MMCSD_READ_READY); if(reIssueReadFlag == 1) { break; } /* * Read from MMCDRR1 register for little endian mode * Read from MMCDRR2 register for big endian mode */ if(hMmcsd->readEndianMode == CSL_MMCSD_ENDIAN_LITTLE) { /* * Since FIFO level is configured for 256 bits, * there will be 32 bytes available in the FIFO. * Loop runs 16 times and 2bytes are read in each * interation. */ for(count = 0; count < 16; count++) { *pReadBuff++ = CSL_FEXT(hMmcsd->mmcRegs->MMCDRR1, MMCSD_MMCDRR1_DRR1); rdCntMmc += 2; } } else { /* * Since FIFO level is configured for 256 bits, * there will be 32 bytes available in the FIFO. * Loop runs 16 times and 2bytes are read in each * interation. */ for(count = 0; count < 16; count++) { *pReadBuff++ = CSL_FEXT(hMmcsd->mmcRegs->MMCDRR2, MMCSD_MMCDRR2_DRR2); rdCntMmc += 2; } } } while(rdCntMmc < noOfBytes); } while(reIssueReadFlag); /* End of re-issue read command loop */
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Best Regards,
O.H