cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F401 Nucleo, SDIO, TX FIFO UNDERRUN, CMD53

ishmeetsinghis
Associate II
Posted on August 05, 2014 at 14:38

Hi,

I am facing an issue with SDIO for STM32F401RE Nucleo platform,

I am trying to use CMD53 data command. From the functions below CMD53_Start(), I get correct response, I have verified the response is valid.

However, when I try to write SDIO->FIFO = Data, then read the status flag in function CMD53_Write(), I get SDIO->FIFO = 0x10, which is TX FIFO UNDERRUN,

has anyone faced this problem before, I have set SDIO clock to 1 MHz. HARDWARE FLOW CONTROL is DISABLED, GPIO SPEED is set to HIGH. BLOCK SIZE is 64 bytes. Writing data in block mode.

Also, I have not find TX FIFO UNDERRUN error when I am reading after CMD Only the write part, I seem of having the problem.

unsigned char CMD53_Start(unsigned long arg)

{

unsigned short error;

volatile uint32_t Response=0x00;

SDIO_CmdInitTypeDef SDIO_CmdInitStruct;

uint8_t respBuf[10];

f_memset(respBuf, 0,10);

SDIO_CmdInitStruct.Argument = arg;

SDIO_CmdInitStruct.CmdIndex = SD_CMD_SDIO_RW_EXTENDED;

SDIO_CmdInitStruct.Response = SDIO_RESPONSE_SHORT;

SDIO_CmdInitStruct.WaitForInterrupt = SDIO_WAIT_NO;

SDIO_CmdInitStruct.CPSM = SDIO_CPSM_ENABLE;

error = SDIO_SendCommand(SDIO, &SDIO_CmdInitStruct);

while(!__HAL_SD_SDIO_GET_FLAG(&uSdHandle, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))

{

}

__HAL_SD_SDIO_CLEAR_FLAG(&uSdHandle, SDIO_STATIC_FLAGS);

Response = SDIO_GetResponse(SDIO_RESP1);

respBuf[1] = (uint8_t)((Response >>24) & 0XFF);

respBuf[2] = (uint8_t)((Response >>16) & 0XFF);

respBuf[3] = (uint8_t)((Response >>8) & 0XFF);

respBuf[4] = (uint8_t)((Response >>0) & 0XFF);

printf(''CMD53 Response : 0x%x\n\r'',Response);

if (error != HAL_OK)

{

return error;

}

return 0;

}

unsigned char CMD53_Write(unsigned char Mode,unsigned char *data,int blocks, int32_t arg)

{

uint32_t counter=0x00,i=0x00;

uint32_t Dat=0x00;

unsigned char * pdata = data;

/* Initialize data control register */

uSdHandle.Instance->DCTRL = 0;

SDIO->DCTRL = 0;

CMD16_Start(64);

CMD53_Start(arg);

SDIO_DataInitStructure.DataTimeOut = SD_DATATIMEOUT;

SDIO_DataInitStructure.DataLength = blocks;//64 * blocks;

SDIO_DataInitStructure.DataBlockSize = SDIO_DATABLOCK_SIZE_64B;

SDIO_DataInitStructure.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;

SDIO_DataInitStructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK;

SDIO_DataInitStructure.DPSM = SDIO_DPSM_ENABLE;

SDIO_DataConfig(SDIO, &SDIO_DataInitStructure);

for(counter =0;counter <

blocks

;counter++)

{

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

{

for(i=0;i<

64

;

i

=i+4)

{

printf(''SDIO->STA : 0x%x\n\r'',SDIO->STA);

Dat = (uint32_t)(((uint8_t)pdata[i]<<

24

) |((uint8_t)pdata[i+ 1] <<16) |((uint8_t)pdata[i+2] <<8)|((uint8_t)pdata[i+3]));

SDIO->FIFO = Dat;

}

pdata += 64;

}

}

}

#sdio #stm32f4 #stm32f401

3 REPLIES 3
jasonp4113
Associate II
Posted on August 06, 2014 at 00:54

I have had the same issue with polled write via SDIO with no true solution except slowing down the SDIO peripheral.

It seems that during polled mode, the uC cannot keep up with the SD data sink, resulting in random underruns (it would help if we could have hardware handshake, but errors on the silicon prevent using this)

My solution was to use DMA instead - which works perfectly and also allows you to do other tasks instead of plugging away throwing data around manually.

Search for ''stm324xg_eval_sd.c'' as this provides working DMA hooks into the HAL.

Jas

ishmeetsinghis
Associate II
Posted on August 07, 2014 at 09:03

Hi JasonP,

1. How were you able to run it by slowing down the SDIO peripheral? I did the following, however the error is still the same.... any thing else i am missing?

GPIO_Init_Structure.Speed = GPIO_SPEED_LOW; // for all SDIO GPIO's pins
uSdHandle.Init.ClockDiv = 0x19; //0x00;

2. Also I am trying to make it work with SDIO DMA Interrupts as per the ''stm324xg_eval_sd.c'' in HAL. But, I am still facing an issue, that when I hook up the logic analyzer to the SDIO pins, I see that the CMD line w.r.t. CLK is coming fine, as I see lots of toggle on the CMD line when I send CMD0,CMD7,CMD52,CMD But, the data line stays HIGH all the time, as I have pullup, and never toggles, even though I am sending enormous buffers over SDIO->FIFO, using DMA Interrupts, almost similar case was when I was doing this on just polling method. However, in this when I read SDIO->STA register I do not get TX FIFO UNDERRUN. Any Ideas....
ishmeetsinghis
Associate II
Posted on August 07, 2014 at 09:27

....?? Any Ideas ....?/