Skip to main content
Torsten Jaekel
Associate III
May 16, 2018 6:13 PM UTC
Question

STM32H743 SDMMC1

Posted on May 16, 2018 at 20:13

I try to use SDMMC1 on STM32H743I Nucleo: It works fine but just if I use PLL1: PeriphClkInitStruct.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL;

If I try to use PLL2, the PLL2R clock output via: PeriphClkInitStruct.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL2; it fails: there does not seem to be a clock for the SDMMC1 peripheral block: the state machine does not proceed, the very first command for PowerOn does not complete (times out) and the status register bit in STA for command complete is never set.

It looks like the PPL2R and RCC_SDMMCCLKSOURCE_PLL2 cannot be used, not working and SDMMC1 does not get a peripheral device clock. But PLL2 (PLL2P and PLL2Q) should be OK because I use for SPI peripherals and all fine.

Using FatFS on SD card needs careful handling of DCache. Even enabling the Cache Maintenance via macro ENABLE_SD_DMA_CACHE_MAINTENANCE=1 is not enough. All the SD card commands are working error free, the f_read() or f_write() functions return properly but the data buffers are not updated (and writes to SD card will corrupt file system).

The only solution was to setup also the MPU, for the SRAM region used for variables (RAM_D1, start address: 0x24000000), data structures and buffers related to the SD card functions. The MPU is configured for the RAM_D1 region as:   MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; - then it works.

Very strange: just DCache enabled but w/o related MPU entry fails, even with cache maintenance properly used.

it seems to me: if DCache is enabled - the MPU 'must' be used and configured in order to specify the cache and buffer modes for the SRAM regions.

BTW:

Be careful when using SDMMC1: I found a remark in an application note the SDMMC1 cannot access D2 SRAM.

And I have also realized that D2 SRAM (D2SRAM1, D2SRAM2, D2SRAM3) is not powered on, not enabled on reset and MCU startup. I had to enable those (via __HAL_RCC_D2SRAM1_CLK_ENABLE(); etc.) and it results in fact, that D2 SRAM cannot have initialized global variables (.data): they would not be loaded, not initialized by the debugger. Just during run time, after enabling D2 SRAM it can be used, but w/o to have it initialized (e.g. not filled with zero by startup).

The STM32H7 is a nice MCU but it seems to be a bit tricky, a bit 'sensitive' in terms of clock configurations and when DCache is enabled (strange is also: if I just disable DCache, do not enable - my working project crashes now in a HardFaultHandler). My experience is: this H7 MCU is quite different, even if a similar project is working fine on an F7 MCU - you cannot really compare and use as a reference. You had to study carefully the H7 datasheet, 'try this and that' and be aware of a quite different system architecture (e.g. how the DCache works, how to deal with the D1..D3 domains, memories and bus fabric = data paths).

==> what is your experience with this H7 MCU?

This topic has been closed for replies.

8 replies

Tesla DeLorean
Guru
May 16, 2018 7:09 PM UTC
Posted on May 16, 2018 at 21:09

>>

what is your experience with this H7 MCU?

H7 is a lot more complicated, complexity in the clocking and DMA routing, etc.

Documentation is poor, things not named consistently, portions of PDF not searchable.

Software could do with refactoring, there is some ugly stuff in the RCC code, and a lack of understanding of how volatile prevents code reduction by compiler/optimizer.

Definitely had the SDMMC running off all available clocks sources. Wrote a clock decoder to crack the PLL and SDMMC clock settings and display. Most likely don't have the PLL running correctly. ST puts code all over the place.

There is 128KB of DTCMRAM, use that for SDMMC+DMA, no coherency issues. The cache flushing has 32-byte granularity, align your buffers suitably if use that method, watch for it discarding write-back buffers and faulting.

Watch for alignment issues with FPU/doubles.

Design has significant headroom, CPU/FPU ran at 500 MHz in tests.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Tesla DeLorean
Guru
May 16, 2018 9:26 PM UTC
Posted on May 16, 2018 at 21:26

{

     PLL1_ClocksTypeDef PLL1_Clocks;

     HAL_RCCEx_GetPLL1ClockFreq(&PLL1_Clocks);

     printf('PLL1_Q_CK=%d, %6.2lf MHz\n', PLL1_Clocks.PLL1_Q_Frequency, (double)PLL1_Clocks.PLL1_Q_Frequency*1e-6);

}

{

     PLL2_ClocksTypeDef PLL2_Clocks;

     HAL_RCCEx_GetPLL2ClockFreq(&PLL2_Clocks);

     printf('PLL2_R_CK=%d, %6.2lf MHz\n', PLL2_Clocks.PLL2_R_Frequency, (double)PLL2_Clocks.PLL2_R_Frequency*1e-6);

}

