cstm32hal

STM32H7 SDMMC1 stuck at Initializing phase


I'm trying to make HAL's SDMMC1 work and didnt get any response in registers ( looking at it in KEIL's debug mode, registers just dont even toggle any bits) , also cant see any tries of Initialize MMC in oscillograph ( clock ,cmd and data line doesnt toggle as well).

Im Initializing MMC:

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SDMMC1_MMC_Init(void)
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USB_DEVICE_Init();
  while (1)
  {
    if (UserRxBufferFS[0] == 0x97)   // GOT command for emmc
     {  
      UserRxBufferFS[0] = 0;
      SDMMC1->POWER = 1; //check the power register( doesnt change in debug mode, why?)
      MX_SDMMC1_MMC_Init();
      SDMMC_PowerState_ON(&hmmc2); // check the power register with HAL( doesnt change aswell)
      SDMMC_SendCommand(&hmmc2, 0); // checking cmd line, nothing happens in oscillo
      }
  }
static void MX_SDMMC1_MMC_Init(void)
{
  hmmc1.Instance = SDMMC1;
  hmmc1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
  hmmc1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  hmmc1.Init.BusWide = SDMMC_BUS_WIDE_1B;
  hmmc1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
  hmmc1.Init.ClockDiv = 0;
}
void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Supply configuration update enable
  */
  HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);

  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 1;
  RCC_OscInitStruct.PLL.PLLN = 80;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

I know that to make mmc/sd card (their protocols pretty same) work we need to send a lot of cmd sequences, i have accomplished it earlier with soft mmc(sdio) realization, now i need speed for reading mmc and hardware can help me with it, but im stuck from the beginning, HAL realization and direct registers access just doesnt react on anyhting at all

Update. My RCC config: RCC HAL

Update2. stm32h7xx_hal_rcc.h HAL generated (__HAL_RCC_C1_SDMMC1_CLK_ENABLE() isnt active): rcc.h


Solution

  • Three things that I think might be causing init problems.

    1. There should be some sort of RCC macro call to enable the clock to the peripheral. @Ilya saw this in the comments
    2. I think there's a SDMMC_Init() call missing.
    3. The code snippet switches between using hmmc1 and hmmc2. I assume its only trying to work with one SDMMC instance at a time right?

    After that, I think your SDMMC initialization code should look something like this.

    // Enable the clock to the peripheral. I'm not sure if this is the right RCC macro though
    __HAL_RCC_SDMMC1_CLK_ENABLE();
    // initializes hmmc1 structure with configuration from STM32Cube
    MX_SDMMC1_MMC_Init();
    // initializes the SMMC1 hardware peripheral with the config set above
    SDMMC_Init(&hmmc1.Instance, &hmmc1.Init);
    // Try the rest of your code here that works with the SDMMC registers
    SDMMC_PowerState_ON(&hmmc1)
    //.... 
    

    I'm getting this info mostly from the doc in the HAL driver here: https://github.com/STMicroelectronics/stm32h7xx_hal_driver/blob/6dd7f0e35c80b6e46ab7b77c972d2e785054d7c6/Src/stm32h7xx_ll_sdmmc.c#L59-L71 . I don't have the hardware so I don't know if it will work. Good luck