AnsweredAssumed Answered

STM32F401 Nucleo, SDIO, TX FIFO UNDERRUN, CMD53

Question asked by singh.ishmeet on Aug 5, 2014
Latest reply on Aug 7, 2014 by singh.ishmeet
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 CMD53. 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;
       }
  }
 
}

Outcomes