cancel
Showing results for 
Search instead for 
Did you mean: 

How to use SD card and eMMC together in STM32H7

Kim KyungTack
Associate III

안녕.

최근에 STM32H753XI를 사용하여 맞춤형 보드를 만들었습니다.

보드의 초기 테스트를 위해 각 주변 장치에 대한 테스트를 실행하고 있습니다.

 

대부분의 경우 잘 작동하지만 SD 및 eMMC 사용에 문제가 있습니다.

내 보드에는 SD 슬롯 1개와 eMMC가 포함되어 있습니다.

eMMC는 SDMMC1에 연결되고 SDSDMMC2에 연결됩니다.

그리고 둘 다 FatFS에 연결하여 파일 시스템으로 사용합니다.

둘 다 각각 사용할 때 매우 잘 작동합니다.

 

...

    FRESULT fr = FR_OK;
#if 0	// FORMAT
    uint8_t buf[512] = {0, };
    // format
    fr = f_mkfs(USERPath, FM_ANY, 0, buf, sizeof(buf));
#endif

#if 1   // MOUNT
    // mount
    fr = f_mount(&USERFatFS, (TCHAR const *) USERPath, 0);
#endif

#if 1   // CREATE AND WRITE FILE
    char write_name[1024] = {0,};
    char write_text[1024] = {0,};
    uint32_t write_size = 0;
    // set data
    for (int i = 0; i < 1024; ++i) {
        // set character
        write_text[i] = 0x30 + (i % 10);
    }

    // check file count
    for (int file = 0; file < 32; ++file) {
        // set path
        sprintf(write_name, "1:/file_%04d.txt", file);
        // create file
        fr = f_open(&USERFile, write_name, FA_CREATE_ALWAYS | FA_WRITE);
        // check result
        if (fr != FR_OK)
            // error
            Error_Handler();
        // write file
        fr = f_write(&USERFile, write_text, sizeof(write_text), (void*)&write_size);
        // close file
        f_close(&USERFile);

        // check result
        if (fr != FR_OK || write_size == 0)
            // error
            Error_Handler();
    }
#endif

#if 1   // READ FILE
    char read_name[1024] = {0,};
    char read_text[1024] = {0,};
    uint32_t read_size = 0;
    // check file count
    for (int file = 0; file < 32; ++file) {
        // set path
        sprintf(read_name, "1:/file_%04d.txt", file);
        // create file
        fr = f_open(&USERFile, read_name, FA_OPEN_EXISTING | FA_READ);
        // check result
        if (fr != FR_OK)
            // error
            Error_Handler();
        // read file
        fr = f_read(&USERFile, read_text, sizeof(read_text), (void*)&read_size);
        // close file
        f_close(&USERFile);

        // check result
        if (fr != FR_OK || read_size == 0)
            // error
            Error_Handler();
    }
#endif

...

 

그러나 SDMMC1과 SDMMC2가 모두 활성화된 경우 FatFS를 사용하여 f_open하는 동안 오류가 발생합니다.

디버깅을 통해 stm32h7xx_II_sdmmc.cSDMC_GetCmdResp1 함수에 문제가 있음을 발견했습니다.

 

 

uint32_t SDMMC_GetCmdResp1(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint32_t Timeout)
{
  uint32_t response_r1;
  uint32_t sta_reg;

  /* 8 is the number of required instructions cycles for the below loop statement.
  The Timeout is expressed in ms */
  uint32_t count = Timeout * (SystemCoreClock / 8U / 1000U);

  do
  {
    if (count-- == 0U)
    {
      return SDMMC_ERROR_TIMEOUT;
    }
    sta_reg = SDMMCx->STA;
  } while (((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT |
                        SDMMC_FLAG_BUSYD0END)) == 0U) || ((sta_reg & SDMMC_FLAG_CMDACT) != 0U));

  if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT))
  {
    __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT);

    return SDMMC_ERROR_CMD_RSP_TIMEOUT;
  }

  .....
}

 

 

 

SDMMCx->STA의 상태는 항상 8192(0x2000) 값을 갖습니다.

즉, 13 번째 비트는 1이며, do ~ while 문이 조건에 갇혀 통과하지 않습니다.

그런 다음 시간이 초과되고 오류와 함께 종료됩니다.

 

eMMC와 SDIO를 단독으로 사용할 때는 괜찮지만 동시에 사용할 때는 그렇지 않은 이유를 이해할 수 없습니다.

아래는 내 IOC 파일 또는 체계의 설정 이미지입니다.

도와주세요. 감사합니다.

 

