cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4xx & eMMC

dmwarnke
Associate
Posted on September 21, 2012 at 21:11

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);

}

#emmc-stm32f4xx
1 REPLY 1
franck
Associate II
Posted on January 08, 2015 at 17:58

Hi,

I know it's an old post but I have the same problem _now_ 🙂

Did you find a solution to solve this ?

Franck.