现在使用TI开发板参考程序“evmc6748_v1-1\tests\experimenter\mmcsd”,在“test_mmcsd.c”内进行mmcsd初始化与首次读操作时,有一个重复尝试的机制如下图:
当首次读操作异常后,会重新进行一次初始化等操作,然后再重新进行读取,请问这种设计的出发点是?
或者说MMSCD接口,SD卡槽与SD卡相关软硬件出现什么情况才会需要上述重复初始化操作?
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.
现在使用TI开发板参考程序“evmc6748_v1-1\tests\experimenter\mmcsd”,在“test_mmcsd.c”内进行mmcsd初始化与首次读操作时,有一个重复尝试的机制如下图:
当首次读操作异常后,会重新进行一次初始化等操作,然后再重新进行读取,请问这种设计的出发点是?
或者说MMSCD接口,SD卡槽与SD卡相关软硬件出现什么情况才会需要上述重复初始化操作?
应该是大意了。
我找了另一个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);
@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 说:问题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进行操作。
是的:
27.2.9.7.6 Determining Whether the Memory Card is Busy
The card sends a busy signal either when waiting for an R1b-type response or when programming the last
write data into its flash memory. The MMC/SD controller has two flags to notify you whether the memory
card is sending a busy signal. The two flags are complements of each other:
• The BSYDNE flag in MMCST0 is set if the card did not send or is not sending a busy signal when the
MMC/SD controller is expecting a busy signal (BSYEXP = 1 in MMCCMD). The interrupt by this bit is
enabled by a corresponding interrupt enable bit (EBSYDNE = 1 in MMCIM).
• The BUSY flag in MMCST1 is set when a busy signal is received from the card.