또한 DMA가 사용되지 않으며 SDMMC의 입력 클럭은 150MHz입니다.

 

 

SDIO_sch.pngeMMC_sch.png

 

CORETEX_M7.pngNVIC.pngSDMMC1.pngSDMMC2.pngFATFS.png

 

 

1 ACCEPTED SOLUTION

Accepted Solutions

Yes. Two mount.

We found that when connecting two SDMMCs to FatFS, there is no initialization code in the SDMMC initialization functions (MX_SDMMC1_MMC_Init, MX_SDMMC2_SD_Init).

 

/**
  * @brief SDMMC2 Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_SDMMC2_SD_Init(void)
{

  /* USER CODE BEGIN SDMMC2_Init 0 */

  /* USER CODE END SDMMC2_Init 0 */

  /* USER CODE BEGIN SDMMC2_Init 1 */

  /* USER CODE END SDMMC2_Init 1 */
  hsd2.Instance = SDMMC2;
  hsd2.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
  hsd2.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  hsd2.Init.BusWide = SDMMC_BUS_WIDE_4B;
  hsd2.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
  hsd2.Init.ClockDiv = 16;
  /* USER CODE BEGIN SDMMC2_Init 2 */
    if (HAL_SD_Init(&hsd2) != HAL_OK)
        // set error
        Error_Handler();
  /* USER CODE END SDMMC2_Init 2 */

}

 

I added the initialization step with User code as shown in the code above and it works fine.

View solution in original post

6 REPLIES 6
KDJEM.1
ST Employee

Hello @Kim KyungTack ,

Thanks to develop your posts in English so it helps us, and the users of our community understand your question and try to help you.

I've translated your question using a translation tool to increase the chances of getting you a reply from our experts and community members, since the majority interact in English.  

 Here is the translation of your post using Google translate:

"hi.

I recently built a custom board using the STM32H753XI.

For initial testing of the board, we are running tests on each peripheral.

It works fine in most cases, but has issues with using SD and eMMC.

My board includes one SD slot and eMMC.

eMMC is connected to SDMMC1 and SD is connected to SDMMC2.

And both connect to FatFS and use it as a file system. Both work very well when used separately.

However, if both SDMMC1 and SDMMC2 are enabled, an error occurs while f_open using FatFS.

Through debugging, I found that there was a problem with the SDMC_GetCmdResp1 function in stm32h7xx_II_sdmmc.c.

The status of SDMMCx->STA always has the value 8192 (0x2000).

That is, the 13th bit is 1, and the do to while statement is stuck in the condition and does not pass.

It then times out and exits with an error.

I don't understand why eMMC and SDIO are fine when used alone, but not when used simultaneously.

Below is an image of my IOC file or setup of the scheme.

help. thank you Additionally, no DMA is used and the SDMMC has an input clock of 150 MHz."

Thank you.

Kaouthar

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Not sure why they wouldn't work together, but there would be a lot of effort to build a test system, and I don't think CubeMX would be the route I chose. Doubt much of this has been heavily tested out side of whatever the DISCO and EVAL boards provide for.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Sorry, I accidentally posted an untranslated post while editing the documentation!

Do you "mount" TWO different medias for the File System?

Yes. Two mount.

We found that when connecting two SDMMCs to FatFS, there is no initialization code in the SDMMC initialization functions (MX_SDMMC1_MMC_Init, MX_SDMMC2_SD_Init).

 

/**
  * @brief SDMMC2 Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_SDMMC2_SD_Init(void)
{

  /* USER CODE BEGIN SDMMC2_Init 0 */

  /* USER CODE END SDMMC2_Init 0 */

  /* USER CODE BEGIN SDMMC2_Init 1 */

  /* USER CODE END SDMMC2_Init 1 */
  hsd2.Instance = SDMMC2;
  hsd2.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
  hsd2.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  hsd2.Init.BusWide = SDMMC_BUS_WIDE_4B;
  hsd2.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
  hsd2.Init.ClockDiv = 16;
  /* USER CODE BEGIN SDMMC2_Init 2 */
    if (HAL_SD_Init(&hsd2) != HAL_OK)
        // set error
        Error_Handler();
  /* USER CODE END SDMMC2_Init 2 */

}

 

I added the initialization step with User code as shown in the code above and it works fine.

KDJEM.1
ST Employee

Hello @Kim KyungTack ,

Glad to know that the issue is solved and thank you for sharing the solution.

I reported internally the missing SDMMC initialization in the generation code.

Internal ticket number: 173593 (This is an internal tracking number and is not accessible or usable by customers).

Kaouthar

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.