2019-05-09 07:51 AM
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.
2019-05-14 08:44 PM
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
2019-05-19 01:38 PM
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.
2019-05-21 08:41 AM
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).
2019-05-22 05:07 AM
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.
2019-05-22 05:18 AM
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
2019-05-22 05:22 AM
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 '-';
}
2019-05-24 02:50 AM
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!
2019-05-24 03:45 AM
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
2019-05-26 02:54 PM
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!