cancel
Showing results for 
Search instead for 
Did you mean: 

FatFs uSDCard read Problem

sm
Associate II
Posted on January 04, 2016 at 09:51

🙂 Hi my friends.

I've written a code to play a song file for long time on repeat mode. Normally this code work correctly without any problem but for a short time. After for number of repeated, the sound goes to choppy mode, but when i change the player to other song, the other song will play correctly without any problem. I dont know why this is happening but as my research in code, i find out the uSDCard (High Capacitance) has delay to respond.

SD_BOOL SD_RecvDataBlock (uint8_t *buf, uint32_t len)
{
uint8_t datatoken;
uint32_t i;
/* Read data token (0xFE) */
Timer1 = 10; /* Data Read Timerout: 100ms */
tokenCounter = 0;
do { 
datatoken = SPIx_RecvByte ();
tokenCounter++;
if (datatoken == 0xFE) 
break;
} while (Timer1);
if(datatoken != 0xFE) 
return (SD_FALSE); /* data read timeout */
/* Read data block */
#ifdef USE_FIFO
SPIx_RecvBlock_FIFO (buf, len);
#else
for (i = 0; i < len; i++) {
buf[i] = SPIx_RecvByte ();
}
#endif
/* 2 bytes CRC will be discarded. */
SPIx_RecvByte ();
SPIx_RecvByte ();
return (SD_TRUE);
}

Normally the tokenCounter for other song is about 0x66, but for the corrupted song is more than 0xFFFF. I Confused that when i deleted the file and replaced the song again the song will play correctly but again after ... the song goes to choppy.

what was happening to the uSDCard or file...?

Thanks alot...

2 REPLIES 2
pkumar1883
Associate II
Posted on January 06, 2016 at 09:45

Dear LRDSMRT,

could you share your code. I have done the same project with Chan FAT file system.

At first debug level you can do one thing. Keep only one file on SD card. Play this in an infinite loop. Print the counter on completion of song play. Then see at which counter value it starts that chopping.

sm
Associate II
Posted on January 11, 2016 at 12:10 Thanks to your reply and sorry to late response of me. I have a question about the max time to wait the response of read block data. I have 2 function for read sector. 1: SD_SendCommand -> to send command of Read Single Block, 2:SD_RecvDataBlock -> to receive token + data + crc as i see in the following code :

if ((SD_SendCommand(READ_SINGLE_BLOCK, sect, NULL, 0)==R1_NO_ERROR) &&
SD_RecvDataBlock(buf, SECTOR_SIZE)==SD_TRUE) 
flag = SD_TRUE; 

per every read cycle,''sect'' will increase 1 byte, and then the code goes to SD_RecvDataBlock(...) . is it true to increase sector one by one? Also i set a delay time about 5 milisecond:

SD_BOOL SD_RecvDataBlock (uint8_t *buf, uint32_t len)
{
uint8_t datatoken;
uint32_t i;
/* Read data token (0xFE) */
Timer1 = 10; /* Data Read Timerout: 100ms */
tokenCounter = 0;
do { 
datatoken = SPIx_RecvByte ();
tokenCounter++;
if (datatoken == 0xFE) 
break;
Delay(5); /*5ms delay time*/
} while (Timer1);
if(datatoken != 0xFE) 
return (SD_FALSE); /* data read timeout */
/* Read data block */
#ifdef USE_FIFO
SPIx_RecvBlock_FIFO (buf, len);
#else
if (tokenCounter > 5)
i = 0;
for (i = 0; i < len; i++) {
*buf++ = SPIx_RecvByte ();
// buf[i] = SPIx_RecvByte ();
}
#endif
/* 2 bytes CRC will be discarded. */
SPIx_RecvByte ();
SPIx_RecvByte ();
return (SD_TRUE);
}

uint8_t SD_SendCommand (uint8_t cmd, uint32_t arg, uint8_t *buf, uint32_t len) 
{
uint32_t r1,i;
uint8_t crc_stop;
/* The CS signal must be kept low during a transaction */
SD_Select();
/* Wait until the card is ready to read (DI signal is High) */
if (SD_WaitForReady() == SD_FALSE) return 0x81;
/* Prepare CRC7 + stop bit. For cmd GO_IDLE_STATE and SEND_IF_COND, 
the CRC7 should be valid, otherwise, the CRC7 will be ignored. */
if (cmd == GO_IDLE_STATE) crc_stop = 0x95; /* valid CRC7 + stop bit */
else if (cmd == SEND_IF_COND) crc_stop = 0x87; /* valid CRC7 + stop bit */
else crc_stop = 0x01; /* dummy CRC7 + Stop bit */
/* Send 6-byte command with CRC. */ 
SPIx_SendByte (cmd | 0x40);
SPIx_SendByte (arg >> 24);
SPIx_SendByte (arg >> 16);
SPIx_SendByte (arg >> 8);
SPIx_SendByte (arg);
SPIx_SendByte (crc_stop); /* Valid or dummy CRC plus stop bit */
/* The command response time (Ncr) is 0 to 8 bytes for SDC, 
1 to 8 bytes for MMC. */
for (i = 8; i; i--)
{
r1 = SPIx_RecvByte ();
if (r1 != 0xFF) break; /* received valid response */ 
}
if (i == 0) return (0x82); /* command response time out error */
/* Read remaining bytes after R1 response */
if (buf && len)
{
do { 
*buf++ = SPIx_RecvByte ();
} while (--len);
}
return (r1);
}

then the tokenCounter decrease to 2 or 3. it means after two times sending 0xFF, the token will detect, but without the delay(5), tokenCounter will be too larger.

uint8_t SPIx_SendByte (uint8_t data)
{
Timer1 = 100;
SPIx->DR = data;
Timer1 = 100;
while((SPIx->SR & SPI_I2S_FLAG_TXE) == RESET){
if (!Timer1)
break;
}
Timer1 = 100;
while((SPIx->SR & SPI_I2S_FLAG_RXNE) == RESET){
if (!Timer1)
break;
}
return ((U08)SPIx->DR); 
}
uint8_t SPIx_RecvByte (void)
{
 /* Send 0xFF to provide clock for MISO to receive one byte */
 return SPIx_SendByte (0xFF);
}

Could you please help me.