{

     uint32_t ck = SDMMC1->CLKCR & 0x3FF;

     uint32_t sdmmcsel = RCC->D1CCIPR & (1 << 16);

     PLL1_ClocksTypeDef PLL1_Clocks;

     PLL2_ClocksTypeDef PLL2_Clocks;

     uint32_t sdmmc_ker_ck;

     HAL_RCCEx_GetPLL1ClockFreq(&PLL1_Clocks);

     HAL_RCCEx_GetPLL2ClockFreq(&PLL2_Clocks);

     printf('PLL1_Q_CK=%d, %6.2lf MHz\n', PLL1_Clocks.PLL1_Q_Frequency, (double)PLL1_Clocks.PLL1_Q_Frequency*1e-6);

     printf('PLL2_R_CK=%d, %6.2lf MHz\n', PLL2_Clocks.PLL2_R_Frequency, (double)PLL2_Clocks.PLL2_R_Frequency*1e-6);

     sdmmc_ker_ck = (sdmmcsel ? PLL2_Clocks.PLL2_R_Frequency : PLL1_Clocks.PLL1_Q_Frequency);

     printf('SDMMC1_CK %4d, %6.2lf MHz\n', ck, ((double)sdmmc_ker_ck * 1e-6) / (double)(2.0 * ck));

}
Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Amel NASRI
ST Technical Moderator
May 23, 2018 10:35 AM UTC
Posted on May 23, 2018 at 12:35

Hi

Jaekel.Torsten

‌,

Could you please check if SDMMC works as expected with PLL2R as clock source

when there is no other peripheral having PLL2 output (P or Q) as clock source

?

Thanks.

-Amel

To give better visibility on the answered topics, please click on "Best Answer" on the reply which solved your issue or answered your question.
Torsten Jaekel
Associate III
May 23, 2018 6:22 PM UTC
Posted on May 23, 2018 at 18:22

Hi Amel,

interesting question. I use PLL2, the other outputs, e.g. 4x for SPI (SPI1 and 2 as master, SPI4 and 5 as slave). Do you think it is a bug and related to the fact that all PLL2 outputs are used?

This is my clock configuration on PLL2 (SDMMC uses PLL1 now, PLL2 fails). I can try w/o to enable the SPIs, just SDMMC on PLL2.

  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART3|RCC_PERIPHCLK_SPI5

                              |RCC_PERIPHCLK_SPI4|RCC_PERIPHCLK_SPI1

                              |RCC_PERIPHCLK_SPI2|RCC_PERIPHCLK_SDMMC

                              |RCC_PERIPHCLK_USB;

  PeriphClkInitStruct.PLL2.PLL2M = 4;

  PeriphClkInitStruct.PLL2.PLL2N = 200;

  PeriphClkInitStruct.PLL2.PLL2P = 4;    //100 MHz SPI

  PeriphClkInitStruct.PLL2.PLL2Q = 4;    //100 MHz SPI

  PeriphClkInitStruct.PLL2.PLL2R = 2;    //RCC_SPI123CLKSOURCE_PLL2 - FAILS!!!

  PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_1;

  PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;

  PeriphClkInitStruct.PLL2.PLL2FRACN = 0;

  PeriphClkInitStruct.PLL3.PLL3M = 4;

  PeriphClkInitStruct.PLL3.PLL3N = 96;    //for USB

  PeriphClkInitStruct.PLL3.PLL3P = 4;

  PeriphClkInitStruct.PLL3.PLL3Q = 4;

  PeriphClkInitStruct.PLL3.PLL3R = 2;

  PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_1;

  PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE;

  PeriphClkInitStruct.PLL3.PLL3FRACN = 0;

  ////PeriphClkInitStruct.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL2;       //FAILS!!!

  PeriphClkInitStruct.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL;            //WORKS!!!

  PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL2;

  PeriphClkInitStruct.Spi45ClockSelection = RCC_SPI45CLKSOURCE_PLL2;

  PeriphClkInitStruct.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1;

  PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3;

  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
Amel NASRI
ST Technical Moderator
May 24, 2018 12:04 PM UTC
Posted on May 24, 2018 at 12:04

Hi

Jaekel.Torsten

‌,

Indeed there is a bug with the current HAL driver implementation when there is more than one output to be used for PLL2or PLL3.

That is why I suggested to try with only SDMMC on PLL2.

Hopefully the fix will be applied in next version of STM32CubeH7 (all depends on the planning of the releases).

Workaround to be applied waiting for the fix is to avoid using multiple outputs for same PLL (2 or 3).

-Amel

To give better visibility on the answered topics, please click on "Best Answer" on the reply which solved your issue or answered your question.
Amel NASRI
ST Technical Moderator
Jul 26, 2018 2:09 PM UTC

Fix applied in RCC driver available in last STM32H7 package version (1.3.0).

To give better visibility on the answered topics, please click on "Best Answer" on the reply which solved your issue or answered your question.