2021-03-12 10:24 AM
Hi Folks,
I experienced a weird problem when I tried to use the SDMMC interface on the STM32H755 Nucleo board.
I set up a very basic test program. I use the template for the H755 Nucleo in CubeIDE. I set the H7 clock frequency to 480 MHz and the M4 clock frequency to 240 MHz. Stack and Heap are set to 0x4000 and 0x8000 respectively. I deactivated all peripherals except USART 3 and SDMMC1. I-cache and D-cache are enabled.
Furthermore, power regulator source is set to PWR_LDO_SUPPLY. Solder bridges and capacitors are set on the board to comply to LDO supply only. SDMMC core clock is 80 MHz. Clock divider is set to 20 and SDMMC interrupt is enabled. All other settings are default.
In the main loop I simply have LED 1 blinking:
while (1)
{
HAL_GPIO_WritePin(LD1_GPIO_Port,LD1_Pin,GPIO_PIN_SET);
HAL_Delay(1000);
HAL_GPIO_WritePin(LD1_GPIO_Port,LD1_Pin,GPIO_PIN_RESET);
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
When I launch the program, it stalls somewhere in the inline function for enabling the D-cache.
When I comment the line
MX_SDMMC1_SD_Init();
everything works fine; LED 1 is blinking. But just with having the SD card init function in the code, the program stalls even before reaching this line. (That feels a bit like quantum physics...)
Did anyone experience similar problems?
Regards,
Daniel
CubeIDE 1.6.0 Firmwarpackage 1.9.0
2021-03-12 11:08 AM
SDMMC has a number of clocking choices, watch if it reconfigures any of the other PLL's, or changes "peripheral clocks"
2021-03-12 11:25 AM
Thanks for your answer, however, the program already stalls before the init function of the SDMMC interface is reached. This is what baffles me. A line in the code that is never reached influences the behavior prior to this line.
2021-03-12 01:08 PM
>>A line in the code that is never reached influences the behavior prior to this line.
Perhaps related to cache-line boundaries and dead code removal?
Perhaps related to CMSIS version and D Cache Enable method..
>>When I launch the program, it stalls somewhere in the inline function for enabling the D-cache.
Instrument Hard Fault Handler and Error Handler in case it wanders off to those quiet while(1) loops to die.
2021-03-12 01:22 PM
Yes, thought about this, too. But when I disable the line where D-cache is enabled, it stalls a few lines later but it stalls still before the sd card enable function. I didnt have this problem on the H743...
2021-03-12 01:40 PM
>>I didnt have this problem on the H743...
Materially they are the same IC design.
The H743 was conceived as a dual core device, the V-Step 743/753 should be the same die as the 745/755, just shipping with working M7+M4, CRYP, HASH
My money is on some other explanation.
2021-03-14 01:31 PM
Oh boi... after a weekend yelling at my computer I figured out what was going wrong:
First of all, the programm got stuck in the init function of the SD card. The reason why I thought it got stucked earlier was that after updating CubeIDE the debugging dind't work as it did before. I had to adjust following line for the M7 core so that I don't get a timeout:
/* USER CODE BEGIN Boot_Mode_Sequence_1 */
/* Wait until CPU2 boots and enters in stop mode or timeout*/
timeout = 0xFFFF;
//while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) != RESET) && (timeout-- > 0));
while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) != RESET));
if ( timeout < 0 )
{
Error_Handler();
}
The reason why the program crashed was that I did not fitted the SD card when I launched the program. Normally that would be no problem. When I compare the code to earlier versions I observe followinf difference. When using SDMMC and FATFS you will geht following code in the init function:
static void MX_SDMMC1_SD_Init(void)
{
/* USER CODE BEGIN SDMMC1_Init 0 */
/* USER CODE END SDMMC1_Init 0 */
/* USER CODE BEGIN SDMMC1_Init 1 */
/* USER CODE END SDMMC1_Init 1 */
hsd1.Instance = SDMMC1;
hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;
hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
hsd1.Init.ClockDiv = 2;
hsd1.Init.TranceiverPresent = SDMMC_TRANSCEIVER_NOT_PRESENT;
/* USER CODE BEGIN SDMMC1_Init 2 */
/* USER CODE END SDMMC1_Init 2 */
}
For the newer firmeware version I get:
static void MX_SDMMC1_SD_Init(void)
{
/* USER CODE BEGIN SDMMC1_Init 0 */
/* USER CODE END SDMMC1_Init 0 */
/* USER CODE BEGIN SDMMC1_Init 1 */
/* USER CODE END SDMMC1_Init 1 */
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 = 4;
hsd1.Init.TranceiverPresent = SDMMC_TRANSCEIVER_NOT_PRESENT;
if (HAL_SD_Init(&hsd1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SDMMC1_Init 2 */
/* USER CODE END SDMMC1_Init 2 */
}
In the former version HAL_SD_Init(&hsd1) was called during f_mount. If you do not have an SD cdard fitted f_mount would return an error. In the newer version you will get stuck in the error handler. You have to have your SD card inserted before the CPU starts. I do not know why this was changed, it does not make any sense in my opinion.
At least I have an explanation for the observed behaviour. SD card ist still not working (as expected, nothing is working out of the box without deep-diving into the code) but now I fan focus on the usual trouble with dma and so on. Can the IDMA of the SDMMC interface access RAM3 region?
Regards,
Daniel
2021-03-15 02:44 PM
Ok, I have it all running now. SDMMC1 cannot access RAM 3. With SDMMC2 and the appropriate MPU settings it's finally working. Was a hard fight though...
2021-05-12 10:18 AM
@Curtis ,
Hello, can you tell me, what was the trick to get sdmmc2 running? i have same problem on H7A3, stall when HAL_SD_Init , but info from card seems read ok, blocksize etc. is read, but then wait for SD-status --- forever . (-1) . ooohhh...
2021-05-16 07:50 AM
It stalls, because if the init fails the error handler is called. As I mentioned above I am very unhappy with th code generation of CubeIDE in this case.
I got it running when I changed the buffer from RAM3 to RAM2. SDMMC2 IDMA cannot access RAM3, but I don't know if this applies for the H7A3, too. However, I got it only running in 1 Bit mode. 4 Bit mode was impossible to implement. I gave it up after weeks, however 1 Bit mode is sufficient for the current application.
Regards,
Daniel