cancel
Showing results for 
Search instead for 
Did you mean: 

SDIO 4 Bit - can't get data via D0

rboeddeker9
Associate II
Posted on November 14, 2009 at 07:11

SDIO 4 Bit - can't get data via D0

5 REPLIES 5
rboeddeker9
Associate II
Posted on May 17, 2011 at 13:29

Hello *,

I have a problem with the 4 bit mode of the sdio.

The SPI mode works well (with another hardware), when I switched the project to the 4 bit mode, then all goes until the

cmd SDIO_SD_APP_SEND_SCR was send. The CPU send the CMD to the SD card, it getting the CMD answer from the SD card and waiting for the SD card data via D0. The data is send by the SD card via D0 (seen by scope) but no data arrive.

The program hang in a polling loop, while waiting the data from the SD card.

I think a hind for the problem could be, that the SDIO_DTIMER (0x24) doesn't count, it is still in the initial value (0xFFFFF)

Thank you for helping

Hardware: A modified testboard KEIL STM3210B with a STM32F103RC (SD Datalines are correct connected, data out works)

Projekt: Mass_Storage demo from um0424.zip

sdcard.c, Version V3.0.1, Date 04/27/2009

Dump of SDIO registers 0x40018000,0x4001803f in the polling state

0x40018000 SDIO_POWER 00000003

0x40018004 SDIO_CLKCR 00000101

0x40018008 SDIO_ARG 00000000

0x4001800C SDIO_CMD 00000473

0x40018010 SDIO_RESPCMD 00000033

0x40018014 SDIO_RESP0 00000920

0x40018018 SDIO_RESP1 5B5B03B9

0x4001801C SDIO_RESP2 6DB7FF80

0x40018020 SDIO_RESP3 0AC000C2

0x40018024 SDIO_DTIMER 000FFFFF

0x40018028 SDIO_DLEN 00000008

0x4001802C SDIO_DCTRL 00000033

0x40018030 SDIO_DCOUNT 00000000

0x40018034 SDIO_STA 00000000

0x40018038 SDIO_ICR 00000000

0x4001803C SDIO_MASK 00000000

/*******************************************************************************

* Function Name : FindSCR

* Description : Find the SD card SCR register value.

* Input : - rca: selected card address.

* - pscr: pointer to the buffer that will contain the SCR value.

* Output : None

* Return : SD_Error: SD Card Error code.

*******************************************************************************/

static SD_Error FindSCR(uint16_t rca, uint32_t *pscr)

{

uint32_t index = 0;

SD_Error errorstatus = SD_OK;

uint32_t tempscr[2] = {0, 0};

/* Set Block Size To 8 Bytes */

/* Send CMD55 APP_CMD with argument as card's RCA */

SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)8;

SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SET_BLOCKLEN;

SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;

SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;

SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;

SDIO_SendCommand(&SDIO_CmdInitStructure);

errorstatus = CmdResp1Error(SDIO_SET_BLOCKLEN);

if (errorstatus != SD_OK)

{

return(errorstatus);

}

/* Send CMD55 APP_CMD with argument as card's RCA */

SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) RCA << 16;

SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_APP_CMD;

SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;

SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;

SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;

SDIO_SendCommand(&SDIO_CmdInitStructure);

errorstatus = CmdResp1Error(SDIO_APP_CMD);

if (errorstatus != SD_OK)

{

return(errorstatus);

}

SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;

SDIO_DataInitStructure.SDIO_DataLength = 8;

SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DataBlockSize_8b;

SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO;

SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;

SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;

SDIO_DataConfig(&SDIO_DataInitStructure);

/* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */

SDIO_CmdInitStructure.SDIO_Argument = 0x0;

SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SD_APP_SEND_SCR;

SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;

SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;

SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;

SDIO_SendCommand(&SDIO_CmdInitStructure);

errorstatus = CmdResp1Error(SDIO_SD_APP_SEND_SCR);

if (errorstatus != SD_OK)

{

return(errorstatus);

}

/********************************************************** here it hang */

while (!(SDIO->STA & (SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR)))

{

if (SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET)

{

*(tempscr + index) = SDIO_ReadData();

index++;

}

}

16-32micros
Associate III
Posted on May 17, 2011 at 13:29

Hi

To help your analysis, Try first to remove the doubt on hardware side, Try the mass Storage device provided in UM4024 with high-density devices

and using the default configuration in this example ( DMA, 4-bit Mode :(

#ifdef USE_STM3210E_EVAL

Status = SD_Init();

Status = SD_GetCardInfo(&SDCardInfo);

Status = SD_SelectDeselect((uint32_t) (SDCardInfo.RCA << 16));

Status = SD_EnableWideBusOperation(SDIO_BusWide_4b);

Status = SD_SetDeviceMode(SD_DMA_MODE);

If it is working, Then your hardware is safe, You should concentrate on the firmware and configuration.

Cheers,

STOne-32.

rboeddeker9
Associate II
Posted on May 17, 2011 at 13:29

Hi STOne-32,

the hardware is checked and I think it's ok.

The pins PC8-PC12, PD2 are used.

The software is the 4-bit DMA example from UM4024.

Now I have extracted the code for the initialisation of the sdio interface,

so nothing else is initialised / running, but its still the same.

All went well until the first data over D0 comes from the SD card.

This data isn't seen by cpu, D1 is always 1.

Greetings

Rudi

rboeddeker9
Associate II
Posted on May 17, 2011 at 13:29

Hi STOne-32,

I found it, the problem was that the DPSM was in the IDLE stage, when it was set to the WAIT_R stage then it works.

Greetings

Rudi

static SD_Error FindSCR(uint16_t rca, uint32_t *pscr)

{

.

.

.

errorstatus = CmdResp1Error(SDIO_SD_APP_SEND_SCR);

if (errorstatus != SD_OK)

{

return(errorstatus);

}

SDIO_StartSDIOReadWait (ENABLE); // *** New code

while (!(SDIO->STA & (SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR)))

{

if (SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET)

{

*(tempscr + index) = SDIO_ReadData();

index++;

}

}

SDIO_StartSDIOReadWait (DISABLE); // *** New code

if (SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)

{

16-32micros
Associate III
Posted on May 17, 2011 at 13:29

Excellent !