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.

C5515 SD Card Read Hangs

Other Parts Discussed in Thread: TMS320C5515

Hi,

I'm dealing with a spurious issue where a call to MMC_read() periodically hangs.

It has happened at least 2 times now, but that is over the past couple weeks of testing and development, so it's not a very frequently happening event.

It is being used on a TMS320C5515 with csl v3.04.

I was able to locate the area of code where it hangs, lines 3811 - 3820 of csl_mmcsd.c.

Below is the code:

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);

Execution never leaves the above do/while loop when the issue occurs.

I was fortunate to see it happen while debugging, but the code was compiled with some level of optimization, so I wasn't able to follow it that well with the debugger.

Two questions I have about this are follows:

1.  Could compiling csl_mmcsd.c. with any level of optimizations cause issues with the execution of the code?

2.  In regards to the if statement on line 3814:

if((status & CSL_MMCSD_DATA_TOUT_CRC_ERROR) != 0)

It is looking for the TOUTRD bit of MMCST0 to be set in order to assert the timeout.

Should it be looking for the TOUTRS to be set in order to assert the command timeout, since the last item it sent the SD Card was a command?

I'll be looking more into this and will post any results as I get them.

Thanks!

Ben

  • Update:

    I'm getting it to timeout finally.

    Basically the MMCTOD and MMCTOR registers had a very large value.

    I'm sure it would have eventually timed out, but it would have taken hours.

    I added the below code at the end of my initialization routine to put the timeout to the lowest level:

    	CSL_MMCConfig mmcConfig;
    
    	memset((void*)&mmcConfig, 0, sizeof(mmcConfig));
    
    	status = MMC_getConfig(mmcsdHandle, &mmcConfig);
    
    	if(status != CSL_SOK)
    	{
    		return(status);
    	}
    
    	// now modify the count registers
    	// so that the SD card engine properly
    	// times out and is detected by the CSL library driver
    	mmcConfig.mmctod = 1;
    	mmcConfig.mmctor = 0x0101;
    
    	status = MMC_config(mmcsdHandle, &mmcConfig);
    
    	if(status != CSL_SOK)
    	{
    		return(status);
    	}

    Now at least the timeout is detected, what to do with a timeout event is another question...

    Ben

  • Hi,

    Thanks for your update.

    Regards,
    Sivaraj K
  • Ben,


    I am having a very similar situation.  Specifically, I'm getting a hangup at this exact section of code when I execute out of Flash memory, but when I use the debugger to launch a session I don't have any issues.   Very difficult to debug something that only works when you're using the debugger....


    Have you made any progress on this issue, as far as what to do when a timeout is encountered?

    Thanks,

    -Jason

  • Hi Jason,

    I did not find a definitive solution to what happens if a timeout occurs.

    I was able to modify my read and write timeouts so that they rarely ever occur, and if they do, I just alert the user that there was a file access issue and continue along like it never happened.

    I'm fortunate that my application can tolerate this, because after a timeout the system will access the again SD card and it's like there was never any issue.

    Below is the code that I implemented for a read from the SD card which seems to have solved the problem:

    		#ifdef ALLOW_SD_CARD
    			case SD_CARD_MEDIA:
    			{
    				// this is used to modify the SD card address
    				// based on if it is sector or byte address needed
    				uint32 address_multiplier;
    				CSL_Status status;
    				CSL_MMCConfig mmcConfig;
    				unsigned int c;
    
    				memset((void*)&mmcConfig, 0, sizeof(mmcConfig));
    
    				// if the card was high capacity, then we stay in
    				// sector count, otherwise we will deal with byte
    				// address (multiply by 512).
    				if(mmcsdHandle->cardObj->sdHcDetected == true)
    					address_multiplier = 1;
    				else
    					address_multiplier = SECTOR_SIZE_IN_BYTES;
    
    				status = MMC_getConfig(mmcsdHandle, &mmcConfig);
    
    				if(status != CSL_SOK)
    				{
    					return RES_ERROR;
    				}
    
    				// now modify the count registers
    				// so that the SD card engine properly
    				// times out and is detected by the CSL library driver.
    				// these values are the lowest possible values for a timeout.
    				// The timeout is asserted by hardware, and the CLS library
    				// driver detects that and leaves.  Even at its lowest value,
    				// it still takes about a second to timeout.
    				mmcConfig.mmctod = 0x0001;
    				mmcConfig.mmctor = 0x0101;
    
    				status = MMC_config(mmcsdHandle, &mmcConfig);
    
    				if(status != CSL_SOK)
    				{
    					return RES_ERROR;
    				}
    
    				// write to the sd card however many times count is.
    				for(c = 0; c < count; c++)
    				{
    					// increment sector each time we do a read in case they wanted multiple blocks, haven't seen
    					// this happen yet, just in case.
    					CSL_Status mmcStatus = MMC_read(mmcsdHandle, (sector++ * address_multiplier), CSL_MMCSD_ATA_BUF_SIZE * 2, gMmcBuf);
    
    					if(mmcStatus != CSL_SOK)
    					{
    						return RES_ERROR;
    					}
    				}
    
    				return RES_OK;
    			}
    		#endif // end of #ifdef ALLOW_SD_CARD

    Good Luck!

    Ben

  • In case anyone encounters this issue in the future, my particular problem came from the fact that the bootloader disables MPORT before it starts the user program.  This causes problems with the SD reads because they're using DMA.

    Adding this code at the beginning of main() fixed the issues:

    	// enable the MPORT and disable HWA
    	*(volatile ioport Uint16 *)0x0001 = 0x020E;
    	asm("   idle");

    More info: http://processors.wiki.ti.com/index.php/C5515_Boot-Image_Programmer

    -J