Page 2 of 4
Re: SDC read fails.
Posted: Fri May 17, 2013 10:45 am
by alexblack
Hi,
Giovanni wrote:Another possible solution could be to poll the card after enabling the clock in sdcConnect() several times before giving up and inserting small delays after each failed attempt.
Giovanni
Are you about to increase debounce time? I tried to set it to 1 sec and tried to power up the device with inserted card this not help. Simple pause after CLOCK SETUP give result.
Re: SDC read fails.
Posted: Fri May 17, 2013 10:48 am
by alexblack
Incidentally, in SPI mode prior to initializations we send some 0xFF to card may be it true in SDC too.
Re: SDC read fails.
Posted: Fri May 17, 2013 12:48 pm
by Giovanni
I will look into this over the weekend, a card exhibiting the problem would help, I'll have to ask to test the new code.
Giovanni
Re: SDC read fails.
Posted: Fri May 17, 2013 4:36 pm
by alexblack
Hi.
Today specifically bought 4 new cards for testing:
1. Transcend SDHC 8Gb 6 class.
2. Team SDHC 8Gb 10 class.
3. GOOD RAM 8Gb 10 class.
4. Transcend SDHC 32Gb 6 class.
All card work with driver without modifications. It seems the init problem is only in old SD cards.
Some benchmark (read 48 kb to internal memory 100 times starting from 0 sector, write same 48 kb buffer from internal memory 100 times, All debug options on, compilation optimization off):
Code: Select all
Transcend SDHC 8Gb 6 class: read 10810 kb/sec, write 7855 kb/sec
Team SDHC 8Gb 10 class: read 10690 kb/sec, write 7339 kb/sec
GOOD RAM 8Gb 10 class: read 7418 kb/sec, write 2845 kb/sec
Transcend SDHC 32Gb 6 class: read 10434 kb/sec, write 6357 kb/sec
Sandisk SD 1Gb Ultra II: read 10300 kb/sec, write 7754 kb/sec
Sandisk uSD 1Gb: read 10191 kb/sec, write 3086 kb/sec
It seems 'GOOD RAM' very BAD RAM

