cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 and u-SD card on sdmmc1 - Using STM32CubeMX and HAL

Jack3
Senior II

Dear friends,

I'm Using STM32Cube_FW_H7_V1.4.0 with TrueStudio 9.3.0, on an STM32H753.

Has anybody got an micro-SD card working on the SDMMC1 peripheral for an STM32H7?

For my it, seems to come with a Timeout error.

I initialized it like:

void MX_SDMMC1_SD_Init(void)
{
  HAL_StatusTypeDef status;
 
  hsd1.Instance = SDMMC1;
  hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
  hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  hsd1.Init.BusWide = SDMMC_BUS_WIDE_1B;
  hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
  hsd1.Init.ClockDiv = 2;  // 0 - 1023
  status = HAL_SD_Init(&hsd1);
  if (status != HAL_OK)
  {
    dmc_puts("!HAL_OK\n");
    _Error_Handler2(__FILE__, __LINE__, status);
//    Error_Handler();
  }
}
 
void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
{
 
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(sdHandle->Instance==SDMMC1)
  {
  /* USER CODE BEGIN SDMMC1_MspInit 0 */
 
  /* USER CODE END SDMMC1_MspInit 0 */
    /* SDMMC1 clock enable */
    __HAL_RCC_SDMMC1_CLK_ENABLE();
  
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();
 
    /**SDMMC1 GPIO Configuration    
    PC8     ------> SDMMC1_D0
    PC9     ------> SDMMC1_D1
    PC10     ------> SDMMC1_D2
    PC11     ------> SDMMC1_D3
    PC12     ------> SDMMC1_CK
    PD2     ------> SDMMC1_CMD 
    */
 
    GPIO_InitStruct.Pin = SD_D0_Pin|SD_D1_Pin|SD_D2_Pin|SD_D3_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
    GPIO_InitStruct.Pin = SD_CK_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;
    HAL_GPIO_Init(SD_CK_GPIO_Port, &GPIO_InitStruct);   // GPIOC
 
    GPIO_InitStruct.Pin = SD_CMD_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;
    HAL_GPIO_Init(SD_CMD_GPIO_Port, &GPIO_InitStruct);  // GPIOD
 
    /* SDMMC1 interrupt Init */
    HAL_NVIC_SetPriority(SDMMC1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(SDMMC1_IRQn);
  /* USER CODE BEGIN SDMMC1_MspInit 1 */
 
  /* USER CODE END SDMMC1_MspInit 1 */
  }
}

The call MX_SDMMC1_SD_Init(); was missing the lines to call HAL_SD_Init(&hsd1);, which I added.

I printed some messages, which I added to the HAL Libraries:

MX_SDMMC1_SD_Init

SDMMC_ERROR_TIMEOUT

ERROR: SD_PowerON

ERROR: HAL_SD_InitCard

!HAL_OK

Besides 4-bit mode, I tried 1-bit mode, and I experimented with the clock speed.

And I tried different SD Cards, all with the same result.

What can I check?

My source code is also on github, I will comment back and update it once it works, so it can help others.

https://github.com/bkht/STM32_SD_SDMMC

I have used an eMMC on SDMMC (8-bit) on an STM32F7, but this SD Card (4-bit) is on an STM32H7.

10 REPLIES 10
sirius506
Associate III

Are you using SD card transceiver?

CubeMX generated code assumes use of the transceiver (as found on ST eval board.)

If you don't have transceiver on your target board, change your stm32h7xx_hal_conf.h file as shown below and see if it works.

It works for my target board.

#define  USE_SD_TRANSCEIVER           0U               /*!< uSD Transceiver is NOT used */

CubeMX should have transceiver configuration option on its "parameter settings" tab.

Toshiharu

Pedro3
Senior

I'm also having troubles with SDMMC and uSD on H743 and H750 boards. My code is set to Mode SD 4 bits at 200 MHz from PLL2R and clock divide factor as 8 (no transceiver, so "USE_SD_TRANSCEIVER 0U"). Using a SanDisk 4GB Class 4 card, everything works fine. Using a SanDisk 8GB Class 4 card, it fails on "identify card operating voltage", returning HAL_SD_ERROR_CMD_RSP_TIMEOUT on "SD_PowerON" method.

I noticed some code changes from Cube FW 1.3.2 and 1.4.0, but both have the same result.

Tim Russell
Associate III

I'm having similar problems getting the uSD (SDMMC1) interface to work on my H7.

I recently upgraded from an F7 (where the uSD was working) to the H7.

I am getting an error in the HAL_SD_Init() function.

I'm using the same CubeMX settings as used with the F7 with no success.

I also modified USE_SD_TRANSCEIVER=0U (for no transceiver).

Hi Toshiharu, thank you! This is very useful information. At the moment, the board is back at the company who made the prototype, to get a Revision 'V' of the STM32H753VIT6, as there was a list errata for the SDMMC in the 'Y' version we got, which all seem fixed in 'V'. I will need to wait to get it back. As soon as I have it, I will test this.

Hi Peaga, I also notices the changes between the version, I moved to the last one, the result is more consistent: at least all cards seem to have the same problem now. I don't have my board at the moment, but hope to get it back soon, I hope with a revision 'V' chip, instead of revison 'Y'.

What version is your chip?

Please also refer to:

https://www.st.com/en/microcontrollers-microprocessors/stm32h743-753.html#resource

Hi Tim, it seems very related to my problem. Yet, I can't try Toshiharu's suggestion/solution, as I have to wait for my board to come back with hopefully a revision 'V' chip. What version is your chip? You can see it at the top, or determine it by software:

uint8_t GetMcuRevIDChar(void)
{
  // Reference Manual, June 2018, page 3131 of 3247
  // Bits 31:16 REV_ID[15:0]: Revision
  // 0x1001 = Revision Z
  // 0x1003 = Revision Y
  // 0x2001 = Revision X
  // 0x2003 = Revision V - (See STM32H750/753 Errata sheet, device limitations)
  
  uint32_t ID_Code = DBGMCU->IDCODE;
  uint16_t Dev_ID = ID_Code & 0x0fff;
  uint16_t Rev_ID = (ID_Code >> 16);
  if (Rev_ID == 0x1001)
    return 'Z';
  if (Rev_ID == 0x1003)
    return 'Y';
  if (Rev_ID == 0x2001)
    return 'X';
  if (Rev_ID == 0x2003)
    return 'V';
  return '-';
}

Jack3
Senior II

I found that CubeMX is assuming the STM32H7 eval board. Because I don't use an SD bus tranceiver, In stm32h7xx_hal_conf, I had to set this option like below:

#define  USE_SD_TRANSCEIVER           0U               /*!< uSD Transceiver is NOT used */

I took a Nucleo-H743ZI and created a small CubeMX poject for it with sdmmc, which now works great, and put the code on github. I hope it helps others.

I do not use a card detect switch, so I made sure BSP_SD_IsDetected always returns SD_PRESENT, and so disk_initialize gives no error.

It works a little bit, but I have this problem:

disk_initialize, disk_status, f_mount and f_getfree return no errors and seem to work fine.

Reading a file works too, but f_write did hang at first, when HAL_SD_WriteBlocks was called. It hung in the while loop.

When I printed dots in the while loop it succeeded, probably because of the delay that it caused.

For now I added a __NOP() in a loop, then all works fine.

It needed a minimum of 25 iterations, when hsd1.Init.ClockDiv = 3;

Decreasing ClockDiv makes the card faster, hence we need less NOPs, which makes sense. Varying the PLLQ ratio does not influence the delay.

Update: I decovered, hsd1.Init.ClockDiv should be less the 6, to avoid writing blocks to hang. Below 6, no delay is required in the function HAL_SD_WriteBlocks . I now have set it to 2.

All seems to work now, I will test a bit more.

Once all seem solved, I will update hithub to help others.

MX_SDMMC1_SD_Init
MX_FATFS_Init
SDPath: 0:/
Initialize disk: OK
Disk status: OK
Mount disk: OK
Volume label:
  31248384 kB total disk space
  31248032 kB available
Read file Info.txt
Hello SD Card.
Close file
Create file hello.txt
Set file timestamp of hello.txt
Append file hello.txt
Set file timestamp of hello.txt
Create file hello2.txt
Set file timestamp of hello2.txt

The code is here:

https://github.com/bkht/Nucleo-H743ZI_SDMMC

So to make f_write not hang, I configured hsd1.Init.ClockDiv = 2; (less then 6 at least!).

It looks like all is working well, I added long file name in FatFs.

I updated github, to help others. =)

Thanks all for bearing with me!

jakob.brunhart
Associate III

Hi Jack

I'm using NUCLEO-H743ZI and uVision 5.27. My SD-Card seems to work now. But I also had problems. The first was the #define USE_SD_TRANSCEIVER 0U which was set to 1U. But you've already found that mistake. I assume that you are also using a filesystem. In the file FS_Config_MC_0.h there is a define which defines the DMA Buffer base address. I had to set to the follwing

#define MC0_CACHE_ADDR     0x24000000

Perhaps this helps also: https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices

Regards

Jakob

Hello Jack, thanks!

It turns out to be something with my bootloader (external flash). Running the main app without it, any SD card works fine... I'll study it a little more!