现在使用TI开发板参考程序“evmc6748_v1-1\tests\experimenter\mmcsd”,在“test_mmcsd.c”内进行mmcsd初始化与首次读操作时,有一个重复尝试的机制如下图:
当首次读操作异常后,会重新进行一次初始化等操作,然后再重新进行读取,请问这种设计的出发点是?
或者说MMSCD接口,SD卡槽与SD卡相关软硬件出现什么情况才会需要上述重复初始化操作?
countryhotel:
C6748 MMCSD接口支持8G与16G的是的卡吗?
countryhotel:
回复 countryhotel:
有专家能给点解答吗?
另外,今天在OMAP-L138 C6000 DSP+ARM Processor Technical Reference Manual的MMCSD模块一掌发现有备注:
按照\evmc6748_v1-1\tests\experimenter\mmcsd给的时钟配置,mmcsd模块function clock由pll0 sysclk2提供,为150Mhz,而代码里关于memory clk的配置如下,这样最终输出的memory clk = function clock/4 = 37.5 >> 400Khz。
是不是我理解上有问题,还是这个初始化代码有漏洞?
Tony Tang:
回复 countryhotel:
应该是大意了。
我找了另一个SDMMC 烧写工程里是按要求配的参数(OMAP-L138_FlashAndBootUtils_2_40\OMAP-L138\CCS\SDMMCWriter)
const SDMMC_ConfigObj DEVICE_SDMMC_config = { SDMMC_LITTLE_ENDIAN, // writeEndian SDMMC_LITTLE_ENDIAN, // readEndian SDMMC_DAT3_EDGE_DETECT_DISABLE, // dat3Detect#if (1) 249, // initModeClockRate (target 300 KHz with 150 MHz input to module) 7, // dataModeClockRate (target 10 MHz with 150 MHz input to module) #else 19, // initModeClockRate (target 300 KHz with 12 MHz input to module) 0, // dataModeClockRate (target 3 MHz with 6 MHz input to module) #endif SDMMC_4BIT_DATABUS, // busWidth 0xFF, // timeoutResponse (none) 0x0000FFFF, // timeoutData SDMMC_FIFO_LEVEL_HIGH // fifoThreshold};
SDMMC_ConfigHandle const hDEVICE_SDMMC_config = (SDMMC_ConfigHandle) &DEVICE_SDMMC_config;
static Uint32 LOCAL_sdmmcwriter(){ SDMMC_MEM_InfoHandle hSDMMCMemInfo;
Int8 fileName[256]; Uint32 baseAddress = 0; Bool useHeaderForApp = FALSE;
DEBUG_printString( "Starting " ); DEBUG_printString( (String) devString ); DEBUG_printString( " SDMMCWriter.\r\n" ); // Initialize SD/MMC Memory Device hSDMMCMemInfo = SDMMC_MEM_open(DEVICE_SDMMCBOOT_PERIPHNUM, hDEVICE_SDMMC_config);
countryhotel:
回复 Tony Tang:
@Tony Tang,下午仔细看了OMAP-L138_FlashAndBootUtils_2_40\OMAP-L138\CCS\SDMMCWriter程序,还有两个问题请教:
问题1:在下面的SD卡扇区块读写测试中(代码实际每次写与读都是一个512长度的数据块),写与读之间加了一个延时语句,去掉该延时语句后程序会停留在函数SDMMC_readNWords内,status=SDMMC->MMCST0; status一直为0,导致死循环。请问对SD卡进行连续的单数据块读写操作之间必须加这样的延时吗?
问题2:同样的工程内,我将SDMMC_MEM_writebytes屏蔽,进入循环后直接进行读操作,则导致程序在SDMMC_readNWords内,status=SDMMC->MMCST0; status为TOUTRD超时,需要通过工程内如下代码重复一次初始化后,才能正常读取,想知道这个具体原因?
countryhotel:
回复 countryhotel:
由专家出来指点下吗?
Tony Tang:
回复 countryhotel:
countryhotel问题1:在下面的SD卡扇区块读写测试中(代码实际每次写与读都是一个512长度的数据块),写与读之间加了一个延时语句,去掉该延时语句后程序会停留在函数SDMMC_readNWords内,status=SDMMC->MMCST0; status一直为0,导致死循环。请问对SD卡进行连续的单数据块读写操作之间必须加这样的延时吗?
对照了TRM27.3.4的流程,这个SDMMC_readNWords的操作没有完整按照27.3.4的步骤来,其中1-4都省了,取而代之的是这个UTIL_waitLoop(100000). 其中第1,2步是用来找卡的,只能对做出响应的卡进行操作。
因为前面刚做完写操作,虽然数据从MMC的FIFO送给MMC卡了,但MMC卡从自己的FIFO写到其memory上是需要时间的,是不能直接马上进行回读的,其实是它不会对这个立即跟上的读操作做出响应的。换言之,根本就没有接收控制器发出的读命令,所以也不会有响应了。而增加的延时即是等SD卡向自己的内存写数完成。
countryhotel问题2:同样的工程内,我将SDMMC_MEM_writebytes屏蔽,进入循环后直接进行读操作,则导致程序在SDMMC_readNWords内,status=SDMMC->MMCST0; status为TOUTRD超时,需要通过工程内如下代码重复一次初始化后,才能正常读取,想知道这个具体原因?
这个应该是跟前面的道理是一样的吧。
建议按手册的完整流程完善你的API进行操作。
countryhotel:
回复 Tony Tang:
while ((MMCST1 & 0x1) !=1 ) ;
应该是笔误
while ((MMCST1 & 0x1) ==1 ) ;
Tony Tang:
回复 countryhotel:
谢谢斧正。
countryhotel:
回复 countryhotel:
对应TRM中: