Question
STM32F401 Nucleo, SDIO, TX FIFO UNDERRUN, CMD53
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