(on label MADE IN JAPAN).
Test my SDXC 64Gb card I was afraid - I check it later.
I think STM32 has very good performance... because my old atXMega on SPI has maximum 1900 kb/sec and I was pleased.
The test code:
Code: Select all
uint8_t test_buff[48*1024];
#define TEST_COUNT 100
static void testSDSpeed(void)
{
DEBUG_TRACE("TEST SD READ SPEED...\n\r");
RTCTime start, end;
rtcGetTime(&RTCD1, &start);
for (int i=0; i<TEST_COUNT; i++)
{
if (sdcRead(&MMC_PORT, 0, test_buff, sizeof(test_buff)/512) != CH_SUCCESS)
{
ERROR_TRACE("Error read from card %X!", sdcGetAndClearErrors(&MMC_PORT));
return;
}
}
rtcGetTime(&RTCD1, &end);
int time = (uint64_t) (end.tv_sec*1000+end.tv_msec) - (uint64_t) (start.tv_sec*1000+start.tv_msec);
DEBUG_TRACE("SD READ SPEED %d kb/s\n\r\n\r", (uint64_t) sizeof(test_buff)*TEST_COUNT*1000/time/1024);
DEBUG_PRINT_MEM(test_buff, 16);
DEBUG_TRACE("TEST SD WRITE SPEED...\n\r");
rtcGetTime(&RTCD1, &start);
for (int i=0; i<TEST_COUNT; i++)
{
if (sdcWrite(&MMC_PORT, 0, test_buff, sizeof(test_buff)/512) != CH_SUCCESS)
{
ERROR_TRACE("Error write to card %X!", sdcGetAndClearErrors(&MMC_PORT));
return;
}
}
rtcGetTime(&RTCD1, &end);
time = (uint64_t) (end.tv_sec*1000+end.tv_msec) - (uint64_t) (start.tv_sec*1000+start.tv_msec);
DEBUG_TRACE("SD WRITE SPEED %d kb/s\n\r\n\r", (uint64_t) sizeof(test_buff)*TEST_COUNT*1000/time/1024);
}
Last question what to do with FIFO overrun error? I think this error was the cause of my 32Gb card fault.
Re: SDC read fails.
Posted: Fri May 17, 2013 4:47 pm
by alexblack
Hi.
Re: SDC read fails.
Posted: Fri May 17, 2013 7:40 pm
by Giovanni
You mean under-run I think. Not sure how it could be prevented unless a test operation is performed. I don't think it is a huge problem because a problem like this could only occur during development.
Anyway, if I remember well there is something in the SDIO peripheral regarding this and also an errata, I have to do a search.
Giovanni
Re: SDC read fails.
Posted: Tue May 21, 2013 11:34 am
by alexblack
I found error why old cards (v.1.1) not initialized correctly.
The reason is that when the SDI driver sends a command 'MMCSD_CMD_SEND_IF_COND' to version check, the cards 1.1 do not respond to this command, setting flag 'ILLEGAL_COMMAND' bit 22 of R1, which resets (according to datasheet) with a delay of one command.
Accordingly, a subsequent send of correct command gives the error bit is set incorrectly.
To avoid this problem I inserted correct command and all old cards pass initialization without problems!
Code: Select all
File: ..\os\hal\src\sdc.c
...
207 /* V2.0 cards detection.*/
208 if (!sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SEND_IF_COND, <<<< this command set ILLEGAL_COMMAND bit in card status register
209 MMCSD_CMD8_PATTERN, resp)) {
210 sdcp->cardmode = SDC_MODE_CARDTYPE_SDV20;
...
224 else
225 #endif /* SDC_MMC_SUPPORT */
226 {
227 sdcp->cardmode = SDC_MODE_CARDTYPE_SDV11;
228 /* reset error flag illegal command */
229 sdc_lld_send_cmd_none(sdcp, MMCSD_CMD_GO_IDLE_STATE, 0);
230 }
231 }
...
Also I tested another two cards: Transcend SD 2Gb and Team SDHC 16Gb Class 10.
Re: SDC read fails.
Posted: Tue May 21, 2013 12:55 pm
by Giovanni
Hi,
Good catch, I will try to include this in 2.6.0 too. Any other comment about this fix?
Giovanni
Re: [TODO] SDC read fails.
Posted: Tue May 21, 2013 2:43 pm
by alexblack
Hi.
Not yet. I will test more ...
Re: [TODO] SDC read fails.
Posted: Tue Sep 17, 2013 11:21 pm
by resset
@alexblack, @Giovanni, can you tell if you have any other information on this?
I use STM32F407-DISCOVERY with Embest board and SDIO interface. ChibiOS/RT is 2.7.0unstable (most recent). My four cards, as turned out below, are most likely all V2.0. And I have quite related problem with them.
I have an InsertHandler written like in alexblack's 2nd example here:
http://forum.chibios.org/phpbb/viewtopic.php?f=16&t=1084&hilit=sdio#p10790. So for every card insertion I do few sdConnect trials separated with 10ms pauses and only then it works. Sometimes it takes one, sometimes even six attempts. The error code returned by sdcGetAndClearErrors is always SDC_COMMAND_TIMEOUT (8). I digged a bit and timeout SDIO_STA_CTIMEOUT happens in sdc_lld_send_cmd_short_crc here:
os/hal/src/sdc.c:
Code: Select all
/* V2.0 cards detection.*/
if (!sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SEND_IF_COND,
MMCSD_CMD8_PATTERN, resp)) {
Condition in if statement is not met and thus SDC_MODE_CARDTYPE_SDV11 is being set as a card mode. I reckon that this is wrong, because each time card type is set to V1.1, sdConnect goes to "failed" label. I don't know where exactly it fails, but if I'm not wrong, the problem lies rather in code above, because every time card type is set to V2.0, sdConnect succeedes and everything other goes on smoothly.
I tried to lower SD card initialization clock, from ~400 kHz to ~250 kHz and nothing changed.