AnsweredAssumed Answered

STM32F4xx & eMMC

Question asked by warnke.doug on Sep 21, 2012
Latest reply on Jan 8, 2015 by fjullien
Hello all,

I have a problem I hope you can help out with. I have grabbed the sample code for writing to an SD card and am modifying it to write to an eMMC chip.

In the SD_PowerON() function the original code does a CMD0,CMD8,CMD55 sequence. For the eMMC the startup should be CMD0,CMD1 to get the chip in a usable mode.

The problem I'm having is that the CMD0 seems to be going out just fine and when it tries to do the CMD1 I get a CTIMEOUT flag in the SDIO_STA register. What am I doing wrong? Here is the power on code I've written.

SD_Error SD_PowerON(void)
{
     __IO SD_Error errorstatus = SD_OK;
     uint32_t response = 0, count = 0, validvoltage = 0;
     uint32_t SDType = SD_STD_CAPACITY;


     /*!< Power ON Sequence -----------------------------------------------------*/
     /*!< Configure the SDIO peripheral */
     /*!< SDIO_CK = SDIOCLK / (SDIO_INIT_CLK_DIV + 2) */
     /*!< on STM32F4xx devices, SDIOCLK is fixed to 48MHz */
     /*!< SDIO_CK for initialization should not exceed 400 KHz */  
     SDIO_InitStructure.SDIO_ClockDiv = SDIO_INIT_CLK_DIV;
     SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising;
     SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable;
     SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable;
     SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b;
     SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable;
     SDIO_Init(&SDIO_InitStructure);


     /*!< Set Power State to ON */
     SDIO_SetPowerState(SDIO_PowerState_ON);


     /*!< Enable SDIO Clock */
     SDIO_ClockCmd(ENABLE);


     /*!< CMD0: GO_IDLE_STATE ---------------------------------------------------*/
     /*!< No CMD response required */
     SDIO_CmdInitStructure.SDIO_Argument = 0x0;
     SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_GO_IDLE_STATE;
     SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_No;
     SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
     SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
     SDIO_SendCommand(&SDIO_CmdInitStructure);


     errorstatus = CmdError();


     if (errorstatus != SD_OK)
     {
            /*!< CMD Response TimeOut (wait for CMDSENT flag) */
          return(errorstatus);
     }


     /*!< CMD1: SEND_OP_COND ----------------------------------------------------*/
     /*!< Send CMD1 to receive the contents of the Operating Conditions Register */
     /*!< Argument:      - [31:31]:     0xxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
               - [30:29]:     x10x xxxx xxxx xxxx xxxx xxxx xxxx xxxx
               - [28:24]:     xxx0 0000 xxxx xxxx xxxx xxxx xxxx xxxx
               - [23:15]:     xxxx xxxx 1111 1111 1xxx xxxx xxxx xxxx
                      - [14:8]:     xxxx xxxx xxxx xxxx x000 0000 xxxx xxxx
                 - [7:7]:     xxxx xxxx xxxx xxxx xxxx xxxx 1xxx xxxx
                     - [6:0]:     xxxx xxxx xxxx xxxx xxxx xxxx x000 0000 */
     /*!< CMD Response: R3 */
     SDIO_CmdInitStructure.SDIO_Argument = 0x40FF8080;
     SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_OP_COND;
     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 = CmdResp3Error();


       if (errorstatus == SD_OK)
       {
              CardType = SDIO_STD_CAPACITY_SD_CARD_V2_0; /*!< SD Card 2.0 */
              SDType = SD_HIGH_CAPACITY;
       }
       else
       {
              /*!< CMD55 */
              SDIO_CmdInitStructure.SDIO_Argument = 0x00;
              SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_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(SD_CMD_APP_CMD);
       }


  /*!< CMD55 */
  SDIO_CmdInitStructure.SDIO_Argument = 0x00;
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_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(SD_CMD_APP_CMD);


  /*!< If errorstatus is Command TimeOut, it is a MMC card */
  /*!< If errorstatus is SD_OK it is a SD card: SD card 2.0 (voltage range mismatch)
     or SD card 1.x */
  if (errorstatus == SD_OK)
  {
    /*!< SD CARD */
    /*!< Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */
    while ((!validvoltage) && (count < SD_MAX_VOLT_TRIAL))
    {


      /*!< SEND CMD55 APP_CMD with RCA as 0 */
      SDIO_CmdInitStructure.SDIO_Argument = 0x00;
      SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_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(SD_CMD_APP_CMD);


      if (errorstatus != SD_OK)
      {
     return(errorstatus);
      }
      SDIO_CmdInitStructure.SDIO_Argument = SD_VOLTAGE_WINDOW_SD | SDType;
      SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SD_APP_OP_COND;
      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 = CmdResp3Error();
      if (errorstatus != SD_OK)
      {
     return(errorstatus);
      }


      response = SDIO_GetResponse(SDIO_RESP1);
      validvoltage = (((response >> 31) == 1) ? 1 : 0);
      count++;
    }
    if (count >= SD_MAX_VOLT_TRIAL)
    {
      errorstatus = SD_INVALID_VOLTRANGE;
      return(errorstatus);
    }

    if (response &= SD_HIGH_CAPACITY)
    {
      CardType = SDIO_HIGH_CAPACITY_SD_CARD;
    }

  }/*!< else MMC Card */

  return(errorstatus);
}

Outcomes